guia - Truncar un texto formateado en HTML con SMARTY
qgis manual (2)
Tengo una variable que está formateada con código HTML aleatorio. Lo llamo a {$text}
y lo trunco.
El valor es, por ejemplo:
<div>Lorem <i>ipsum <b>dolor <span>sit </span>amet</b>, con</i> elit.</div>
Si trunco las primeras 30 letras del texto, obtendré esto:
<div>Lorem <i>ipsum <b>dolor <span>sit
El problema es que no puedo cerrar los elementos. Entonces, necesito un script que verifique los elementos <*>
en el código (donde * podría ser cualquier cosa), y si no tiene una etiqueta de cierre, ciérrelos.
Por favor, ayúdame en esto. Gracias.
Solución después de horas y 4 votos a favor @ stackoverflow:
PHP:
...
function closetags($content) {
preg_match_all(''#<(?!meta|img|br|hr|input/b)/b([a-z]+)(?: .*)?(?<![/|/ ])>#iU'', $content, $result);
$openedtags = $result[1];
preg_match_all(''#</([a-z]+)>#iU'', $content, $result);
$closedtags = $result[1];
$len_opened = count($openedtags);
if (count($closedtags) == $len_opened) {
return $content;
}
$openedtags = array_reverse($openedtags);
for ($i=0; $i < $len_opened; $i++) {
if (!in_array($openedtags[$i], $closedtags)) {
$content .= ''</''.$openedtags[$i].''>'';
} else {
unset($closedtags[array_search($openedtags[$i], $closedtags)]);
}
}
return $content;
}
...
el TPL:
{$pages[j].text|truncate:300|@closetags}
Extraiga todas las etiquetas abiertas, empújelas en una matriz (matriz_1) una a una.
Extraiga todas las etiquetas cerradas, empújelas en una matriz (matriz_2) una por una (esto incluye las etiquetas de cierre automático).
Para las etiquetas en la primera matriz (matriz_1) que no se encuentran en la segunda matriz (matriz_2), agréguelas al html.
[editar]
Por supuesto, este método falla miserablemente si no escribe html apropiado ... ¿pero qué chachanado?
Otra forma sería mirar hacia adelante en la cadena para ver qué etiquetas están cerradas y cerrarlas según sea necesario.
Para simplificar, si el código es XML válido antes de truncar y no corta las etiquetas a la mitad, el algoritmo sería algo como esto:
- Empuje las etiquetas de apertura en una pila
- Apagarlos cuando encuentre la etiqueta de cierre (que coincidirá si el código es válido)
- Cuando llegue al final, comience a abrir para crear el cierre. Las etiquetas restantes deben anexarse al texto original (truncado).
Ejemplo:
<div>Lorem <i>ipsum <b>dolor <span>sit </span>amet</b><div>
- Presiona "div", "i", "b", "span"
- Se encontró la etiqueta de cierre "span"
- Pop "span"
- Se encuentra la etiqueta de cierre "b"
- Pop "b"
- Presione "div"
- Fin del texto truncado
- Pop "div" -> agregar
</div>
al texto - Pop "b" -> agregar
</b>
al texto - Pop "i" -> agregar
</i>
al texto - Pop "div" -> agregar
</div>
al texto - Fin