将纯文本呈现为HTML维护空白 - 不使用<pre>

Ala*_* H. 10 html javascript python algorithm plaintext

给定任何可打印字符的任意文本文件,如何将其转换为完全相同的HTML(具有以下要求)?

  • 除了默认的HTML空格规则之外,不依赖于任何其他规则
    • 没有<pre>标签
    • 没有CSS white-space规则
  • <p>标签很好,但不是必需的(<br />s和/或<div>s很好)
  • 确切地保留了空白.

    给定以下输入行(忽略错误的自动语法突出显示):

    Line one
        Line two, indented    four spaces
    
    Run Code Online (Sandbox Code Playgroud)

    浏览器应该使输出完全相同,保持第二行的缩进以及"缩进"和"空格"之间的间隙.当然,我实际上并不是在寻找等宽输出,而且字体与算法/标记正交.

    给定两行作为完整的输入文件,示例正确的输出将是:

    Line one<br />&nbsp;&nbsp;&nbsp;&nbsp;Line two, 
    indented&nbsp;&nbsp;&nbsp; four spaces
    
    Run Code Online (Sandbox Code Playgroud)
  • 希望在浏览器中进行软包装.也就是说,即使输入行比其视口宽(假设单个单词仍然比所述视口缩小),生成的HTML也不应强制用户滚动.

我正在寻找完全定义的算法.pythonjavascript中实现的加分点.

(请不要只回答我应该使用<pre>标签或CSS white-space规则,因为我的要求使这些选项无法使用.请不要发布未经测试和/或天真的建议,例如"用所有空格替换&nbsp;."毕竟,我"从积极的角度来看,解决方案在技术上是可行的 - 这是一个有趣的问题,你不觉得吗?)

Arn*_*anc 14

在允许浏览器包装长行的同时执行此操作的解决方案是用空格和非中断空格替换两个空格的每个序列.

浏览器将正确渲染所有空格(正常和非断开),同时仍然包裹长行(由于正常空格).

使用Javascript:

text = html_escape(text); // dummy function
text = text.replace(/\t/g, '    ')
           .replace(/  /g, '&nbsp; ')
           .replace(/  /g, ' &nbsp;') // second pass
                                      // handles odd number of spaces, where we 
                                      // end up with "&nbsp;" + " " + " "
           .replace(/\r\n|\n|\r/g, '<br />');
Run Code Online (Sandbox Code Playgroud)

  • 虽然你的代码看起来很像你复制我的并调整它,你已经处理了软包装和HTML转义问题,而我没有,并且没有重复的答案,所以我会删除我的和赞成你的. (6认同)

gil*_*ly3 11

使用零宽度空格(&#8203;)来保留空格并允许文本换行.基本思想是将每个空间或空间序列与零宽度空间配对.然后用不间断的空间替换每个空间.您还需要编码html并添加换行符.

如果你不关心unicode字符,那就太微不足道了.你可以使用string.replace():

function textToHTML(text)
{
    return ((text || "") + "")  // make sure it is a string;
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/\t/g, "    ")
        .replace(/ /g, "&#8203;&nbsp;&#8203;")
        .replace(/\r\n|\r|\n/g, "<br />");
}
Run Code Online (Sandbox Code Playgroud)

如果白色空间可以包裹,则将每个空间与零宽度空间配对,如上所述.否则,要将空白区域保持在一起,请将每个空间序列与零宽度空间配对:

    .replace(/ /g, "&nbsp;")
    .replace(/((&nbsp;)+)/g, "&#8203;$1&#8203;")
Run Code Online (Sandbox Code Playgroud)

要编码unicode字符,它会更复杂一些.你需要迭代字符串:

var charEncodings = {
    "\t": "&nbsp;&nbsp;&nbsp;&nbsp;",
    " ": "&nbsp;",
    "&": "&amp;",
    "<": "&lt;",
    ">": "&gt;",
    "\n": "<br />",
    "\r": "<br />"
};
var space = /[\t ]/;
var noWidthSpace = "&#8203;";
function textToHTML(text)
{
    text = (text || "") + "";  // make sure it is a string;
    text = text.replace(/\r\n/g, "\n");  // avoid adding two <br /> tags
    var html = "";
    var lastChar = "";
    for (var i in text)
    {
        var char = text[i];
        var charCode = text.charCodeAt(i);
        if (space.test(char) && !space.test(lastChar) && space.test(text[i + 1] || ""))
        {
            html += noWidthSpace;
        }
        html += char in charEncodings ? charEncodings[char] :
        charCode > 127 ? "&#" + charCode + ";" : char;
        lastChar = char;
    }
    return html;
}  
Run Code Online (Sandbox Code Playgroud)

现在,只是一个评论.如果不使用等宽字体,您将失去一些格式.考虑这些带有等宽字体的文本行如何形成列:

ten       seven spaces
eleven    four spaces
Run Code Online (Sandbox Code Playgroud)

如果没有等宽字体,您将丢失列:

 十七个空间
 十一个四个空间

似乎修复它的算法将非常复杂.