git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@15590 f3b2605a-c512-4ea7-a41b-209d697bcdaa

This commit is contained in:
sjplimp
2016-09-16 16:26:52 +00:00
parent 7d77aea42d
commit 5336ec0735
3 changed files with 95 additions and 7 deletions

View File

@ -25,6 +25,7 @@ import re
import sys
import argparse
class Markup(object):
BOLD_START = "["
BOLD_END = "]"
@ -77,6 +78,7 @@ class Markup(object):
text = text.replace('\"%s\"_%s' % (name, link), href, 1)
return text
class HTMLMarkup(Markup):
def __init__(self):
super().__init__()
@ -101,6 +103,7 @@ class HTMLMarkup(Markup):
return "<A HREF = \"" + href + "\">" + content + "</A>"
class Formatting(object):
UNORDERED_LIST_MODE = "unordered-list"
ORDERED_LIST_MODE = "ordered-list"
@ -435,6 +438,7 @@ class Formatting(object):
return rows
class HTMLFormatting(Formatting):
def __init__(self, markup):
super().__init__(markup)
@ -448,6 +452,7 @@ class HTMLFormatting(Formatting):
def raw_html(self, content):
return content
class TxtParser(object):
def __init__(self):
self.markup = HTMLMarkup()
@ -630,6 +635,7 @@ class TxtParser(object):
i += 1
class Txt2Html(TxtParser):
def __init__(self):
super().__init__()
@ -641,6 +647,7 @@ class Txt2Html(TxtParser):
line.startswith(".. END_HTML_ONLY") or \
super().is_paragraph_separator(line)
class TxtConverter:
def get_argument_parser(self):
return None
@ -665,7 +672,15 @@ class TxtConverter:
print("Converting", filename, "...", file=err)
content = f.read()
converter = self.create_converter(parsed_args)
result = converter.convert(content)
try:
result = converter.convert(content)
except Exception as e:
msg = "###########################################################################\n" \
" ERROR: " + e.args[0] + "\n" \
"###########################################################################\n"
print(msg, file=err)
result = msg
if write_to_files:
output_filename = self.get_output_filename(filename)
@ -674,6 +689,7 @@ class TxtConverter:
else:
print(result, end='', file=out)
class Txt2HtmlConverter(TxtConverter):
def get_argument_parser(self):
parser = argparse.ArgumentParser(description='converts a text file with simple formatting & markup into HTML.\n'

View File

@ -24,6 +24,7 @@ import argparse
from lammpsdoc import lammps_filters
from lammpsdoc.txt2html import Markup, Formatting, TxtParser, TxtConverter
class RSTMarkup(Markup):
def __init__(self):
super().__init__()
@ -65,6 +66,7 @@ class RSTMarkup(Markup):
def escape_rst_chars(self, text):
text = text.replace('*', '\\*')
text = text.replace('^', '\\^')
text = text.replace('|', '\\|')
text = re.sub(r'([^"])_', r'\1\\_', text)
return text
@ -72,6 +74,7 @@ class RSTMarkup(Markup):
text = text.replace('\\*', '*')
text = text.replace('\\^', '^')
text = text.replace('\\_', '_')
text = text.replace('\\|', '|')
return text
def inline_math(self, text):
@ -112,13 +115,18 @@ class RSTMarkup(Markup):
return "`%s <%s>`_" % (content, href)
class RSTFormatting(Formatting):
RST_HEADER_TYPES = '#*=-^"'
def __init__(self, markup):
super().__init__(markup)
self.indent_level = 0
def paragraph(self, content):
if self.indent_level > 0:
return '\n' + self.list_indent(content.strip(), self.indent_level)
return content.strip() + "\n"
def center(self, content):
@ -128,7 +136,9 @@ class RSTFormatting(Formatting):
return content.strip()
def preformat(self, content):
return ".. parsed-literal::\n\n" + self.indent(content.rstrip())
if self.indent_level > 0:
return self.list_indent("\n.. parsed-literal::\n\n" + self.indent(content.rstrip()), self.indent_level)
return "\n.. parsed-literal::\n\n" + self.indent(content.rstrip())
def horizontal_rule(self, content):
return "\n----------\n\n" + content.strip()
@ -159,7 +169,7 @@ class RSTFormatting(Formatting):
def header(self, content, level):
header_content = content.strip()
header_content = re.sub(r'[0-9]+\.[0-9]*\s+', '', header_content)
header_content = re.sub(r'[0-9]+\.([0-9]*\.?)*\s+', '', header_content)
header_underline = RSTFormatting.RST_HEADER_TYPES[level-1] * len(header_content)
return header_content + "\n" + header_underline + "\n"
@ -178,14 +188,17 @@ class RSTFormatting(Formatting):
return self.indent(paragraph.strip())
def unordered_list_begin(self, paragraph):
self.indent_level += 1
return paragraph
def unordered_list_end(self, paragraph):
self.indent_level -= 1
return paragraph.rstrip() + '\n'
def ordered_list_begin(self, paragraph):
if paragraph.startswith('* '):
paragraph = '#. ' + paragraph[2:]
self.indent_level += 1
return paragraph
def definition_list_begin(self, paragraph):
@ -195,6 +208,7 @@ class RSTFormatting(Formatting):
return paragraph
def ordered_list_end(self, paragraph):
self.indent_level -= 1
return paragraph.rstrip() + '\n'
def ordered_list(self, paragraph):
@ -228,6 +242,12 @@ class RSTFormatting(Formatting):
indented += " %s\n" % line
return indented
def list_indent(self, content, level=1):
indented = ""
for line in content.splitlines():
indented += " " * level + ("%s\n" % line)
return indented
def get_max_column_widths(self, rows):
num_columns = max([len(row) for row in rows])
max_widths = [0] * num_columns
@ -321,6 +341,7 @@ class RSTFormatting(Formatting):
return text + post
class Txt2Rst(TxtParser):
def __init__(self):
super().__init__()
@ -354,6 +375,11 @@ class Txt2Rst(TxtParser):
return commands
return super().order_commands(commands)
def transform_paragraphs(self, content):
if self.format.indent_level > 0:
raise Exception("unbalanced number of ulb,ule or olb,ole pairs!")
return super().transform_paragraphs(content)
class Txt2RstConverter(TxtConverter):
def get_argument_parser(self):
@ -370,6 +396,7 @@ class Txt2RstConverter(TxtConverter):
filename, ext = os.path.splitext(path)
return filename + ".rst"
def main():
app = Txt2RstConverter()
app.run()

View File

@ -81,6 +81,10 @@ class TestMarkup(unittest.TestCase):
s = self.markup.convert("[*bold] and {italic*}")
self.assertEqual("**\*bold** and *italic\**", s)
def test_escape_rst_characters(self):
s = self.markup.convert("[|bold|] and {|italic|}")
self.assertEqual("**\|bold\|** and *\|italic\|*", s)
def test_escape_hat_character(self):
s = self.markup.convert("x^2")
self.assertEqual("x\^2", s)
@ -155,13 +159,13 @@ class TestFormatting(unittest.TestCase):
def test_preformat_formatting(self):
s = self.txt2rst.convert("Hello :pre\n")
self.assertEqual(".. parsed-literal::\n\n"
self.assertEqual("\n.. parsed-literal::\n\n"
" Hello\n\n", s)
def test_preformat_formatting_with_indentation(self):
s = self.txt2rst.convert(" Hello\n"
" World :pre\n")
self.assertEqual(".. parsed-literal::\n\n"
self.assertEqual("\n.. parsed-literal::\n\n"
" Hello\n"
" World\n\n", s)
@ -196,6 +200,16 @@ class TestFormatting(unittest.TestCase):
self.assertEqual("Level\n"
"#####\n\n", s)
def test_filter_header_numbers_deep(self):
s = self.txt2rst.convert("1.1.1.1.1 Level :h1\n")
self.assertEqual("Level\n"
"#####\n\n", s)
def test_no_filter_date(self):
s = self.txt2rst.convert("9 Sept 2016 version :h1\n")
self.assertEqual("9 Sept 2016 version\n"
"###################\n\n", s)
def test_all_breaks(self):
s = self.txt2rst.convert("one\n"
"two\n"
@ -308,8 +322,6 @@ class TestListFormatting(unittest.TestCase):
"* third\n"
" paragraph\n\n", s)
def test_definition_list(self):
s = self.txt2rst.convert("A\n"
"first\n"
@ -322,6 +334,39 @@ class TestListFormatting(unittest.TestCase):
" second\n"
"\n\n", s)
def test_multi_paragraph_lists(self):
s = self.txt2rst.convert("first\n"
"paragraph of first bullet :ulb,l\n\n"
"second paragraph of first bullet\n\n"
"first paragraph of second bullet :l\n\n"
":ule\n")
self.assertEqual("* first\n"
" paragraph of first bullet\n"
"\n"
" second paragraph of first bullet\n"
"\n"
"* first paragraph of second bullet\n\n\n", s)
def test_multi_paragraph_lists_with_listing(self):
s = self.txt2rst.convert("first\n"
"paragraph of first bullet :ulb,l\n\n"
"code1 :pre\n"
"or\n"
"\n"
"first paragraph of second bullet :l\n\n"
":ule\n")
self.assertEqual("* first\n"
" paragraph of first bullet\n"
" \n"
" .. parsed-literal::\n"
" \n"
" code1\n"
"\n\n"
" or\n"
"\n"
"* first paragraph of second bullet\n\n\n", s)
class TestSpecialCommands(unittest.TestCase):
def setUp(self):
self.txt2rst = txt2rst.Txt2Rst()