fork(1) download
  1. <?php
  2. $string = '<span class="test">Lorem <i>ipsum</i> <b id="the-b">dolor</b> sit amet!</span>';
  3. print HtmlTruncate::truncate($string, 10) . PHP_EOL;
  4.  
  5. class HtmlTruncate
  6. {
  7. const READ_STRING = 1;
  8. const READ_OPEN_TAG = 2;
  9. const READ_CLOSE_TAG = 3;
  10.  
  11. public static function truncate($string, $length)
  12. {
  13.  
  14. $left = $length;
  15. $state = self::READ_STRING;
  16. $trunc = '';
  17. $tags = 0;
  18.  
  19. for ($i = 0; $i < strlen($string); $i++) {
  20. $c = $string[$i];
  21.  
  22. switch ($state) {
  23. case self::READ_STRING:
  24. if ($c == '<') {
  25. if ($string[$i+1] == '/') {
  26. $state = self::READ_CLOSE_TAG;
  27. } else {
  28. $state = self::READ_OPEN_TAG;
  29. $tags += $left ? 0 : 1;
  30. }
  31. $i--;
  32. continue;
  33. } else {
  34. if ($left) {
  35. $trunc .= $c;
  36. } else {
  37. print "skip: " . $c . PHP_EOL;
  38. }
  39. $left = max($left-1, 0);
  40. }
  41. break;
  42.  
  43. case self::READ_OPEN_TAG:
  44. if ($left) {
  45. $trunc .= $c;
  46. }
  47.  
  48. if ($c == '>') {
  49. $state = self::READ_STRING;
  50. }
  51. break;
  52.  
  53. case self::READ_CLOSE_TAG:
  54. if ($left || !$tags) {
  55. $trunc .= $c;
  56. }
  57.  
  58. if ($c == '>') {
  59. $tags = max($tags-1, 0);
  60. $state = self::READ_STRING;
  61. }
  62. break;
  63. }
  64. }
  65.  
  66. return $trunc;
  67. }
  68. }
Success #stdin #stdout 0.01s 20568KB
stdin
Standard input is empty
stdout
skip: m
skip:  
skip: d
skip: o
skip: l
skip: o
skip: r
skip:  
skip: s
skip: i
skip: t
skip:  
skip: a
skip: m
skip: e
skip: t
skip: !
<span class="test">Lorem <i>ipsu</i></span>