3

我有一个 web.py 应用程序,它从 textarea 获取输入并将其输入到数据库中。我可以从数据库中获取信息并将其发布到页面但 NEWLINES 消失了。发回 HTML 时如何保留换行符?数据确实包含\r\n在其中,但不会在 HTML 中呈现为 NEWLINES。有什么想法吗?这是一个小例子:

(2, u'Title', u'content here...hey\r\nthis\r\nhas\r\nbreaks in it....?', 
    datetime.datetime(2012, 7, 5, 21, 5, 14, 354516))

那是我从数据库返回的。我需要\r\n代表 a<br />如果有两个 a<p>那就太棒了。任何方向将不胜感激。

还有一个图书馆吗?我听说过降价和标记,但我找不到如何从 python 字符串发布 html 数据的示例?

4

4 回答 4

11

有两种主要方法可以做到这一点。最简单的方法是包装输出<pre></pre>,将其格式化为输入的格式。

或者,您可以将 newlies 替换为<br />(而不是<p>),因为字符代表换行符而不是段落。

对于第二种选择,这是一种方法:

>>> s
'hello\nthere\r\nthis\n\ris a test'
>>> r = '<br />'
>>> s.replace('\r\n',r).replace('\n\r',r).replace('\r',r).replace('\n',r)
'hello<br />there<br />this<br />is a test'
>>> 

或者第三个选项 - 这是使用许多文本输入库/格式之一并通过它们呈现内容(正如其他人所提到的 - 如降价)。

但是,如果您只想进行简单的替换,那将是矫枉过正。

于 2012-07-07T10:26:47.877 回答
6

不作为换行符呈现的换行符是 html 中的预期行为。您想要的是插入 <br>或将您的输入解析为文本段落并用<p>..</p>

我会做两者的混合:<br>用于单个换行符和<p>..</p>用于双换行符。您可以在保存到数据库时或在将其取出时进行此解析。

编辑:我为您制作了以下图形。查看解析器的方法有很多种。就个人而言,我想将它们视为一种状态机。为了实现它,您应该以流的方式读取输入字符串,例如使用http://docs.python.org/library/stringio.html

在此处输入图像描述 Edit2:将描述“下推自动机”更改为“状态机”。下推自动机是正确的,但不精确,并且与图表不匹配 - 我将两者混合在一起。

Edit3:这里有一些关于如何在代码中实现状态机解析器的 sudo 代码,使用 while 循环、switch case 和状态转换的 if 语句。

state = 'plainState'
streamer = get_stream_reader_from_input()
buffer = ''
while true {
  nextchar = streamer.readchar()
  if (nextchar == null) { //EOS
   print(buffer)
   exit
  }
  switch (state) {
    case('plainState') {
      if (nextchar == '\n') {
        state = 'singleBreakState' 
      }
      else if (nextchar == '\r') {
        state = 'CRState'
      }
      else {
        buffer += nextchar
      }
    }
    case('singleBreakState') {
      if (nextchar == '\n') {
        state = 'doubleBreakState' 
      }
      else if (nextchar == '\r') {
        state = 'CRState2'
      }
      else {
        state = 'plainState'
        buffer += '<br>' + nextchar
      }
    }
    //...
  }
}  
于 2012-07-06T05:27:27.280 回答
3

在提出解决方案之前,您需要对正在发生的事情有一些基本的了解。如果你不理解这个问题,“扔进另一个库”的方法要么根本不起作用(更好),要么很快就会适得其反(更糟)。

@MichelMüller 正确地指出\nHTML 源代码中的 s 不会在浏览器中呈现。有关此行为的更详细说明,请参阅本教程(警告,HTML 2.0 描述)。现在,要在 HTML 中添加换行符,请使用<br>; 放置一个新段落,<p>

你可以做很多事情来实现这一点,但你要解决的问题是什么?这个用户提交的内容是什么?谁提交?需要考虑的两个方面是:

  1. 格式化。是公共网站上的评论,还是网站工作人员准备的帖子,还是 Stack Overflow 等网站上的 UGC?
  2. 安全。它是由陌生人发布的,还是由完全信任的用户发布的,还是介于两者之间?

可能的解决方案:

  • 最直接的方法是text.replace('\r\n', '<br>')在输出到模板格式化程序之前运行。如果您不在{ text | safe }模板中放入 a , in 将不起作用,因为 Jinja 不应该逃避<br>您生成的 s 。但是,文本本身不应完全信任,因此您必须先转义<并且&(至少)替换换行符之前。

  • 看看MarkupSafe以了解处理 HTML 转义的不那么特别的方法。顺便说一句,它是由 Jinja 使用的。

  • 对于非结构化内容的格式(例如,用户提交的评论如YouTube),请查看PottyMouth库。

  • 如果您的内容准备得更充分(博客平台或类似 Stack Overflow 的网站上的帖子),请按照 @BernhardKircher 的建议尝试Markdown 。它有一些学习曲线,所以如果用户愿意花一些时间写帖子,效果最好。请记住正确配置解析器,因为核心 Markdown 不会转义 HTML

  • 对于员工准备的内容,您可以使用 Markdown 或更复杂的东西。这真的取决于员工的背景。在这里,未转义的 HTML 可能是一种祝福,而不是一种诅咒。

于 2012-07-07T10:26:05.510 回答
2

而不是使用不是 html 的插入文本,因此不会显示为 html(\r\n 不是“p”标签等),您可以使用诸如 markdown 之类的格式化语言(如您所述)。

否则,您将需要手动替换/解析输入的文本(我认为这不是一个好主意,因为已经为此发明了诸如降价之类的语言)。

有一些很好的 python 库可以将markdown(您存储在数据库中的数据)转换为 html,例如python-markdown2

它真的很容易使用,请参阅 python-markdown 链接中的示例:

>>> import markdown2
>>> markdown2.markdown("*boo!*")  # or use `html = markdown_path(PATH)`
u'<p><em>boo!</em></p>\n'

>>> markdowner = Markdown()
>>> markdowner.convert("*boo!*")
u'<p><em>boo!</em></p>\n'
>>> markdowner.convert("**boom!**")
u'<p><strong>boom!</strong></p>\n'

这迫使您使用降价语法(或您使用的任何格式)输入内容。为了使这更容易,您可以使用所见即所得的编辑器来为您创建降价(就像 Stackoverflow 上的编辑器)。我认为 Stackoverflow 使用wmd但还有很多其他降价所见即所得的编辑器。

wmd 示例:

<html>
    <head>
        <title>WMD Example using jquery</title>
        <link rel="stylesheet" type="text/css" href="wmd.css"/>

        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
        <script type="text/javascript" src="jquery.wmd.min.js"></script>
    </head>
    <body>
        <h1>WMD Example using jquery</h1>
        <div>
            <textarea id="notes"/>
        </div>

        <script type="text/javascript">
            $().ready(function() {
               $("#notes").wmd(); 
            });
        </script>
    </body>
</html>
于 2012-07-06T05:27:21.757 回答