Подавить перенос текста уценки в 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, который уже может быть

элемент. Так что я не хотел еще один в середине. Две вещи:

  1. Преобразовать () уценки не добавляет

    теги к предоставленному тексту, если он уже заключен в какой-либо тег уровня блока (перечисленный здесь: https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements).

  2. Если это не сработает для вас, я расширил 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;}
Другие вопросы по тегам