How to format plaintext like a book/magazine with PHP?

前端 未结 2 1777
面向向阳花
面向向阳花 2021-01-28 04:20

I have:

This is a test string. Cool, huh?

I want:

This is a te-
st string. C-
ool, huh?

That is, each line is

相关标签:
2条回答
  • 2021-01-28 05:05

    Here's some code you should be able to work with, using some sort of hyphenation library. This code uses a fake 3-character hyphenation function. You can see it in action at https://www.tehplayground.com/eNtxiMTeXj16oPkT - it took me about 10 minutes to write this, so it was, in fact, trivial - contrary to what you wrote in the now deleted thread.

    <?php
    $loremipsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
    
    function FAKE_hyphenate($word) { // use some real library's hyphenation function here
        return explode("-",wordwrap($word,3,"-",true));
    }
    
    function hyphenate_text ($text, $line_length) {
        $words = explode(" ",$text);
        $lines = [str_repeat("-",$line_length)];
        $line = "";
        while ($words) {
            $word = array_shift($words);
            if (strlen($line)+strlen($word)+1<=$line_length)
                $line .= (strlen($line)>0 ? " " : "") . $word;
            else {
                $syllables = FAKE_hyphenate($word);
                $syllables[0] = " ".$syllables[0];
                $syl_count=0;
                while ($syllables) {
                    $syllable = array_shift($syllables);
                    if (strlen($line)+strlen($syllable)<=$line_length-1) {
                        $line .= $syllable;
                        $syl_count++;
                    } else {
                        array_unshift($syllables,$syllable);
                        break;
                    }
                }
                if ($syl_count>0)
                    $line .= "-";
                $syllables[0] = str_replace(" ","",$syllables[0]);
                array_unshift($words,implode("",$syllables));
                $lines[] = $line;
                $line = "";
            }
        }
        $lines[] = $line;
        return implode("\n",$lines);
    }
    
    echo hyphenate_text($loremipsum,25);
    
    0 讨论(0)
  • 2021-01-28 05:09

    The libraries Hyphenator or Org_Heigl/Hyphenator seem to be handling hyphenation properly. Based on one of those, you should be able to write your own wordwrap() able to use either spaces or hyphens as break points.

    Note that English words have very specific hyphenation points, and you're absolutely not guaranteed to have each line exactly n characters long. Sometimes you'll fall a few characters short, if the next syllable just happens to be long - for example "thorough" hyphenates as thor-ough, while "through" does not hyphenate at all.

    0 讨论(0)
提交回复
热议问题