mirror of
https://github.com/aantron/better-enums.git
synced 2025-12-08 09:47:41 +08:00
The documentation is now generated from markdown. Samples are generated from the tutorial pages. Testing is done by a Python script which runs the tests for a large number of compilers. This version is not very developer-friendly - the Python scripts need ways of limiting what compilers they try to run. If you don't have 15 compilers installed, you won't be able to run the tests in this commit. Fix coming soon.
198 lines
5.4 KiB
Python
Executable File
198 lines
5.4 KiB
Python
Executable File
#! /usr/bin/env python
|
|
|
|
# Reads mixed source/text markdown files and outputs HTML and/or C++ source.
|
|
# Usage:
|
|
# ./transform.py --o-html OUT.html --o-cxx OUT.cc in.md
|
|
|
|
import argparse
|
|
import mistune
|
|
import re
|
|
import sys
|
|
|
|
parser = argparse.ArgumentParser(description = "Translate markdown tutorials.",
|
|
epilog = "At least one output file must be specified")
|
|
parser.add_argument("--o-html", metavar = "HTML", dest = "html_file",
|
|
help = "HTML output file name")
|
|
parser.add_argument("--o-cxx", metavar = "CXX", dest = "cxx_file",
|
|
help = "C++ output file name")
|
|
parser.add_argument("md_file", metavar = "MD")
|
|
|
|
def pretty_print(text, prefix, start_with_prefix = True):
|
|
words = text.split()
|
|
|
|
index = 0
|
|
|
|
if start_with_prefix:
|
|
result = prefix
|
|
else:
|
|
result = ""
|
|
|
|
while index < len(words):
|
|
column = len(prefix)
|
|
|
|
result += words[index]
|
|
column += len(words[index])
|
|
index += 1
|
|
|
|
while index < len(words) and column + 1 + len(words[index]) <= 80:
|
|
result += " "
|
|
result += words[index]
|
|
column += 1 + len(words[index])
|
|
index += 1
|
|
|
|
result += "\n"
|
|
if index < len(words):
|
|
result += prefix
|
|
|
|
return result
|
|
|
|
class HtmlRenderer(mistune.Renderer):
|
|
def __init__(self):
|
|
super(HtmlRenderer, self).__init__()
|
|
self._definitions = {}
|
|
|
|
def header(self, text, level, raw = None):
|
|
if level == 2:
|
|
if "title" not in self._definitions:
|
|
self._definitions["title"] = text
|
|
|
|
return super(HtmlRenderer, self).header(text, level, raw)
|
|
|
|
def paragraph(self, text):
|
|
if text.startswith("%%"):
|
|
tokens = text[2:].split("=", 1)
|
|
if len(tokens) == 2:
|
|
pass
|
|
key = tokens[0].strip()
|
|
value = tokens[1].strip()
|
|
|
|
self._definitions[key] = value
|
|
|
|
return ""
|
|
|
|
return super(HtmlRenderer, self).paragraph(text)
|
|
|
|
def block_code(self, code, lang):
|
|
escaped = mistune.escape(re.sub("\n*$", "", code))
|
|
replaced = re.sub("<em>", "<em>", escaped)
|
|
replaced = re.sub("</em>", "</em>", replaced)
|
|
replaced = re.sub("#(ifn?def|endif).*\n?", "", replaced)
|
|
|
|
if lang == "comment":
|
|
start_tag = "<pre class=\"comment\">"
|
|
else:
|
|
start_tag = "<pre>"
|
|
|
|
return start_tag + replaced + "</pre>"
|
|
|
|
def definitions(self):
|
|
return self._definitions
|
|
|
|
def to_html(text):
|
|
renderer = HtmlRenderer()
|
|
html = mistune.Markdown(renderer = renderer).render(text)
|
|
definitions = renderer.definitions()
|
|
definitions["body"] = html
|
|
return definitions
|
|
|
|
class CxxRenderer(mistune.Renderer):
|
|
def __init__(self):
|
|
super(CxxRenderer, self).__init__()
|
|
self._not_in_list()
|
|
self._not_paragraph()
|
|
|
|
def header(self, text, level, raw = None):
|
|
self._not_in_list()
|
|
return self._join_paragraph() + pretty_print(text, "// ")
|
|
|
|
def paragraph(self, text):
|
|
if text.startswith("%%"):
|
|
return ""
|
|
|
|
self._not_in_list()
|
|
return self._join_paragraph() + pretty_print(text, "// ")
|
|
|
|
def codespan(self, text):
|
|
return text
|
|
|
|
def list(self, body, ordered = True):
|
|
return self._join_paragraph() + body
|
|
|
|
def list_item(self, text):
|
|
return ("// %i. " % self._number_list_item()) + \
|
|
pretty_print(text, "// ", False)
|
|
|
|
def block_code(self, code, lang):
|
|
self._not_in_list()
|
|
|
|
code = re.sub("</?em>", "", code)
|
|
|
|
if lang == "comment":
|
|
code = re.sub("^(.)", "// \g<1>", code, flags = re.MULTILINE)
|
|
code = re.sub("^$", "//", code, flags = re.MULTILINE)
|
|
return self._join_paragraph() + code + "\n"
|
|
else:
|
|
self._not_paragraph()
|
|
return "\n" + code
|
|
|
|
def hrule(self):
|
|
self._not_in_list()
|
|
self._not_paragraph()
|
|
return ""
|
|
|
|
def footnote_ref(self, key, index):
|
|
return ""
|
|
|
|
def footnotes(self, text):
|
|
return ""
|
|
|
|
def _not_in_list(self):
|
|
self._list_index = None
|
|
|
|
def _number_list_item(self):
|
|
if self._list_index == None:
|
|
self._list_index = 2
|
|
return 1
|
|
else:
|
|
result = self._list_index
|
|
self._list_index += 1
|
|
return result
|
|
|
|
def _not_paragraph(self):
|
|
self._join = False
|
|
|
|
def _paragraph(self):
|
|
self._join = True
|
|
|
|
def _join_paragraph(self):
|
|
if self._join:
|
|
result = "//\n"
|
|
else:
|
|
result = ""
|
|
|
|
self._join = True
|
|
|
|
return result
|
|
|
|
def main(md_file, html_file, cxx_file):
|
|
markdown = open(md_file, "r").read()
|
|
|
|
if html_file != None:
|
|
html = mistune.markdown(markdown)
|
|
open(html_file, "w").write(html)
|
|
|
|
if cxx_file != None:
|
|
renderer = CxxRenderer()
|
|
source = mistune.Markdown(renderer = renderer).render(markdown)
|
|
source = re.sub(r"\n*$", "\n", source)
|
|
source = "// This file was generated automatically\n\n" + source
|
|
open(cxx_file, "w").write(source)
|
|
|
|
if __name__ == "__main__":
|
|
arguments = parser.parse_args()
|
|
if arguments.html_file == None and arguments.cxx_file == None:
|
|
parser.print_help()
|
|
sys.exit(1)
|
|
|
|
main(arguments.md_file, arguments.html_file, arguments.cxx_file)
|