File indexing completed on 2024-04-14 04:31:22
0001 #!/usr/bin/env python 0002 # 0003 # This file is part of KDevelop 0004 # 0005 # Copyright 2016 Anton Anikin <anton.anikin@htower.ru> 0006 # 0007 # This program is free software; you can redistribute it and/or 0008 # modify it under the terms of the GNU General Public 0009 # License as published by the Free Software Foundation; either 0010 # version 2 of the License, or (at your option) any later version. 0011 # 0012 # This program is distributed in the hope that it will be useful, 0013 # but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 # General Public License for more details. 0016 # 0017 # You should have received a copy of the GNU General Public License 0018 # along with this program; see the file COPYING. If not, write to 0019 # the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0020 # Boston, MA 02110-1301, USA. 0021 0022 from xml.sax.saxutils import escape, unescape 0023 import pyparsing as pp 0024 import string 0025 import re 0026 0027 # escape() and unescape() takes care of &, < and >. 0028 html_escape_table = { 0029 '"': """, 0030 "'": "'" 0031 } 0032 0033 html_unescape_table = {v:k for k, v in html_escape_table.items()} 0034 0035 def html_escape(text): 0036 return escape(text, html_escape_table) 0037 0038 def html_unescape(text): 0039 return unescape(text, html_unescape_table) 0040 0041 def parseFile(fileName): 0042 EOL = pp.LineEnd().suppress() 0043 endTag = pp.Literal('**Compliance:**') 0044 0045 ruleTitle = pp.Regex(r'[A-Z]\d{3}') + pp.White().suppress() + pp.restOfLine() + pp.ZeroOrMore(EOL) 0046 ruleTitle.setParseAction( 0047 lambda t: '\ntitles[type("%s")] = "%s";\nexplanations[type("%s")] =\n<html>\n%s: %s' % 0048 (t[0], html_unescape(t[1]), 0049 t[0], t[0], t[1]) 0050 ) 0051 0052 ruleEnd = endTag + pp.restOfLine() + pp.ZeroOrMore(EOL) 0053 ruleEnd.setParseAction( lambda t: '%s\n</html>' % (t[0] + t[1]) ) 0054 0055 hline = pp.Regex(r'-{3,}') + pp.ZeroOrMore(EOL) 0056 hline.setParseAction( lambda t: '<hr>' ) 0057 0058 textLine = pp.LineStart() + pp.NotAny('~') + pp.NotAny(endTag) + pp.NotAny(EOL) + pp.restOfLine() + EOL 0059 textBlock = pp.OneOrMore(textLine) + pp.ZeroOrMore(EOL) 0060 textBlock.setParseAction( lambda t: '%s\n<br><br>' % ' '.join(t) ) 0061 0062 codeTag = pp.Regex(r'~~~~.*') + EOL 0063 codeLine = pp.LineStart().leaveWhitespace() + pp.NotAny(codeTag) + pp.restOfLine() + pp.ZeroOrMore(EOL) 0064 codeBlock = codeTag.suppress() + pp.OneOrMore(codeLine) + codeTag.suppress() + pp.ZeroOrMore(EOL) 0065 0066 parametersLine = pp.Literal(' ').leaveWhitespace() + pp.restOfLine() + EOL 0067 parametersLine.setParseAction( lambda t: ''.join(t) ) 0068 parametersBlock = pp.OneOrMore(parametersLine) + pp.ZeroOrMore(EOL) 0069 0070 listLine = pp.Literal('-') + pp.restOfLine() + EOL 0071 listLine.setParseAction( lambda t: ("•"+t[1]).replace('`', '') ) 0072 listBlock = pp.OneOrMore(listLine) + pp.ZeroOrMore(EOL) 0073 0074 preBlock = codeBlock ^ parametersBlock ^ listBlock 0075 preBlock.setParseAction( lambda t: '<pre>\n%s\n</pre>' % '\\n\n'.join(t) ) 0076 0077 rule = ruleTitle + hline + pp.OneOrMore(preBlock ^ textBlock) + ruleEnd 0078 rule.setParseAction( lambda t: '\n'.join(t) ) 0079 0080 rules = pp.Literal("Rules").suppress() + pp.Literal("=====").suppress() + EOL + pp.OneOrMore(rule) 0081 rules.setParseAction( lambda t: '\n'.join(t) ) 0082 0083 t = open(fileName, 'r').read() 0084 0085 # escaping 0086 t = html_escape(t) 0087 t = re.sub(r'\\', r'\\\\', t) 0088 0089 t = rules.parseString(t)[0] 0090 0091 # add bold and italic 0092 t = re.sub(r'\*\*(.+)\*\*', r'<b>\1</b>', t) 0093 t = re.sub(r'\*(.+)\*', r'<i>\1</i>', t) 0094 0095 # remove <br> before and after <pre> blocks 0096 t = re.sub(r'<br><br>\n<pre>', r'<pre>', t) 0097 t = re.sub(r'</pre>\n<br><br>', r'</pre>', t) 0098 0099 # 'stringify' lines 0100 t = re.sub(r'(.+)', r'"\1"', t) 0101 0102 # fix begin ane end of code 0103 t = re.sub(r'</html>"', r'</html>";', t) 0104 t = re.sub(r'"(titles\[.*)"', r'\1', t) 0105 t = re.sub(r'"(explanations\[.*)"', r'\1', t) 0106 0107 #r = re.sub(r'^"', r' "', r, flags = re.MULTILINE) 0108 0109 return t 0110 0111 prefix=\ 0112 '// This file is generated by \'rules_db_create.py\' from \'Rules.md\'.\n' \ 0113 '// Please don\'t edit it\n\n' \ 0114 '#include "rules.h"\n\n' \ 0115 '#include <QString>\n\n' \ 0116 'namespace verapp\n' \ 0117 '{\n\n' \ 0118 'namespace rules\n' \ 0119 '{\n\n' \ 0120 'void initDb(QString* titles, QString* explanations)\n' \ 0121 '{\n' 0122 0123 suffix='\n\n}\n\n}\n\n}\n' 0124 0125 f = open('rules_db.cpp', 'w') 0126 f.write(prefix) 0127 f.write(parseFile('Rules.md')) 0128 f.write(suffix)