Evospace  0.19.0
Modding API
 
Loading...
Searching...
No Matches
lua_code_highlight.py
1# -*- coding: utf-8 -*-
2
3import os
4import re
5import shutil
6
7LUATOKENS = [
8 (r'--[^\n]*', 'comment'),
9 (r'[ \t]', 'whitespace'),
10 (r'\b(print|and|break|do|else|elseif|end|false|for|function|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b', 'keyword'),
11 (r'[+-]?\d+\.\d+', 'number'),
12 (r'[+-]?\d+', 'number'),
13 (r'[a-zA-Z_][a-zA-Z0-9_]*', 'identifier'),
14 (r'".*?"', 'string'),
15 (r"'.*?'", 'string'),
16 (r'[\+\-\*\/\^%%#=<>~]', 'operator'),
17 (r'[\[\]\{\}\‍(\‍)\.,;:]', 'punctuation'),
18 (r'\b(and|or)\b', 'boolean'),
19 (r'\b(nil)\b', 'null'),
20 (r'\n', 'newline'),
21
22]
23
24def tokenize_lua(code):
25 tokens = []
26 i = 0
27 while i < len(code):
28 for pattern, token_type in LUATOKENS:
29 match = re.match(pattern, code[i:])
30 if match:
31 value = match.group(0)
32 tokens.append((token_type, value))
33 i += len(value)
34 break
35 else:
36 i += 1
37 return tokens
38
39JSONTOKENS = [
40 (r'[ \t]', 'whitespace'),
41 (r'\b(true|false|null)\b', 'boolean'),
42 (r'-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?', 'number'),
43 (r'"(?:\\.|[^"\\])*"', 'string'),
44 (r'[\[\]\{\}\:,]', 'punctuation'),
45 (r'\n', 'newline'),
46
47]
48
49def tokenize_json(code):
50 tokens = []
51 i = 0
52 while i < len(code):
53 for pattern, token_type in JSONTOKENS:
54 match = re.match(pattern, code[i:])
55 if match:
56 value = match.group(0)
57 tokens.append((token_type, value))
58 i += len(value)
59 break
60 else:
61 i += 1
62 return tokens
63
64TOKEN_COLORS = {
65 'text': '#D4D4D4',
66 'newline': '#D4D4D4',
67 'keyword': '#B988BA',
68 'string': '#C5947C',
69 'number': '#B5CEA8',
70 'operator': '#C7C7C7',
71 'punctuation': '#D4D4D4',
72 'boolean': '#6DBEF9',
73 'null': '#CE9178',
74 'identifier': '#9CC9FA',
75 'comment': '#74975D',
76}
77TOKEN_DEFAULT_COLOR = '#D4D4D4'
78
79# Regular expression to find the code blocks
80code_block_regex = re.compile(r'```(lua|json)([\s\S]+?)```|([\s\S]+?)')
81
82def extract_code_blocks(text):
83 code_blocks = []
84 pos = 0
85 while pos < len(text):
86 match = code_block_regex.match(text, pos)
87 if match.group(1):
88 code_type = match.group(1)
89 code = match.group(2)
90 code_blocks.append((code_type, code))
91 else:
92 code_blocks.append(('text', match.group(3)))
93 pos = match.end()
94 return code_blocks
95
96def decorate_tokens(tokens, spaces):
97 html = ""
98 space_n = 0
99 html += ' ' * spaces[space_n]
100 for token in tokens:
101 if token[0] == 'newline':
102 html += '<br>\n'
103 space_n += 1
104 html += '<span>' + '&nbsp;' * spaces[space_n] + '</span>'
105 elif token[0] == 'whitespace':
106 html += ' '
107 elif token[0] == 'comment': # small fix to replace - with --
108 color = TOKEN_COLORS[token[0]]
109 minus = '<span class="' + token[0] + '_code_block" style="color: ' + color + '">-</span>'
110 html += minus * 2
111 html += '<span class="' + token[0] + '_code_block" style="color: ' + color + '">' + token[1][2:] + '</span>'
112 else:
113 color = TOKEN_COLORS[token[0]]
114 html += '<span class="' + token[0] + '_code_block" style="color: ' + color + '">' + token[1] + '</span>'
115
116 return html
117
118def decorate_codeblocks(code_blocks):
119 md = ""
120 for code_block in code_blocks:
121 if code_block[0] == 'lua':
122 md += '<div class="fragment">\n'
123 tokens = tokenize_lua(code_block[1])
124 spaces = count_leading_spaces(code_block[1])
125 md += decorate_tokens(tokens, spaces)
126 md += '</div>\n'
127 elif code_block[0] == 'json':
128 md += '<div class="fragment">\n'
129 tokens = tokenize_json(code_block[1])
130 spaces = count_leading_spaces(code_block[1])
131 md += decorate_tokens(tokens, spaces)
132 md += '</div>\n'
133 else:
134 md += code_block[1]
135 return md
136
137
138def count_leading_spaces(text):
139 lines = text.splitlines()
140 leading_spaces = []
141 for line in lines:
142 stripped_line = line.lstrip()
143 leading_spaces.append(len(line) - len(stripped_line))
144 leading_spaces.append(0)
145
146 return leading_spaces
147
148for root, dirs, files in os.walk('./'):
149 for filename in files:
150 namepath = os.path.join(root, filename)
151 if namepath.find('.md') != -1:
152 with open(namepath, 'r') as file:
153 code = file.read()
154
155 if code.find('<div class="fragment">') != -1:
156 print('already decorated')
157 continue
158
159 print('colorize code in ' + namepath)
160
161 code_blocks = extract_code_blocks(code)
162 md = decorate_codeblocks(code_blocks)
163
164 with open(namepath, 'w') as file:
165 file.write(md)
166
167# try:
168# os.remove('lua_block.html')
169# except Exception as err:
170# print(err)
171
172# try:
173# shutil.copy('LuaBlock.md','lua_block.html')
174# except Exception as err:
175# print(err)