Парсер для структурированного текста
Иногда мне нужен парсер, который может анализировать структурированный текст. Я знаю, что могу найти такой модуль для каждого типа структурированного текстового формата, например:
Но я всё ещё хочу разработать такую вещь сам, потому что мне нужно знать детали того, как разработать такой инструмент, и когда мне это нужно, я могу легко модифицировать его в соответствии со своими потребностями. Поэтому был разработан Par. И я не хочу заменять ни один из вышеперечисленных инструментов, а сначала использовать для себя. Также я хочу использовать ту же кодовую базу для реализации разных форматов структурированного текста.
В качестве парсера я выбрал pyPEG (http://fdik.org/pyPEG/), также протестировал несколько модулей, но думаю, что этот достаточно прост. Я также модифицировал исходный код pyPEG так, чтобы он подходил мне. Что я делаю, так это добавляю некоторые функции в класс Symbol и немного изменяю Symbol. Например:
class Symbol(list): def init(self, name, what): self.name = name # self.append(name) # Удалено мной self.what = what # self.append((name, what)) # Это старое self.extend(what) # Это новое
def render(self, index=0):
"""
Отображает что-то вроде дерева, позволяя мне легко находить что-либо:
list_item:
number_list_item:
:'3.'
space:' '
list_content:
list_content_lines:
list_rest_of_line:
:'Item 3'
eol:'\n'
list_content_line:' * Item 3a'
blankline:
eol:'\n'
"""
...
def find(self, name):
"""
Находит дочерний узел по имени, возвращает только первый совпавший дочерний элемент
"""
...
def find_all(self, name):
"""
Перебирает все дочерние узлы по одному, возвращает генератор
"""
@property
def text(self):
"""
Возвращает текущий текст узла, если есть дочерние заметки, объединяет их все вместе.
"""
Также я написал простой класс Visitor, чтобы другие посетители могли наследовать от него. У него есть метод visit, похожий на:
def visit(self, nodes, root=False):
И когда он посещает узел, он ищет всё дерево узлов и также вызывает некоторые динамические функции, такие как:
if root: begin() # Если root не False before_visit(node) # Вызов перед посещением узла visit_<node.name>begin(node) # В соответствии с текущим именем узла visit<node.name> # В соответствии с текущим именем узла visit_<node.name>_end(node) # В соответствии с текущим именем узла after_visit(node) # Вызов после посещения узла if root: end() # Если корень не False
В Par есть два парсера для формата Google Code Wiki и формата Markdown. Есть примеры в папке examples.
Markdown2html
Это пример того, как использовать Par для анализа текста в формате Markdown. Его можно использовать в команде, например:
python markdown2html.py readme.md > readme.html
Анализ Markdown программно
Сделайте так:
from par.md import parseHtml
template = '''<!doctype html>
<title>%(title)s</title> %(body)s '''tag_class = {'table':'table'}
text = """
This is a pragraph """
print parseHtml(text, template, tag_class)
Расширение синтаксиса Markdown
Это:
|| a || b || c ||
|| c || d || e ||
вернёт это:
<table>
<tr><td> a </td><td> b </td><td> c </td>
</tr>
<tr><td> b </td><td> c </td><td> d </td>
</tr>
</table>
Другой формат таблицы:
| a | b | c |
|---|---|---|
| c | d | e |
и это выведет:
<table>
<thead>
<tr><th>aa</th><th>bb</th><th></th></tr>
</thead>
<tbody>
<tr><td>asd</td><td></td></tr>
</tbody></table>
Вы также можете установить выравнивание заголовка таблицы, например так:
First Header | Second Header | Third Header
:------------ | ------------: | :----------:
Content Cell | Content Cell | Content Cell
Content Cell | Content Cell | Content Cell
это выведет:
<table>
<thead>
<tr><th>First Header</th><th>Second Header</th><th>Third Header</th></tr>
</thead>
<tbody>
<tr><td align="left">Content Cell</td><td align="right">Content Cell</td><td align="center">Content Cell</td></tr>
<tr><td align="left">Content Cell</td><td align="right">Content Cell</td><td align="center">Content Cell</td></tr>
</tbody></table>
Сделайте так:
a --
abc
b --
cde
получите это:
<dl>
<dt>a</dt>
<dd><p>abc</p>
</dd>
<dt>b</dt>
<dd><p>cde</p>
</dd>
</dl>
Обратите внимание, что каждый список определений должен быть отделён пустыми строками.
Или вы можете определить список определений в таком формате:
a --
: abc
b --
: cde
Можно использовать:
http://google.com
в тексте.
Можно просто использовать <code>```</code>
для цитирования абзаца кода, как в формате GitHub:
``` code here ```
Par.md также добавляет некоторые новые декораторы текста, такие как:
^text^ <sup>text<sup>
,,text,, <sub>text<sub>
~~text~~ <span style="text-decoration: line-through">text</span>
***text*** <strong><em>text</em></strong>
___text___ <strong><em>text</em></strong>
{% alert %}
Success
{% endalert %}
{% alert class=error%}
Success
{% endalert %}
Синтаксис такой же, как у предупреждения Bootstrap, но имя тега может быть message.
{% message %}
Success
{% endmessage %}
Для использования Bootstrap код следует вызывать так:
from par.md import parseHtml
from par.bootstrap_ext import blocks
print parseHtml(text, template, block_callback=blocks)
Для семантического использования следует вызывать код так:
from par.md import parseHtml
from par.semantic_ext import blocks
print parseHtml(text, template, block_callback=blocks)
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )