CheckTexinfo.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. from __future__ import print_function
  4. import sys
  5. import re
  6. import os
  7. import argparse
  8. from os.path import *
  9. from subprocess import Popen, PIPE
  10. from CheckOptions import CheckOptions
  11. class CheckTexinfo (CheckOptions):
  12. def __init__(self, args):
  13. CheckOptions.__init__(self, args)
  14. self.option_pattern = '^@item\s+--([-A-Za-z]+)'
  15. self.function_pattern = '^@defun\s+([-A-Za-z_]+)'
  16. self.source_file = join(self.source, 'doc', 'ledger3.texi')
  17. self.source_type = 'texinfo'
  18. def find_functions(self, filename):
  19. functions = set()
  20. state_normal = 0
  21. state_function = 1
  22. state = state_normal
  23. function = None
  24. fun_doc = str()
  25. fun_example = False
  26. item_regex = re.compile(self.function_pattern)
  27. itemx_regex = re.compile('^@defunx')
  28. example_regex = re.compile('^@smallexample\s+@c\s+command:')
  29. fix_regex = re.compile('FIX')
  30. comment_regex = re.compile('^\s*@c')
  31. for line in open(filename):
  32. line = line.strip()
  33. if state == state_normal:
  34. match = item_regex.match(line)
  35. if match:
  36. state = state_function
  37. function = match.group(1)
  38. elif state == state_function:
  39. if line == '@end defun':
  40. if function and fun_example and len(fun_doc) and not fix_regex.search(fun_doc):
  41. functions.add(function)
  42. state = state_normal
  43. fun_example = None
  44. fun_doc = str()
  45. elif itemx_regex.match(line):
  46. continue
  47. elif example_regex.match(line):
  48. fun_example = True
  49. elif not comment_regex.match(line):
  50. fun_doc += line
  51. return functions
  52. def find_options(self, filename):
  53. options = set()
  54. state_normal = 0
  55. state_option_table = 1
  56. state = state_normal
  57. option = None
  58. opt_doc = str()
  59. item_regex = re.compile(self.option_pattern)
  60. itemx_regex = re.compile('^@itemx')
  61. fix_regex = re.compile('FIX')
  62. comment_regex = re.compile('^\s*@c')
  63. for line in open(filename):
  64. line = line.strip()
  65. if state == state_normal:
  66. if line == '@ftable @option':
  67. state = state_option_table
  68. elif state == state_option_table:
  69. if line == '@end ftable':
  70. if option and len(opt_doc) and not fix_regex.search(opt_doc):
  71. options.add(option)
  72. state = state_normal
  73. option = None
  74. continue
  75. match = item_regex.match(line)
  76. if match:
  77. if option and len(opt_doc) and not fix_regex.search(opt_doc):
  78. options.add(option)
  79. option = match.group(1)
  80. opt_doc = str()
  81. elif itemx_regex.match(line):
  82. continue
  83. elif not comment_regex.match(line):
  84. opt_doc += line
  85. return options
  86. if __name__ == "__main__":
  87. def getargs():
  88. parser = argparse.ArgumentParser(prog='CheckTexinfo',
  89. description='Check that ledger options are documented in the texinfo manual')
  90. parser.add_argument('-l', '--ledger',
  91. dest='ledger',
  92. type=str,
  93. action='store',
  94. required=True,
  95. help='the path to the ledger executable to test with')
  96. parser.add_argument('-s', '--source',
  97. dest='source',
  98. type=str,
  99. action='store',
  100. required=True,
  101. help='the path to the top level ledger source directory')
  102. return parser.parse_args()
  103. args = getargs()
  104. script = CheckTexinfo(args)
  105. status = script.main()
  106. sys.exit(status)