Примените стиль к простому тексту внутри DIV, не затрагивая других детей DIV - PullRequest
2 голосов
/ 29 августа 2010

С учетом DIV с этой общей структурой (class = "post", из извлеченного сообщения доски объявлений)


<div class="post" id="1575524">
    I'm not sure why these items in the construction updates caught my eye, but they did...<br />
    <br />
    <div style="margin:20px; margin-top:5px; ">
        <div class="smallfont" style="margin-bottom:2px">Quote:</div>
        <table cellpadding="6" cellspacing="0" border="0" width="100%">
        <tr>
            <td class="alt2" style="border:1px inset">

                    Bay Lake Tower – bathroom modifications.

            </td>
        </tr>
        </table>
    </div>They're already having to do stuff to BLT?<br />
    <div style="margin:20px; margin-top:5px; ">
        <div class="smallfont" style="margin-bottom:2px">Quote:</div>
        <table cellpadding="6" cellspacing="0" border="0" width="100%">
        <tr>
            <td class="alt2" style="border:1px inset">

                    Caribbean Beach Resort – refurbish pool rules and spa rules signs at all pools. <br />
    All Star Resorts – refurbish pool rules and spa rules signs. 

            </td>
        </tr>
        </table>
    </div>I bet there are a lot of jurisdictions out there that would love to get building permit fees from this level of work.
</div>

Мне нужно применить стили CSS к простому тексту DIV "post", не касаясь других его дочерних элементов (Ps, таблиц, других DIV и т. Д.). Я не могу изменить способ создания пост-DIV до того, как я его получу; Я могу изменить его после получения и до вывода столько, сколько необходимо. Я использую PHP для вывода HTML. Есть связанная таблица стилей CSS, которая может принимать дополнительные стили при необходимости. Внутри «post» DIV может быть любое количество блоков простого текста, которые нужно стилизовать, и любое количество дочерних элементов, которые следует оставить в покое.

Я работал с PHP-функциями обработки строк (stripos, strripos, substr). Приведенный ниже код успешно переносит обычный простой текст перед первым дочерним элементом («Я не уверен, почему эти элементы ...») и после последнего («Держу пари, что много юрисдикций ...») в P теги. Проблема заключается в доступе к простому тексту между дочерними элементами («Они уже должны ...»).


if ( stripos ( $postMessage, '<div' ) !== FALSE ) {
//  wrap text outside divs, if any
//  start of first div
  $divStartPos = stripos ( $postMessage, '<div' );
//  end of last div
  $divEndPos = strripos ( $postMessage, '/div>' ) + 4;
//  all up to start of first div + <p> tags
  if ( $divStartPos > 0 ) { 
    $textBeforeDiv = "<p class=\"postMessage\">". substr ( $postMessage, 0, $divStartPos -1 ) . "</p>\n";
  } // if
//  all between start of first and end of last div
  $div = substr ( $postMessage, $divStartPos, ($divEndPos - $divStartPos) + 1 );
//  all after end of last div + <p> tags
  $textAfterDiv = "<p class=\"postMessage\">". substr ( $postMessage, $divEndPos + 1, $postMessage->length - 1 ) . "</p>\n";
  $postMessage = $textBeforeDiv . $div . $textAfterDiv;
}   // if

Я провел несколько часов, стуча головой по классам PHP DOMDocument / DOMElement, прежде чем перейти к обработке строк, и с радостью останусь здесь, если это возможно. Мне нужен действительно простой программный способ доступа к простому тексту на верхнем уровне DIV. Если такая вещь существует.

Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 31 августа 2010

Я бы использовал два индекса сложения: startOfValidArea и endOf ...
область - это где находится ваш текст, а индексы - где вы должны поместить свои теги <p...> и </p> или любые другие теги

Затем вы перемещаете эти теги, как:
startof .. установить окончание корня <div> и найти первый случай < после него, это первая область
и затем, пока вы не в конце, получите тег после упомянутой < (например, подстрока между < и ' ' или >) и создайте временный конечный тег этого (например, </xxx>), конечно знать о нескольких одинаковых тегах внутри (например, <table><table></table></table>)
найдите этот временный конечный тег, и это будет следующий индекс startOf ..., снова найдите следующий <, это вторая область и т. д.
надеюсь, что это ясно и понятно ..
Постскриптум знать о таких тегах, как <br />, и проверять каждый запуск < на эту ситуацию
это просто алгоритм, я не кодирую в php, но он должен быть похож на

Редактировать: код, но я не уверен, что он работает, у меня нет локального сервера для тестирования, надеюсь, это будет полезно

$textStart = stripos($postMessage, '>')+1;            // startig index for the text to highlight
$textEnd = stripos($postMessage, '<', $textStartPos);     // ending index for the text to highlight

while($textStart != false && $textEnd != false){
    // while there is still any text to highlight

    // insert the highlighting code
    $postMessage = substr ($postMessage, 0, $textStart) . '<p class=\"postMessage\">' . substr ($postMessage, $textStart, $textEnd) . '</p>' . substr ($postMessage, $textEnd, strlen($postMessage);

    // get the tag
    $endOfTag = (stripos($postMessage, ' ', $textEnd) < stripos($postMessage, '>', $textEnd)) ? stripos($postMessage, ' ', $textEnd) : stripos($postMessage, '>', $textEnd);
    $tag = substr ($postMessage, $textEnd, $endOfTag); // getting the tag here

    if($tag == '<br' || $tag == '<img'){
        // do smthing with not-paired tag, like check if the tag is ending with the '/>' string and then ignore it and get the next tag
    }

    $closingTag = '</'.substr($tag,1,strlen($tag));           // creating the closing tag like </div or </p    
    $nextSameTag = stripos($postMessage, $tag, $endTag);
    $nextClosingTag = stripos($postMessage, $closingTag, $nextSameTag);

    // loop through the same inner tags like <div>text<div>text</div>text</div>
    while($nextSameTag < $nextClosingTag && $textStart != false && $textEnd != false){  
        $nextSameTag = stripos($postMessage, $tag, $nextClosingTag);
        $nextClosingTag = stripos($postMessage, $closingTag, $nextSameTag);
    }
    $textStart = stripos($postMessage, '>', $nextClosingTag)+1;
    $textEnd = stripos($postMessage, '<', $nextClosingTag);
}
0 голосов
/ 01 сентября 2010
body {color:blue}    
div.post {color:red}
div.post * {color:blue}

работает как минимум в сафари. Почему вы делаете это на PHP?

0 голосов
/ 29 августа 2010

если вы можете настроить таргетинг только на браузеры, поддерживающие CSS3 (достаточно для поддержки новых селекторов), тогда вы можете использовать: not селектор отрицания , чтобы исключить всех дочерних элементов.

что-то вроде этого должно работать:

div.post *:not(div)  
div.post *:not(table)  

селектор: not хорошо документирован, его больше проб и ошибок от людей, пробующих его. смотрите здесь: http://kilianvalkhof.com/2008/css-xhtml/the-css3-not-selector/

Но в остальном я думаю, что лучший вариант - это настроить CSS таким образом, чтобы стилевое оформление для каждого дочернего элемента и его дочерних элементов было необходимо явно определить. Это гарантирует, что стиль, применяемый к родительскому элементу div, повлияет только на текстовое содержимое вне дочерних элементов.

например.

div.post { font-family:tahoma }
div.post div { font-famile:arial }
div.post table { font-family:verdana }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...