]> rtime.felk.cvut.cz Git - jenkicar/rpp-simulink.git/blob - rpp/blocks/scripts/doc_parse.py
266060208a3381d34f6badd1ecfda7f21c969ab9
[jenkicar/rpp-simulink.git] / rpp / blocks / scripts / doc_parse.py
1 #!/usr/bin/env python3
2
3 import yaml
4 import argparse
5 import Rx
6 import sys
7 import subprocess
8 import os
9 from string import Template
10
11 parser = argparse.ArgumentParser()
12 parser.add_argument("file", help="file to process", nargs='+')
13 parser.add_argument("--html", help="output block description or help as HTML",
14                     action = 'store_true')
15 parser.add_argument("--latex", help="output block description as LaTeX",
16                     action = 'store_true')
17 parser.add_argument("--latex-table", help="output block status table as LaTeX",
18                     action = 'store_true')
19 parser.add_argument('--printdesc', help="output block description",
20                     action = 'store_true')
21 parser.add_argument('--printhelp', help="output block help",
22                     action = 'store_true')
23 parser.add_argument('--maskpromptstring', help="output prompt strings for Simulink mask",
24                     action = 'store_true')
25 parser.add_argument('--masktype', help="output mask type for Simulink mask",
26                     action = 'store_true')
27 args = parser.parse_args()
28
29 mydir = os.path.dirname(os.path.realpath(__file__))
30
31 def print_markdown_as(format, text):
32     proc = subprocess.Popen(['pandoc', '-f', 'markdown', '-t', format], stdin = subprocess.PIPE)
33     proc.stdin.write(bytes(text, 'UTF-8'))
34     proc.communicate()
35     proc.stdin.close()
36     if proc.returncode:
37         raise Exception("pandoc failed: %d" % proc.returncode)
38
39 def print_latex_desc(doc):
40     def iodef_str(iodef):
41         if iodef is None: return "None"
42         str='%d\n\\begin{enumerate}\n' % len(iodef)
43         for io in iodef:
44             str += Template('\\item {\\bf $name} $type').substitute(io)
45             if 'range' in io:
46                 str += '  %s' % io['range']
47             str += '\n'
48         return str +'\end{enumerate}'
49
50     print("\\newpage\n")
51     print("\\subsubsection{%s}\n" % doc['Name'])
52     print("\\begin{description}\n")
53     print("\\item[Inputs:]     %s\n" % iodef_str(doc['Inputs']))
54     print("\\item[Outputs:]    %s\n" % iodef_str(doc['Outputs']))
55     print("\\item[Parameters:] %s\n" % iodef_str(doc['Parameters']))
56     print("\\end{description}\n")
57
58     print_markdown_as('latex', doc['Description'])
59
60     print("\n\\textbf{Status:}")
61     print("\\begin{multicols}{3}")
62     if doc['Status']['Tested']:
63         print("\\begin{compactitem}")
64         print("\\item \\textbf{Tested}:")
65         print(" \\begin{compactitem}")
66         print("\n".join(["\\item %s" % i.replace('_', '\\_') for i in doc['Status']['Tested']]))
67         print(" \\end{compactitem}")
68         print("\\end{compactitem}")
69     else:
70         print("\\ ")
71
72     print("\\vfill\\columnbreak")
73
74     if doc['Status']['Untested']:
75         print("\\begin{compactitem}")
76         print("\\item \\textbf{Untested}:")
77         print(" \\begin{compactitem}")
78         print("\n".join(["\\item %s" % i.replace('_', '\\_') for i in doc['Status']['Untested']]))
79         print(" \\end{compactitem}")
80         print("\\end{compactitem}")
81     else:
82         print("\\ ")
83
84     print("\\vfill\\columnbreak")
85
86     if doc['Status']['Not working']:
87         print("\\begin{compactitem}")
88         print("\\item \\textbf{Not working}:")
89         print(" \\begin{compactitem}")
90         print("\n".join(["\\item %s" % i.replace('_', '\\_') for i in doc['Status']['Not working']]))
91         print(" \\end{compactitem}")
92         print("\\end{compactitem}")
93     else:
94         print("\\ ")
95
96     print("\\end{multicols}\n")
97
98     if doc.get('RPP API functions used', None) is not None:
99         print("\\textbf{RPP API functions used:}")
100         print("\\begin{compactitem}")
101         print("\n".join(["\\item \\texttt{%s}" % i.replace('_', '\\_') for i in doc['RPP API functions used']]))
102         print("\\end{compactitem}")
103
104     if doc.get('Relevant demos', None) is not None:
105         print("\\textbf{Relevant demos:}")
106         print("\\begin{compactitem}")
107         print("\n".join(["\\item %s" % i.replace('_', '\\_') for i in doc['Relevant demos']]))
108         print("\\end{compactitem}")
109
110 def process_file(f):
111     yaml_doc = None
112     for line in open(f, 'r'):
113         if yaml_doc:
114             yaml_doc += line
115         elif line.startswith("%YAML"):
116             yaml_doc = line
117         if line == '...\n':
118             break
119     if yaml_doc is None:
120         raise Exception("No line starting with '%%YAML' found in %s" % f)
121
122     doc = yaml.load(yaml_doc)
123     schema = yaml.load(open(mydir+'/schema.yaml', 'r'))
124
125     rx = Rx.Factory({ "register_core_types": True })
126     rpp_block_doc_schema = rx.make_schema(schema)
127     try:
128         rpp_block_doc_schema.check(doc)
129     except Rx.ValidationError as e:
130         raise Exception("Validation error in %s: %s" % (f, e))
131         #raise
132
133     fmt = 'html' if args.html else 'markdown'
134
135     if args.printdesc:
136         print_markdown_as(fmt, doc['Description'])
137     if args.printhelp:
138         print_markdown_as(fmt, doc['Help'])
139     if args.latex:
140         print_latex_desc(doc)
141     if args.latex_table:
142         global last_category
143         if last_category == doc['Category']: doc['Category']=''
144         doc['Header'] = doc['Header'].replace('_', '\\_')
145         if   doc['Status']['Not working']: doc['ShortStatus'] = '$\\alpha$'
146         elif doc['Status']['Untested']:    doc['ShortStatus'] = '$\\beta$'
147         elif not doc['Status']['Tested']:  doc['ShortStatus'] = '$\\beta$'
148         else:                              doc['ShortStatus'] = 'Stable'
149         print(Template("$Category & $Name & $ShortStatus & $Mnemonic & \\texttt{$Header} \\\\").substitute(doc))
150         if doc['Category']:
151             last_category = doc['Category']
152     if args.masktype:
153         print('RPP {name}'.format(name=doc['Name']))
154     if args.maskpromptstring and doc['Parameters'] != None:
155         print('|'.join(['{name}{range}{colon}'.format(name=par['name'],
156                                                       range=(' '+par['range'] if ('range' in par and (par['type'] in ['double'] or
157                                                                                                 'int' in par['type']))
158                                                              else ''),
159                                                       colon=':' if par['type'] != 'bool' else '')
160                         for par in doc['Parameters']]))
161
162 last_category = None
163 for f in args.file:
164     process_file(f)