【问题标题】:How to format plaintext like a book/magazine with PHP?如何使用 PHP 像书籍/杂志一样格式化纯文本?
【发布时间】:2020-04-29 03:04:06
【问题描述】:

我有:

This is a test string. Cool, huh?

我想要:

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

也就是说,每行正好是 13 个字符,根据英文规则。也就是说,我不确定“test”是否可以像“test-st”一样被分解,或者“Cool”是否可以被分解为“C-ool”,但这就是我想要的“风格”达到。

我已经进行了大约一千次搜索查询。我找不到任何可以做到这一点的东西。

wordwrap() 没有用,因为它只适用于整个“单词”,并且在大多数行的末尾留下大量空白。

这太令人沮丧了,因为在我解决这个问题之前我无法继续我的项目。我以为会有一个库来解决这个问题,但我发现的唯一甚至远程相关的是 https://github.com/vanderlee/phpSyllable ,但这似乎根本没有做到这一点。该示例没有任何意义,因为它没有显示任何输出,也没有在任何地方提及任何行“宽度”。

【问题讨论】:

  • 我不会英语有断字规则。
  • 您到底想达到什么目的?你为什么需要这个?我只是好奇你是否以正确的方式去做。也看看 wordwrap(cut) 的最后一个参数。
  • 您是在查看固定宽度还是使用连字规则?你不能总是在第 13 个字符上打断并且可读。回到打字机的旧时代,有书籍显示单词可以在哪里拆分,目标是将右边距保持在 5 个字符左右。十三个字符用起来并不多......
  • [您应该能够对自己的帖子发表评论,而不是回复答案。我的观点是您的要求,“根据英语规则,每行正好是 13 个字符”无法获得。那么你想要哪个,固定宽度还是正确的连字符?你不能两者兼得。您的示例需要是您想要的合理示例。 te-stC-ool 暗示您正在寻找固定宽度,因为这些绝不是分割单词的有效位置。
  • FWIW,如果您使用浏览器来显示结果,那么您正在寻找的内容是通过 CSS 完成的。例如text-align: justify。单词通常不再使用连字符...

标签: php formatting plaintext text-manipulation


【解决方案1】:

这里有一些你应该可以使用的代码,使用某种连字符库。此代码使用假的 3 字符连字符函数。你可以在https://www.tehplayground.com/eNtxiMTeXj16oPkT 看到它的实际效果——我花了大约 10 分钟来写这篇文章,所以它实际上是微不足道的——与你在现已删除的线程中写的相反。

<?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);

【讨论】:

    【解决方案2】:

    HyphenatorOrg_Heigl/Hyphenator 似乎可以正确处理连字符。基于其中之一,您应该能够编写自己的 wordwrap() 能够使用空格或连字符作为断点。

    请注意,英语单词有非常具体的连字符点,并且您绝对不能保证每行的长度都是 n 个字符。有时,如果下一个音节恰好很长,有时您会缺少几个字符 - 例如,“thorough”连字符为 thor-ough,而“through”根本不连字符。 p>

    【讨论】: