]> rtime.felk.cvut.cz Git - pes-rpp/rpp-simulink.git/blob - rpp/blocks/scripts/doc_parse.py
Change license to MIT
[pes-rpp/rpp-simulink.git] / rpp / blocks / scripts / doc_parse.py
1 #!/usr/bin/env python3
2
3 # Copyright (C) 2013-2015, 2019 Czech Technical University in Prague
4 #
5 # Authors:
6 #     - Michal Sojka <sojkam1@fel.cvut.cz>
7 #
8 # Permission is hereby granted, free of charge, to any person
9 # obtaining a copy of this software and associated documentation
10 # files (the "Software"), to deal in the Software without
11 # restriction, including without limitation the rights to use,
12 # copy, modify, merge, publish, distribute, sublicense, and/or sell
13 # copies of the Software, and to permit persons to whom the
14 # Software is furnished to do so, subject to the following
15 # conditions:
16
17 # The above copyright notice and this permission notice shall be
18 # included in all copies or substantial portions of the Software.
19
20 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22 # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 # OTHER DEALINGS IN THE SOFTWARE.
28 #
29 # File : doc_parse.py
30 # Abstract:
31
32 import yaml
33 import argparse
34 import Rx
35 import sys
36 import subprocess
37 import os
38 import os.path
39 from string import Template
40
41 parser = argparse.ArgumentParser()
42 parser.add_argument("file", help="file to process", nargs='+')
43 parser.add_argument("--html", help="output block description or help as HTML",
44                     action = 'store_true')
45 parser.add_argument("--latex", help="output block description as LaTeX",
46                     action = 'store_true')
47 parser.add_argument("--latex-table", help="output block status table as LaTeX",
48                     action = 'store_true')
49 parser.add_argument('--printdesc', help="output block description",
50                     action = 'store_true')
51 parser.add_argument('--printhelp', help="output block help",
52                     action = 'store_true')
53 parser.add_argument('--maskpromptstring', help="output prompt strings for Simulink mask",
54                     action = 'store_true')
55 parser.add_argument('--masktype', help="output mask type for Simulink mask",
56                     action = 'store_true')
57 parser.add_argument('--name', help="print block name",
58                     action = 'store_true')
59 args = parser.parse_args()
60
61 mydir = os.path.dirname(os.path.realpath(__file__))
62
63 def markdown_as(format, text):
64     sys.stdout.flush()
65     proc = subprocess.Popen(['pandoc', '-f', 'markdown-smart', '-t', format], stdin = subprocess.PIPE, stdout = subprocess.PIPE)
66     proc.stdin.write(bytes(text, 'UTF-8'))
67     (stdout, stderr) = proc.communicate()
68     proc.stdin.close()
69     if proc.returncode:
70         raise Exception("pandoc failed: %d" % proc.returncode)
71     return stdout.decode('utf-8').rstrip()
72
73 def print_markdown_as(format, text):
74     print(markdown_as(format, text))
75
76 def print_latex_desc(doc, filename):
77     def iodef_str(iodef):
78         if iodef is None: return "None"
79         str ='~\n\n\\smallskip\\noindent\\begin{tabularx}{\\textwidth}{|r|l|l|X|}\n'
80         str += '\\hline\n'
81         str += '~ & \\textbf{Name} & \\textbf{Type} & \\textbf{Range or notes} \\\\ \\hline \n'
82         i = 1
83         for io in iodef:
84             str += Template('%d. & $name & $type &' % i).substitute(io)
85             if 'range' in io:
86                 str += '  %s' % markdown_as('latex', io['range'])
87             if 'note' in io:
88                 str += '  %s' % markdown_as('latex', io['note'])
89             str += '\\\\ \\hline\n'
90             i += 1
91         return str +'\\end{tabularx}'
92
93     print("\\newpage\n")
94     print("\\subsection{%s}" % doc['Name'])
95     print("\\label{sec:block:%s}\n" % os.path.basename(filename))
96     print("\\paragraph{Inputs:}     %s\n" % iodef_str(doc['Inputs']))
97     print("\\paragraph{Outputs:}    %s\n" % iodef_str(doc['Outputs']))
98     print("\\paragraph{Parameters:} %s\n" % iodef_str(doc['Parameters']))
99     print("\\paragraph{Description:}\n")
100
101     print_markdown_as('latex', doc['Help'])
102
103     if doc.get('RPP API functions used', None) is not None:
104         print("\\paragraph{RPP API functions used:}")
105         print("\\begin{compactitem}")
106         print("\n".join(["\\item \\texttt{%s}" % i.replace('_', '\\_') for i in doc['RPP API functions used']]))
107         print("\\end{compactitem}")
108
109     if doc.get('Relevant demos', None) is not None:
110         print("\\paragraph{Relevant demos:}")
111         print("\\begin{compactitem}")
112         print("\n".join(["\\item %s" % i.replace('_', '\\_') for i in doc['Relevant demos']]))
113         print("\\end{compactitem}")
114
115 def process_file(f):
116     yaml_doc = None
117     for line in open(f, 'r'):
118         if yaml_doc:
119             yaml_doc += line
120         elif line.startswith("%YAML"):
121             yaml_doc = line
122         if line == '...\n':
123             break
124     if yaml_doc is None:
125         raise Exception("No line starting with '%%YAML' found in %s" % f)
126
127     doc = yaml.load(yaml_doc)
128     schema = yaml.load(open(mydir+'/schema.yaml', 'r'))
129
130     rx = Rx.Factory({ "register_core_types": True })
131     rpp_block_doc_schema = rx.make_schema(schema)
132     try:
133         rpp_block_doc_schema.check(doc)
134     except Rx.ValidationError as e:
135         raise Exception("Validation error in %s: %s" % (f, e))
136         #raise
137
138     fmt = 'html' if args.html else 'markdown'
139
140     if args.printdesc:
141         print_markdown_as(fmt, doc['Description'])
142     if args.printhelp:
143         print_markdown_as(fmt, doc['Help'])
144     if args.latex:
145         print_latex_desc(doc, f)
146     if args.latex_table:
147         global last_category
148         if last_category == doc['Category']: doc['Category']=''
149         doc['Header'] = doc['Header'].replace('_', '\\_')
150         print(Template("$Category & $Name & $Status & $Mnemonic & \\texttt{$Header} \\\\").substitute(doc))
151         if doc['Category']:
152             last_category = doc['Category']
153     if args.masktype:
154         print('RPP {name}'.format(name=doc['Name']))
155     if args.name:
156         print(doc['Name'])
157     if args.maskpromptstring and doc['Parameters'] != None:
158         print('|'.join(['{name}{range}{colon}'.format(name=par['name'],
159                                                       range=(' '+par['range'] if ('range' in par and (par['type'] in ['double'] or
160                                                                                                 'int' in par['type']))
161                                                              else ''),
162                                                       colon=':' if par['type'] != 'bool' else '')
163                         for par in doc['Parameters']]))
164
165 last_category = None
166 for f in args.file:
167     process_file(f)