Compare commits
6 Commits
master
...
bugfixes/a
| Author | SHA1 | Date | |
|---|---|---|---|
| ee8ad050ff | |||
| 7b9b716b63 | |||
| 4c5bdfb6cf | |||
| 5d78fd6c42 | |||
| 7141f3fa53 | |||
| 8ffc31c64c |
@ -1,60 +0,0 @@
|
||||
#! /usr/bin/env python3
|
||||
# LAMMPS Documentation Utilities
|
||||
#
|
||||
# Scan for duplicate anchor labels in documentation files
|
||||
#
|
||||
# Copyright (C) 2017 Richard Berger
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import re
|
||||
import sys
|
||||
import argparse
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='scan for duplicate anchor labels in documentation files')
|
||||
parser.add_argument('files', metavar='file', nargs='+', help='one or more files to scan')
|
||||
parsed_args = parser.parse_args()
|
||||
|
||||
anchor_pattern = re.compile(r'^:link\(([^,\)]*)\)')
|
||||
anchors = {}
|
||||
|
||||
for filename in parsed_args.files:
|
||||
with open(filename, 'rt') as f:
|
||||
for line_number, line in enumerate(f):
|
||||
m = anchor_pattern.match(line)
|
||||
if m:
|
||||
label = m.group(1)
|
||||
if label in anchors:
|
||||
anchors[label].append((filename, line_number+1))
|
||||
else:
|
||||
anchors[label] = [(filename, line_number+1)]
|
||||
|
||||
count = 0
|
||||
|
||||
for label in sorted(anchors.keys()):
|
||||
if len(anchors[label]) > 1:
|
||||
print(label)
|
||||
count += 1
|
||||
for filename, line_number in anchors[label]:
|
||||
print(" - %s:%d" % (filename, line_number))
|
||||
|
||||
|
||||
if count > 0:
|
||||
print("Found %d anchor label errors." % count)
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("No anchor label errors.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@ -655,7 +655,7 @@ class TxtConverter:
|
||||
def get_output_filename(self, path):
|
||||
return ""
|
||||
|
||||
def create_converter(self, args):
|
||||
def create_converter(self, args, filename='default.txt'):
|
||||
return None
|
||||
|
||||
def run(self, args=sys.argv[1:], out=sys.stdout, err=sys.stderr):
|
||||
@ -704,7 +704,7 @@ class Txt2HtmlConverter(TxtConverter):
|
||||
parser.add_argument('files', metavar='file', nargs='+', help='one or more files to convert')
|
||||
return parser
|
||||
|
||||
def create_converter(self, args):
|
||||
def create_converter(self, args, filename='default.txt'):
|
||||
converter = Txt2Html()
|
||||
converter.append_page_break = args.breakflag
|
||||
converter.create_title = args.create_title
|
||||
|
||||
@ -23,11 +23,25 @@ import re
|
||||
import argparse
|
||||
from lammpsdoc import lammps_filters
|
||||
from lammpsdoc.txt2html import Markup, Formatting, TxtParser, TxtConverter
|
||||
from collections import OrderedDict
|
||||
|
||||
|
||||
def simplify_anchor(anchor_url):
|
||||
""" Remove repeating words, but leave repeating numbers """
|
||||
def unique_words(s):
|
||||
parts = s.split('_')
|
||||
last_word = ""
|
||||
for word in parts:
|
||||
if word.isdecimal() or word != last_word:
|
||||
yield word
|
||||
last_word = word
|
||||
return '_'.join(unique_words(anchor_url))
|
||||
|
||||
|
||||
class RSTMarkup(Markup):
|
||||
def __init__(self):
|
||||
def __init__(self, filename='default.rst'):
|
||||
super().__init__()
|
||||
self.filename = os.path.basename(filename)
|
||||
|
||||
def bold_start(self):
|
||||
return "**"
|
||||
@ -104,11 +118,20 @@ class RSTMarkup(Markup):
|
||||
|
||||
anchor_pos = href.find('#')
|
||||
|
||||
if anchor_pos >= 0 and not href.startswith('http'):
|
||||
href = href[anchor_pos+1:]
|
||||
if anchor_pos > 0 and not href.startswith('http'):
|
||||
filename = os.path.splitext(href[0:anchor_pos])[0]
|
||||
href = href[anchor_pos + 1:]
|
||||
href = simplify_anchor(filename + "_" + href)
|
||||
return ":ref:`%s <%s>`" % (content, href)
|
||||
elif anchor_pos == 0 and not href.startswith('http'):
|
||||
filename = os.path.splitext(self.filename)[0]
|
||||
href = href[anchor_pos + 1:]
|
||||
href = simplify_anchor(filename + "_" + href)
|
||||
return ":ref:`%s <%s>`" % (content, href)
|
||||
|
||||
if href in self.references:
|
||||
filename = os.path.splitext(self.filename)[0]
|
||||
href = simplify_anchor(filename + "_" + href)
|
||||
return ":ref:`%s <%s>`" % (content, href)
|
||||
elif href in self.aliases:
|
||||
href = "%s_" % href
|
||||
@ -122,8 +145,9 @@ class RSTMarkup(Markup):
|
||||
class RSTFormatting(Formatting):
|
||||
RST_HEADER_TYPES = '#*=-^"'
|
||||
|
||||
def __init__(self, markup):
|
||||
def __init__(self, markup, filename = 'default.rst'):
|
||||
super().__init__(markup)
|
||||
self.filename = os.path.basename(filename)
|
||||
self.indent_level = 0
|
||||
|
||||
def paragraph(self, content):
|
||||
@ -165,7 +189,9 @@ class RSTFormatting(Formatting):
|
||||
|
||||
def named_link(self, paragraph, name):
|
||||
self.markup.add_internal_reference(name)
|
||||
return (".. _%s:\n\n" % name) + paragraph
|
||||
filename = os.path.splitext(self.filename)[0]
|
||||
name = simplify_anchor(filename + "_" + name)
|
||||
return (".. _%s:\n\n" % self.markup.unescape_rst_chars(name)) + paragraph
|
||||
|
||||
def define_link_alias(self, paragraph, alias, value):
|
||||
self.markup.add_link_alias(alias, value)
|
||||
@ -347,10 +373,10 @@ class RSTFormatting(Formatting):
|
||||
|
||||
|
||||
class Txt2Rst(TxtParser):
|
||||
def __init__(self):
|
||||
def __init__(self, filename='default.rst'):
|
||||
super().__init__()
|
||||
self.markup = RSTMarkup()
|
||||
self.format = RSTFormatting(self.markup)
|
||||
self.markup = RSTMarkup(filename=filename)
|
||||
self.format = RSTFormatting(self.markup,filename=filename)
|
||||
self.register_filters()
|
||||
|
||||
def register_filters(self):
|
||||
@ -394,8 +420,8 @@ class Txt2RstConverter(TxtConverter):
|
||||
parser.add_argument('files', metavar='file', nargs='+', help='one or more files to convert')
|
||||
return parser
|
||||
|
||||
def create_converter(self, args):
|
||||
return Txt2Rst()
|
||||
def create_converter(self, args, filename='default.txt'):
|
||||
return Txt2Rst(filename=self.get_output_filename(filename))
|
||||
|
||||
def get_output_filename(self, path):
|
||||
filename, ext = os.path.splitext(path)
|
||||
|
||||
3
setup.py
3
setup.py
@ -12,7 +12,6 @@ setup(name='LAMMPS Documentation Utilities',
|
||||
tests_require=['nose'],
|
||||
entry_points = {
|
||||
"console_scripts": ['txt2html = lammpsdoc.txt2html:main',
|
||||
'txt2rst = lammpsdoc.txt2rst:main',
|
||||
'doc_anchor_check = lammpsdoc.doc_anchor_check:main ']
|
||||
'txt2rst = lammpsdoc.txt2rst:main']
|
||||
},
|
||||
)
|
||||
|
||||
@ -411,18 +411,26 @@ class TestSpecialCommands(unittest.TestCase):
|
||||
def test_internal_reference_link(self):
|
||||
s = self.txt2rst.convert("one :link(name)\n"
|
||||
"a \"link\"_name to above\n")
|
||||
self.assertEqual(".. _name:\n"
|
||||
self.assertEqual(".. _default_name:\n"
|
||||
"\n"
|
||||
"one \n\n"
|
||||
"a :ref:`link <name>` to above\n\n", s)
|
||||
"a :ref:`link <default_name>` to above\n\n", s)
|
||||
|
||||
def test_local_anchor_link(self):
|
||||
s = self.txt2rst.convert("one :link(name)\n"
|
||||
"a \"link\"_#name to above\n")
|
||||
self.assertEqual(".. _name:\n"
|
||||
self.assertEqual(".. _default_name:\n"
|
||||
"\n"
|
||||
"one \n\n"
|
||||
"a :ref:`link <name>` to above\n\n", s)
|
||||
"a :ref:`link <default_name>` to above\n\n", s)
|
||||
|
||||
def test_repeating_words_in_anchor_link(self):
|
||||
s = self.txt2rst.convert("one :link(name_name_2_2)\n"
|
||||
"a \"link\"_#name_name_2_2 to above\n")
|
||||
self.assertEqual(".. _default_name_2_2:\n"
|
||||
"\n"
|
||||
"one \n\n"
|
||||
"a :ref:`link <default_name_2_2>` to above\n\n", s)
|
||||
|
||||
def test_external_anchor_link(self):
|
||||
s = self.txt2rst.convert('some text "containing a\n'
|
||||
|
||||
Reference in New Issue
Block a user