]>
git.proxmox.com Git - ceph.git/blob - ceph/src/fmt/support/rst2md.py
2 # reStructuredText (RST) to GitHub-flavored Markdown converter
5 from docutils
import core
, nodes
, writers
8 def is_github_ref(node
):
9 return re
.match('https://github.com/.*/(issues|pull)/.*', node
['refuri'])
12 class Translator(nodes
.NodeVisitor
):
13 def __init__(self
, document
):
14 nodes
.NodeVisitor
.__init
__(self
, document
)
17 self
.preserve_newlines
= False
19 def write(self
, text
):
20 self
.output
+= text
.replace('\n', '\n' + ' ' * self
.indent
)
22 def visit_document(self
, node
):
25 def depart_document(self
, node
):
28 def visit_section(self
, node
):
31 def depart_section(self
, node
):
32 # Skip all sections except the first one.
33 raise nodes
.StopTraversal
35 def visit_title(self
, node
):
36 self
.version
= re
.match(r
'(\d+\.\d+\.\d+).*', node
.children
[0]).group(1)
37 raise nodes
.SkipChildren
39 def visit_title_reference(self
, node
):
42 def depart_title(self
, node
):
45 def visit_Text(self
, node
):
46 if not self
.preserve_newlines
:
47 node
= node
.replace('\n', ' ')
50 def depart_Text(self
, node
):
53 def visit_bullet_list(self
, node
):
56 def depart_bullet_list(self
, node
):
59 def visit_list_item(self
, node
):
63 def depart_list_item(self
, node
):
67 def visit_paragraph(self
, node
):
70 def depart_paragraph(self
, node
):
73 def visit_reference(self
, node
):
74 if not is_github_ref(node
):
77 def depart_reference(self
, node
):
78 if not is_github_ref(node
):
79 self
.write('](' + node
['refuri'] + ')')
81 def visit_target(self
, node
):
84 def depart_target(self
, node
):
87 def visit_literal(self
, node
):
90 def depart_literal(self
, node
):
93 def visit_literal_block(self
, node
):
95 if 'c++' in node
['classes']:
98 self
.preserve_newlines
= True
100 def depart_literal_block(self
, node
):
101 self
.write('\n```\n')
102 self
.preserve_newlines
= False
104 def visit_inline(self
, node
):
107 def depart_inline(self
, node
):
110 def visit_image(self
, node
):
111 self
.write('![](' + node
['uri'] + ')')
113 def depart_image(self
, node
):
116 def write_row(self
, row
, widths
):
117 for i
, entry
in enumerate(row
):
118 text
= entry
[0][0] if len(entry
) > 0 else ''
121 self
.write('{:{}}'.format(text
, widths
[i
]))
124 def visit_table(self
, node
):
125 table
= node
.children
[0]
126 colspecs
= table
[:-2]
129 widths
= [int(cs
['colwidth']) for cs
in colspecs
]
130 sep
= '|'.join(['-' * w
for w
in widths
]) + '\n'
132 self
.write_row(thead
[0], widths
)
135 self
.write_row(row
, widths
)
136 raise nodes
.SkipChildren
138 def depart_table(self
, node
):
141 class MDWriter(writers
.Writer
):
142 """GitHub-flavored markdown writer"""
145 """Formats this writer supports."""
148 translator
= Translator(self
.document
)
149 self
.document
.walkabout(translator
)
150 self
.output
= (translator
.output
, translator
.version
)
153 def convert(rst_path
):
154 """Converts RST file to Markdown."""
155 return core
.publish_file(source_path
=rst_path
, writer
=MDWriter())
158 if __name__
== '__main__':