Как бы вы пошли на разбор Markdown?

Синтаксис здесь.

Источник, следующий за загрузкой, написан в Perl, который у меня нет намерений почитать. Он пронизан регулярными выражениями, и он полагается на MD5 хэши, чтобы избежать определенных символов. В этом что-то не так!

Я собираюсь записать код синтаксического анализа для Markdown. Что с этим связано?

Если у вас нет никакого смысла говорить о фактическом разборе Markdown, избавьте меня от времени. (Это может показаться резким, но да, я ищу понимание, а не решение, то есть стороннюю библиотеку).

Чтобы немного помочь в ответах, регулярные выражения предназначены для идентифицировать шаблоны! НЕ разбирать всю грамматику. То, что люди считают, что это так, является foobar.

  • Если вы думаете о Markdown, он основывается на концепции абзацев.
  • Таким образом, разумным подходом может быть разделение ввода на абзацы.
  • Существует много видов абзацев, например, заголовок, текст, список, блок-кавычка и код.
  • Таким образом, задача состоит в том, чтобы идентифицировать эти параграфы и в каком контексте они происходят.

Я вернусь с решением, как только я нахожу его достойным для совместного использования.

Ответ 1

Единственная реализация уценки, которую я знаю, которая использует фактический парсер, - Jon MacFarleane s peg-markdown. Свой синтаксический анализатор основан на синтаксическом анализаторе выражения грамматики peg.


EDIT: Маурисио Фернандес недавно выпустил свой Простой маркер разметки парсера, который он написал как часть своего OcsiBlog механизма веб-журнала. Поскольку синтаксический анализатор написан в OCaml, он чрезвычайно прост и короток (268 SLOC для , 43 SLOC для HTML-эмиттер), но невероятно быстро (на 20% быстрее, чем скидка (написана в ручном оптимизированном C) и в шестьсот раз быстрее, чем BlueCloth (Ruby)), несмотря на то, что это не даже не оптимизированный для производительности. Поскольку он предназначен только для внутреннего использования Маурисио для его веб-журнала, есть несколько отклонений от официальной спецификации Markdown ветвь, которая возвращает большинство этих изменений.

Ответ 2

На прошлой неделе я выпустил новую реализацию Markdown Java на основе парсера, называемую pegdown. pegdown использует парсер PEG для создания абстрактного синтаксического дерева, которое впоследствии выписывается в HTML. Таким образом, он достаточно чист и намного легче читать, поддерживать и расширять, чем подход, основанный на регулярном выражении. PEG-грамматика основана на реализации Джона МакФарланеса "привязка кодов".

Может быть, что-то интересное для вас...

Ответ 3

Я бы, наверное, достаточно долго читал спецификацию синтаксиса, чтобы узнать ее, и понять, как ее разобрать.

Чтение существующего кода парсера, конечно, великолепен, как для того, чтобы увидеть, что, по-видимому, является основным источником сложности, и если используются какие-либо специальные умные трюки. Использование контрольной суммы MD5 кажется немного странным, но я недостаточно изучил этот код, чтобы понять, почему это делается. Комментарий в процедуре под названием _EscapeSpecialChars() гласит:

Мы заменяем каждый такой символ соответствующим значением контрольной суммы MD5; это, вероятно, излишний, но это должно помешать нам столкнуться с побегом значения по ошибке.

Замена одного символа на полный MD5 кажется экстравагантным, но, возможно, это действительно имеет смысл.

Конечно, было бы разумно подумать о создании "истинного" синтаксиса для инструмента, такого как Flex, чтобы получить из regex болота.

Ответ 4

Если бы я попытался разобрать отметку (и ее расширение Markdown extra) Я думаю, что я попытаюсь использовать конечный автомат и проанализировать это один из char за один раз, связывая некоторые внутренние структуры, представляющие биты текста, когда я иду дальше, после того, как все разобраны, генерируя вывод из всех объектов, объединенных вместе.

В принципе, я бы построил мини-DOM-подобное дерево, когда прочитал входной файл.
Чтобы сгенерировать вывод, я бы просто пересекал дерево и выводил HTML или что-то еще (PS, LaTex, RTF,...)

Вещи, которые могут увеличить сложность:

  • Тот факт, что вы можете смешивать HTML и уценку, хотя правило может быть легко реализовано: просто игнорируйте что-либо, что между двумя сбалансированными тегами и выводите его дословно.

  • URL-адреса и заметки могут содержать ссылку в нижней части текста. Использование структур данных для гиперссылок может просто записать что-то вроде:

    [my text to a link][linkkey]
    results in a structure like: 
        URLStructure: 
        |  InnerText : "my text to a link"
        |  Key       : "linkkey"
        |  URL       : <null>
    
  • Заголовки могут быть определены с подчеркиванием, что может заставить нас использовать простую структуру данных для общего абзаца и изменить его свойства при чтении файла:

    ParagraphStructure:
    |  InnerText    : the current paragraph text 
    |                 (beginning of line until end of line).
    |  HeadingLevel : <null> or 1-4 when we can assess 
    |                 that paragraph heading level, if any.
    

Во всяком случае, только некоторые мысли.

Я уверен, что есть много мелких деталей, которые нужно позаботиться, и я уверен, что регулярные выражения могут стать удобными во время процесса.
В конце концов, они предназначены для обработки текста.

Ответ 5

Если Perl не ваша вещь, есть варианты Markdown в не менее 10 других языков. Они, вероятно, не все имеют совместимость на 100%, но, как правило, довольно близки.

Ответ 6

MarkdownPapers - это другая реализация Java, парсер которой определяется в JavaCC.

Ответ 7

Здесь вы можете найти JavaScript-реализацию Markdown. Он также в значительной степени зависит от регулярных выражений, поскольку это всего лишь самый быстрый и простой способ анализа текста.

Но он сохраняет часть MD5.

Я не могу напрямую помочь с кодированием синтаксического анализа, но, возможно, эта ссылка может помочь вам так или иначе.

Ответ 8

Существуют библиотеки, доступные на нескольких языках, включая php, ruby, java, С#, javascript. Я бы предложил взглянуть на некоторые из них для идей.

Это зависит от того, какой язык вы хотите использовать, для лучшего способа его реализации будут идиоматические и неидиоматические способы сделать это.

Regexes работают в perl, потому что perl и regex являются лучшими друзьями.

Ответ 9

Если вы используете язык программирования, который содержит более трех других пользователи, вы сможете найти библиотеку для ее анализа. быстрый Google-поиск показывает библиотеки для CL, Haskell, Python, JavaScript, Ruby и т.д. Очень маловероятно, что вам понадобится изобретать это колесо.

Если вам действительно нужно писать это с нуля, я рекомендую написать правильный парсер. С помощью этой техники вам не придется избегать вещей с хешами MD5. (Я согласен, что если вам нужно сделать что-то подобное, пришло время пересмотреть ваш дизайн.)

Ответ 10

Markdown - это JAWL (просто еще один вики-язык)

Существует много открытых wiki с открытым исходным кодом, в которых вы можете проверить код анализатора. Большинство используют REGEX

Посмотрите на винт-вики, есть интересный многопроходный форматирующий конвейер, очень хороший метод - см. /core/Formatter.cs и/core/FormatterPipeline.cs

Лучше всего использовать/присоединять к существующему проекту, такие вещи всегда намного сложнее, чем они появляются