Как бы вы пошли на разбор 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
Лучше всего использовать/присоединять к существующему проекту, такие вещи всегда намного сложнее, чем они появляются