在<p> </p>中抑制python markdown包装文本

时间:2013-03-21 18:56:15

标签: python markdown jinja2 templating

我正在使用python markdown作为Jinja2的过滤器来生成html。作为其中的一部分,我从渲染输入中填写表条目。通过降价过滤器传递输入始终将文本包装在段落标记中,因此表格中的每个条目都包含在<p></p>中,这是我不想要的。

我已经阅读了降价文档和第三方扩展程序列表,但除了编写自己的扩展程序之外,似乎无法抑制此行为。有没有其他方法可以抑制段落标记包装?或者我是以错误的方式解决这个问题?

更新:这是我现在正在使用的脏兮兮的糟糕黑客:

def safe_markdown(text):
  p = '<p>'
  np = '</p>'
  md = markdown.markdown(text)
  if md.startswith(p) and md.endswith(np): #you filthy bastard
    md = md[len(p):-len(np)]
  return jinja2.Markup(md)

env = jinja2.Environment(...)
env.filters['markdown'] = safe_markdown 

更新2 (回应Aaron的回答):

欣赏帮助,但肯定是导致问题的降价。以下是jinja模板的示例部分:

        {%- if spc.docs -%}
<td>{{ spc.docs|markdown }}</td></tr>
        {%- else -%}
<td></td></tr>
        {%- endif -%}

如果spc.docs只是'foo',那么生成的html将会以<td><p>foo</p></td></tr>结束,除非我使用肮脏的黑客。

更新3

这是一个不那么令人讨厌的黑客,虽然仍然是一个黑客,而不是一个'答案',IMO。

def safe_markdown(text):
    md = markdown.markdown(text)
    return jinja2.Markup(md)

def safe_markdown_td(text):
    text = ''.join(['<td>', text, '</td>'])
    return safe_markdown(text)

env = jinja2.Environment(...)
env.filters['markdown'] = safe_markdown
env.filters['markdowntd'] = safe_markdown_td

然后模板变为:

        {%- if spc.docs -%}
{{ spc.docs|markdowntd }}</tr>
        {%- else -%}
<td></td></tr>
        {%- endif -%}

5 个答案:

答案 0 :(得分:2)

任何时候使用markdown,你都必须接受对html最终结构的一些非常严厉的妥协。有许多你根本无法表达的结构。不要将它视为html的替代品,将其视为另一种简单编写内容的语言。

可能发生的事情是将表格单元格内容包装在段落标记中会弄乱您的布局,在这种情况下您应该使用CSS修复它:

td p {
  margin: 0;
  padding: 0;
}

答案 1 :(得分:1)

我同意,黑客是肮脏的(但总比没有好)。

根据我的经验,表格中的怪异,特别是<td>,是由于格式错误的标记造成的。在您的情况下,这可能是同一个问题。

>>> import markdown
>>> markdown.version
'2.1.1'
>>> text = '''
... <table>
... <tr>
...     <td>
...             Here's some fancy text
...
...             and some more
...     </td>
...     <td>Here's other text</td>
... </tr>
... </table>
... 
... This should be in a **paragraph.**
... '''
>>> markdown.markdown(text)
u"<table>
<tr>
    <td>
        Here's some fancy text

        and some more
    </td>
    <td>Here's other text</td>
</tr>
</table>
<p>This should be in a <strong>paragraph.</strong></p>"

^看?表中没有疯狂的段落标签。

还有Jinja喝醉的远程可能性,并添加了这些标签。我个人没有注意到这种行为,但是在使用和不使用模板过滤器的情况下尝试这个实验可能是值得的。

还有一件事。 Markdown摇滚,虽然你将失去一些控制权,但我认为你做出了一个很好的选择。

编辑抱歉,Elhefe,我并不完全了解发生了什么。我也遇到过这个问题!我的解决方案:如果我不想要段落,请将该垃圾包裹在<div>中。

>>> markdown.markdown(text)
u'<p>Here be some <em>foo</em></p>'
>>> text = '<div>Here be some *foo*</div>'
>>> markdown.markdown(text)
u'<div>Here be some *foo*</div>'

但这并不能解决你的问题。我唯一能想到的是在标记之前将文本包装在<td></td>中。

答案 2 :(得分:1)

...另一种消除刺激性外部标签的方法是编写一个简单的剥离功能:

def strip(s):
    """ strips outer html tags """

    start = s.find('>')+1
    end = len(s)-s[::-1].find('<')-1

    return s[start:end]

答案 3 :(得分:0)

我的<p> </p>标签弄乱我的桌子时遇到了同样的问题。对我来说最简单的解决方案是通过添加

来解决这个问题
td p {display:inline;}

答案 4 :(得分:0)

只是遇到了同样的问题-markdown.markdown()免费提供了不需要的开始/结束段落标签。

对于我不希望markdown()包装为段落的字符串,以下内容对我来说效果很好。我没有直接调用markdown(),而是将调用包装在一个正则表达式中,该正则表达式去除了有问题的段落标记,并且不干扰嵌入在我的markdown中的任何intended hard-wraps

from markdown import markdown

# ... other stuff ...

def no_p_markdown(non_p_string) -> str:
    ''' Strip enclosing paragraph marks, <p> ... </p>, 
        which markdown() forces, and which interfere with some jinja2 layout
    '''
    return re.sub("(^<P>|</P>$)", "", markdown(non_p_string), flags=re.IGNORECASE)

# ... other stuff ...

non_p_html = no_p_markdown("my markdown text not intended for a paragraph")