parser_standard_options.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Fri Jun 26 19:10:58 2015
  4. @author: pietro
  5. """
  6. from __future__ import print_function
  7. import argparse
  8. import sys
  9. try:
  10. from urllib.request import urlopen
  11. except ImportError:
  12. from urllib2 import urlopen
  13. from build_html import *
  14. def parse_options(lines, startswith='Opt'):
  15. def split_in_groups(lines):
  16. def count_par_diff(line):
  17. open_par = line.count('(')
  18. close_par = line.count(')')
  19. return open_par - close_par
  20. res = None
  21. diff = 0
  22. for line in lines:
  23. if line.startswith('case'):
  24. optname = line.split()[1][:-1]
  25. res = []
  26. # if optname == 'G_OPT_R_BASENAME_INPUT':
  27. # import ipdb; ipdb.set_trace()
  28. elif line == 'break;':
  29. diff = 0
  30. yield optname, res
  31. elif line.startswith('G_'):
  32. diff = count_par_diff(line)
  33. elif diff > 0:
  34. diff -= count_par_diff(line)
  35. else:
  36. res.append(line) if res is not None else None
  37. def split_opt_line(line):
  38. index = line.index('=')
  39. key = line[:index].strip()
  40. default = line[index + 1:].strip()
  41. if default.startswith('_('):
  42. default = default[2:]
  43. return key, default
  44. def parse_glines(glines):
  45. res = {}
  46. key = None
  47. for line in glines:
  48. if line.startswith('/*'):
  49. continue
  50. if line.startswith(startswith) and line.endswith(';'):
  51. key, default = [w.strip() for w in split_opt_line(line[5:])]
  52. res[key] = default
  53. elif line.startswith(startswith):
  54. key, default = split_opt_line(line[5:])
  55. res[key] = [default, ]
  56. else:
  57. if key is not None:
  58. if key not in res:
  59. res[key] = []
  60. start, end = 0, -1
  61. if line.startswith('_('):
  62. start = 2
  63. if line.endswith(');'):
  64. end = -3
  65. elif line.endswith(';'):
  66. end = -2
  67. res[key].append(line[start:end])
  68. # pprint(glines)
  69. # pprint(res)
  70. return res
  71. def clean_value(val):
  72. if isinstance(val, list):
  73. val = ' '.join(val)
  74. return (val.replace('"', '').replace("\'", "'").strip().strip(';')
  75. ).strip().strip('_(').strip().strip(')').strip()
  76. # with open(optionfile, mode='r') as optfile:
  77. lines = [line.strip() for line in lines]
  78. result = []
  79. for optname, glines in split_in_groups(lines):
  80. if glines:
  81. res = parse_glines(glines)
  82. if res:
  83. for key, val in res.items():
  84. res[key] = clean_value(val)
  85. result.append((optname, res))
  86. return result
  87. class OptTable(object):
  88. """"""
  89. def __init__(self, list_of_dict):
  90. self.options = list_of_dict
  91. self.columns = sorted(set([key for _, d in self.options
  92. for key in d.keys()]))
  93. def csv(self, delimiter=';', endline='\n'):
  94. """Return a CSV string with the options"""
  95. csv = []
  96. csv.append(delimiter.join(self.columns))
  97. for optname, options in self.options:
  98. opts = [options.get(col, '') for col in self.columns]
  99. csv.append(delimiter.join([optname, ] + opts))
  100. return endline.join(csv)
  101. def html(self, endline='\n', indent=' ', toptions='border=1'):
  102. """Return a HTML table with the options"""
  103. html = ['<table{0}>'.format(' ' + toptions if toptions else '')]
  104. # write headers
  105. html.append(indent + "<thead>")
  106. html.append(indent + "<tr>")
  107. html.append(indent * 2 + "<th>{0}</th>".format('option'))
  108. for col in self.columns:
  109. html.append(indent * 2 + "<th>{0}</th>".format(col))
  110. html.append(indent + "</tr>")
  111. html.append(indent + "</thead>")
  112. html.append(indent + "<tbody>")
  113. for optname, options in self.options:
  114. html.append(indent + "<tr>")
  115. html.append(indent * 2 + "<td>{0}</td>".format(optname))
  116. for col in self.columns:
  117. html.append(indent * 2 +
  118. "<td>{0}</td>".format(options.get(col, '')))
  119. html.append(indent + "</tr>")
  120. html.append(indent + "</tbody>")
  121. html.append("</table>")
  122. return endline.join(html)
  123. def _repr_html_(self):
  124. """Method used by IPython notebook"""
  125. return self.html()
  126. if __name__ == "__main__":
  127. URL = ('https://trac.osgeo.org/grass/browser/grass/'
  128. 'trunk/lib/gis/parser_standard_options.c?format=txt')
  129. parser = argparse.ArgumentParser(description='Extract GRASS default '
  130. 'options from link.')
  131. parser.add_argument('-f', '--format', default='html', dest='format',
  132. choices=['html', 'csv', 'grass'],
  133. help='Define the output format')
  134. parser.add_argument('-l', '--link', default=URL, dest='url', type=str,
  135. help='Provide the url with the file to parse')
  136. parser.add_argument('-t', '--text', dest='text',
  137. type=argparse.FileType('r'),
  138. help='Provide the file to parse')
  139. parser.add_argument('-o', '--output', default=sys.stdout, dest='output',
  140. type=argparse.FileType('w'),
  141. help='Provide the url with the file to parse')
  142. parser.add_argument('-s', '--starts-with', default='Opt',
  143. dest='startswith', type=str,
  144. help='Extract only the options that starts with this')
  145. parser.add_argument('-p', '--html_params', default='border=1', type=str,
  146. dest='htmlparmas', help="Options for the HTML table")
  147. args = parser.parse_args()
  148. cfile = args.text if args.text else urlopen(args.url, proxies=None)
  149. options = OptTable(parse_options(cfile.readlines(),
  150. startswith=args.startswith))
  151. outform = args.format
  152. if outform in ['csv', 'html']:
  153. print(getattr(options, outform)(), file=args.output)
  154. args.output.close()
  155. else:
  156. year = os.getenv("VERSION_DATE")
  157. name = args.output.name
  158. args.output.close()
  159. topicsfile = open(name, 'w')
  160. topicsfile.write(header1_tmpl.substitute(title="GRASS GIS " \
  161. "%s Reference Manual: Parser standard options index" % grass_version))
  162. topicsfile.write(headerpso_tmpl)
  163. topicsfile.write(options.html(toptions=args.htmlparmas))
  164. write_html_footer(topicsfile, "index.html", year)
  165. topicsfile.close()