Scripts
Indenting functies
Ik was bezig met een klein deel van een website waarin teksten konden worden bewerkt. Aangezien ik graag nette ge-indente HTML heb, heb ik een paar helpers geschreven die dat makkelijk voor me kunnen regelen. En natuurlijk, regex-gek die ik ben, kon ik het niet laten om het ook met regexes op te lossen. De tree van de algemene unindent regex heb ik bijgesloten als commentaar bovenaan. Reacties / commentaar / boze klachten hoor ik graag (nouja, behalve klachten dan) :-) Edit: de regex deed het ineens niet meer, foei! Eventjes gefixt. Deze moet overigens nog wat optimalisatiewerk krijgen, maar hij is ook nu heel snel :-) Edit: de regex met zo'n 10 keer versneld dankzij een paar atomische aanpassingen.
indenting-functies
[code]<?php
/**
Regex tree:
\A # Assert position at the beginning of the string
[\r\n] # Match a single character present in the list below
# A carriage return character
# A line feed character
* # Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
( # Match the regular expression below and capture its match into backreference number 1
[ \t] # Match a single character present in the list below
# The character " "
# A tab character
+ # Between one and unlimited times, as many times as possible, giving back as needed (greedy)
)
[^\r\n] # Match a single character NOT present in the list below
# A carriage return character
# A line feed character
*+ # Between zero and unlimited times, as many times as possible, without giving back (possessive)
[\r\n] # Match a single character present in the list below
# A carriage return character
# A line feed character
++ # Between one and unlimited times, as many times as possible, without giving back (possessive)
(?> # Atomic group. Match the regex below, and do not try further permutations of it if the overall match fails.
| # Match either the regular expression below (attempting the next alternative only if this one fails)
\1 # Match the same text as most recently matched by capturing group number 1
[^\r\n] # Match a single character NOT present in the list below
# A carriage return character
# A line feed character
*+ # Between zero and unlimited times, as many times as possible, without giving back (possessive)
(?: # Match the regular expression below
# Match either the regular expression below (attempting the next alternative only if this one fails)
[\r\n] # Match a single character present in the list below
# A carriage return character
# A line feed character
+ # Between one and unlimited times, as many times as possible, giving back as needed (greedy)
| # Or match regular expression number 2 below (the entire group fails if this one fails to match)
\z # Assert position at the very end of the string
)
| # Or match regular expression number 2 below (the entire group fails if this one fails to match)
[\r\n] # Match a single character present in the list below
# A carriage return character
# A line feed character
+ # Between one and unlimited times, as many times as possible, giving back as needed (greedy)
)+ # Between one and unlimited times, as many times as possible, giving back as needed (greedy)
\z # Assert position at the very end of the string
*/
/**
* Unindent de gegeven string naar het begin van de regel indien mogelijk
*
* Hierbij worden lege regels overgeslagen
*
* N.b.: de langste substring wordt gebruikt, dus alle indenting moet exact
* gelijk aan elkaar zijn, anders wordt wellicht niet alles gematcht
*
* @param string $text
* @return string
*/
function unindent($text) {
// fix voor phphulp
if (preg_match('{\A[\r\n]*([ \t]+)[^\r\n]*+[\r\n]++(?' . '>\1[^\r\n]*+(?:[\r\n]+|\z)|[\r\n]+)+\z}', rtrim($text), $match)) {
$text = preg_replace('{^' . $match[1] . '}m', '', $text);
}
return $text;
}
/**
* Indent een gegeven string naar een bepaalde diepte
*
* @param string $text
* @param numeric $indent hoe vaak moet $char vooraan iedere regel terugkomen
* @param string $char welk karakter wordt gebruikt voor indenten
* @return string
*/
function indent($text, $indent, $char = "\t") {
return preg_replace('{^}m', str_repeat($char, $indent), $text);
}
/**
* Deze functie is een combinatie van {@link unindent} en {@link indent}
*
* @param string $text
* @param numeric $indent hoe vaak moet $char vooraan iedere regel terugkomen
* @param string $char welk karakter wordt gebruikt voor indenten
* @return string
*/
function indentTo($text, $indent, $char = "\t") {
return indent(unindent($text), $indent, $char);
}
//
// Voorbeeldje
//
$example = '
Dit is een voorbeeld tekst!
Zoals je ziet is deze regel origineel twee spaties geindent :-)
En deze vijf!
En deze maar drie. Kijken wat er gebeurt :-)
';
echo '<pre>', htmlspecialchars(
unindent($example)
. "\n\n" .
indent($example, 1)
. "\n\n" .
indentTo($example, 1, ' ')
), '</pre>';
?>[/code]
Reacties
0