Skip to content

Instantly share code, notes, and snippets.

@kanghyojun
Created December 30, 2020 05:11
Show Gist options
  • Save kanghyojun/97b549b08b84ae093454b0aca31eb1c9 to your computer and use it in GitHub Desktop.
Save kanghyojun/97b549b08b84ae093454b0aca31eb1c9 to your computer and use it in GitHub Desktop.
import json
from docutils.core import Publisher
from docutils.io import StringInput, StringOutput
from docutils.nodes import NodeVisitor, document, section
from docutils.writers import Writer
class MyTranslator(NodeVisitor):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.summary = []
self.descriptions = []
self.context = []
def visit_title(self, node):
if isinstance(node.parent, document):
self.context.append('header1')
if isinstance(node.parent, section):
self.context.append('header2')
def depart_title(self, node):
type_ = self.context.pop(0)
body = ''.join(self.context[:])
if type_ == 'header1':
self.summary.append(body)
elif type_ == 'header2':
self.descriptions.append('# ' + body + '\n')
self.context = []
def visit_document(self, node):
pass
def depart_document(self, node):
pass
def visit_paragraph(self, node):
pass
def depart_paragraph(self, node):
self.descriptions.append(self.context.pop())
def visit_Text(self, node):
self.context.append(node.astext())
def depart_Text(self, node):
pass
def visit_literal_block(self, node):
if 'http' in node.attributes['classes']:
self.context.append('::http')
def depart_literal_block(self, node):
if len(self.context) >= 2 and self.context[1] == '::method':
d = self.read_request()
else:
d = self.read_response()
print(node)
self.context = []
def consume_next(self, starts, k, n):
next_item = False
for i, item in enumerate(self.context[starts:]):
if next_item:
return i, {n: item}
if item == k:
next_item = True
return None
def read_request(self):
i = 0
response = {}
for symbol, key in [
('::method', 'method'),
('::path', 'path'),
]:
token = self.consume_next(i, symbol, key)
if token is not None:
i, r = token
response.update(r)
print(response)
def read_response(self):
i = 0
print(self.context)
response = {}
for symbol, key in [
('::exception', 'status'),
]:
token = self.consume_next(i, symbol, key)
if token is not None:
i, r = token
response.update(r)
aaa = ('::attribute', 'Content-Type', '::literal')
d = {}
next_item = False
is_symbol = False
is_data = False
search = None
for item in self.context:
next_item = next_item or (item == aaa[0])
if next_item and item == aaa[1]:
search = aaa[2]
is_symbol = is_symbol or (search is not None and item == search)
if is_symbol and not item.startswith('::'):
print('yay',item)
is_symbol = False
print(d)
def visit_inline(self, node):
if self.context[0] == '::http':
if 'function' in node.attributes['classes']:
self.context.append('::method')
elif 'namespace' in node.attributes['classes']:
self.context.append('::path')
elif 'exception' in node.attributes['classes']:
self.context.append('::exception')
elif 'attribute' in node.attributes['classes']:
self.context.append('::attribute')
elif 'literal' in node.attributes['classes']:
self.context.append('::literal')
elif 'punctuation' in node.attributes['classes']:
self.context.append('::punctuation')
def depart_inline(self, node):
pass
def visit_section(self, node):
pass
def depart_section(self, node):
pass
class MyWriter(Writer):
def translate(self):
visitor = MyTranslator(self.document)
self.document.walkabout(visitor)
self.output = json.dumps({
'summary': '\n'.join(visitor.summary),
'descriptions': '\n'.join(visitor.descriptions),
}, indent=4)
source = '''Hello mynamea
~~~~~~~~~~~~~~~~~~~~~~~~~
hi
aabc
=====
for the i
.. sourcecode:: http
GET /abc/ HTTP/1.1
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
{
"a": 1
}
'''
source_path = None
destination_path = None
reader = None
reader_name = 'standalone'
parser = None
parser_name = 'restructuredtext'
#writer = None
#writer_name = 'xhtml'
writer = MyWriter()
writer_name = None
settings = None
settings_spec = None
settings_overrides = None
config_section = None
enable_exit_status = False
source_class = StringInput
destination_class = StringOutput
destination = None
pub = Publisher(reader, parser, writer, settings=settings,
source_class=source_class,
destination_class=destination_class)
pub.set_components(reader_name, parser_name, writer_name)
pub.process_programmatic_settings(
settings_spec, settings_overrides, config_section)
pub.set_source(source, source_path)
pub.set_destination(destination, destination_path)
output = pub.publish(enable_exit_status=enable_exit_status)
print(output.decode('utf-8'))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment