我有一个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
代表<br />
,如果有两个<p>
则会很棒。任何方向都会非常感激。
还有一个图书馆吗?我听说过markdown和mark up但是我找不到如何从python字符串发布html数据的例子?
答案 0 :(得分:10)
两种主要方法。最简单的方法是将输出包装在<pre></pre>
中,并将其格式化为输入。
或者,您可以使用<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'
>>>
或者第三个选项 - 使用众多文本条目库/格式之一并通过它们呈现内容(如其他人所提到的那样 - 如markdown)。
但是,如果您只想做一个简单的替换,那就太过分了。
答案 1 :(得分: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
}
}
//...
}
}
答案 2 :(得分:3)
在提出解决方案之前,您需要对发生的事情有一些基本的了解。如果你不理解这个问题,那么“扔进另一个图书馆”的方法要么根本不能工作(更好),要么很快就会适得其反(更糟)。
@MichelMüller在说明HTML源代码中的\n
未在浏览器中呈现时是正确的。有关此行为的更详细说明,请参阅this tutorial(caveat,HTML 2.0描述)。现在,要在HTML中添加换行符,请使用<br>
;添加一个新段落<p>
。
你可以做很多事情来实现这个目标,但是你要解决的问题是什么?这个用户提交的内容是什么?谁提交了它?需要考虑的两个方面是:
可能的解决方案:
最直接的方法是在将text.replace('\r\n', '<br>')
输出到模板格式化程序之前运行它。如果你没有在模板中放置{ text | safe }
,那么将无效,因为Jinja不应该逃脱你生成的<br>
。但是,文本本身不应该完全信任,因此您必须在替换换行符之前转义<
和&
(至少)。
查看MarkupSafe,了解处理HTML转义的不那么特别的方法。顺便说一句,它被Jinja聘用。
要格式化非结构化内容(即用户提交的评论 a la YouTube),请查看PottyMouth库。
如果您的内容准备得更充分(在博客平台或类似Stack Overflow的网站上发布),请按照@BernhardKircher的建议尝试Markdown。它有一些学习曲线,因此如果用户愿意花一些时间写帖子,它会效果最好。请记住正确配置解析器,因为核心Markdown不会转义HTML 。
对于员工准备的内容,您可以使用Markdown或其他更复杂的内容。这真的取决于员工的背景。在这里,未转义的HTML可能是一种祝福,而不是一种诅咒。
答案 3 :(得分:2)
您可以使用像markdown这样的格式化语言(如您所述),而不是使用不是html的插入文本,因此不会显示为html(\ r \ n不是“p”标签等) 。
否则你需要手动替换/解析输入的文本(我认为这不是一个好主意,因为像这样的语言已经被发明了。)
有一些好的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'
这会强制您使用markdown语法(或您使用的任何格式)输入内容。为了使这更容易,您可以使用所见即所得编辑器为您创建降价(就像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>