title: Cutting text without destroying html tags
body: <p>Is there a way to do this without writing my own function?</p>
  
  <p>For example:</p>
  
  <pre><code>$text = 'Test &lt;span&gt;&lt;a&gt;something&lt;/a&gt; something else&lt;/span&gt;.';
  $text = cutText($text, 2, null, 20, true);
  //result: Test &lt;span&gt;&lt;a&gt;something&lt;/a&gt;&lt;/span&gt;
  </code></pre>
  
  <p>I need to make this function indestructible</p>
  
  <p>My problem is similar to 
  <a href="https://stackoverflow.com/questions/830283/cutting-html-strings-without-breaking-html-tags">This thread</a>
  but I need a better solution. I would like to keep nested tags untouched.</p>
  
  <p>So far my algorithm is:</p>
  
  <pre><code>function cutText($content, $max_words, $max_chars, $max_word_len, $html = false) {
      $len = strlen($content);
      $res = '';
  
      $word_count = 0;
      $word_started = false;
      $current_word = '';
      $current_word_len = 0;
  
      if ($max_chars == null) {
          $max_chars = $len;
      }
      $inHtml = false;
      $openedTags = array();
      for ($i = 0; $i&lt;$max_chars;$i++) {
  
          if ($content[$i] == '&lt;' &amp;&amp; $html) {
              $inHtml = true;
          }
  
          if ($inHtml) {
              $max_chars++;
          }       
  
          if ($html &amp;&amp; !$inHtml) {
  
              if ($content[$i] != ' ' &amp;&amp; !$word_started) {
                  $word_started = true;
                  $word_count++;
              }
  
              $current_word .= $content[$i];
              $current_word_len++;
  
              if ($current_word_len == $max_word_len) {
                  $current_word .= '- ';
              }
  
              if (($content[$i] == ' ') &amp;&amp; $word_started) {
                  $word_started = false;
                  $res .= $current_word;
                  $current_word = '';
                  $current_word_len = 0;
                  if ($word_count == $max_words) {
                      return $res;
                  }
              }
          }
  
          if ($content[$i] == '&lt;' &amp;&amp; $html) {
              $inHtml = true;
          }
      }
      return $res;
  }
  </code></pre>
  
  <p>But of course it won't work. I thought about remembering opened tags and closing them if they were not closed but maybe there is a better way?</p>