Подавить перенос текста уценки в Python в<p></ p>
Я использую 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 (ответ на ответ Аарона):
Цените помощь, но это определенно уценка, вызывающая проблему. Вот пример части шаблона 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 -%}
6 ответов
Каждый раз, когда вы используете уценку, вы должны принять довольно серьезные компромиссы в окончательной структуре HTML. Существует множество структур, которые вы просто не можете выразить. Не думайте об этом как о замене HTML, думайте об этом как о другом языке, чтобы просто писать контент.
Может случиться так, что упаковка содержимого ячейки таблицы в теги абзаца испортит ваш макет, и в этом случае вы должны исправить это с помощью CSS:
td p {
margin: 0;
padding: 0;
}
Просто наткнулся на ту же проблему - нежелательные теги начала / конца абзаца бесплатно от
markdown.markdown()
.
Следующее работает для меня, для строк, которые мне не нужны
markdown()
обернуть как абзацы. Вместо того, чтобы звонить
markdown()
напрямую, я заключаю вызов в регулярное выражение, которое удаляет оскорбительные знаки абзаца, и таким образом, чтобы не мешать никаким предполагаемым жестким оболочкам, встроенным в мою уценку.
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")
Я столкнулся с той же проблемой, когда использовал Markdown для добавления HTML-разметки к некоторым пользовательским строкам в файле конфигурации, чтобы им не приходилось изучать HTML (для этого и нужен Markdown, верно?). Эти строки встраиваются в другой HTML, который уже может быть
элемент. Так что я не хотел еще один в середине. Две вещи:
Преобразовать () уценки не добавляет
теги к предоставленному тексту, если он уже заключен в какой-либо тег уровня блока (перечисленный здесь: https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements).
Если это не сработает для вас, я расширил Markdown, чтобы переопределить метод convert () для удаления
теги.
из уценки импортировать уценку класс EMarkdown(уценка): преобразование по определению (я, текст): т = супер (). преобразовать (текст) t = t.removeprefix("<p>").removesuffix("</p>") вернуть т
Распространение этого на все теги блочного уровня оставляется читателю в качестве упражнения. ;-)
... еще один способ удалить раздражающие внешние теги - написать простую функцию удаления:
def strip(s):
""" strips outer html tags """
start = s.find('>')+1
end = len(s)-s[::-1].find('<')-1
return s[start:end]
Я согласен, что взломать грязно (но лучше, чем ничего).
По моему опыту странности внутри таблиц, а конкретно <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>"
^ Видишь? Нет сумасшедших тегов абзаца в таблице.
Есть также отдаленная вероятность того, что Джинджа пьян, и добавляет эти теги. Я не заметил такого поведения лично, но, возможно, стоит попробовать этот эксперимент с фильтром шаблона и без него.
Еще кое-что. Markdown рушится, и пока вы потеряете контроль, я думаю, вы сделали отличный выбор.
Редактировать Извините, Эльхеф, я не совсем понял, что происходит. У меня тоже была эта проблема! Мое решение: завернуть этот мусор в <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>
до уценки.
У меня была такая же проблема с <p> </p>
теги портят мои таблицы. Самым простым решением для меня было исправить это в CSS, добавив
td p {display:inline;}