-
Notifications
You must be signed in to change notification settings - Fork 2
/
orez-md
executable file
·167 lines (153 loc) · 6.6 KB
/
orez-md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#!/usr/bin/python3
import sys
import yaml
from pygments import highlight
from pygments.lexers import CLexer
from pygments.lexers import CppLexer
from pygments.lexers import Python3Lexer
from pygments.lexers import SchemeLexer
from pygments.lexers import LuaLexer
from pygments.lexers import BashLexer
from pygments.lexers import MakefileLexer
from pygments.lexers import TexLexer
from pygments.lexers import GnuplotLexer
from pygments.lexers import TextLexer
from pygments.lexers import EmacsLispLexer
from pygments.formatters import HtmlFormatter
def make_alnum_text(text):
alnum_text = ''
for c in text:
if c.isalnum():
alnum_text += c
return alnum_text
def orez_output(text):
sys.stdout.write(text)
def orez_code_highlight(code, lexer):
if code.isspace():
return code
n_chars = len(code)
# 保留首部空白字符
leading_spaces = ''
for i in range(0, n_chars):
if not code[i].isspace():
leading_spaces = code[:i]
break
# 保留尾部空白字符
trailing_spaces = ''
for i in range(-1, -(n_chars + 1), -1):
if not code[i].isspace():
if i < -1:
trailing_spaces = code[i+1:]
break
# 代码高亮
code = code.strip()
hl_code = highlight(code, lexer(), HtmlFormatter(nowrap=True))
# 将 highlight 引入的首尾空白字符清除
hl_code = hl_code.strip()
# 将首部空白字符与尾部空白字符放回去
hl_code = leading_spaces + hl_code + trailing_spaces
return hl_code
def lang_mark_warn(code_frag, info):
sys.stderr.write("@ {0} # : ".format(code_frag['NAME'].strip("'")))
sys.stderr.write(info)
sys.stderr.write('\n')
def format_code_frag_ref(ref):
name = ref['NAME'].strip("'")
name_alnum = make_alnum_text(name)
if 'ID_ARRAY' in ref:
orez_output('<span class="orez-callee-text"># %s @</span>' % name)
for id in ref['ID_ARRAY']: # 尾随一组 \at 生成的页码
orez_output(' <a href="#%s%d">[%d]</a>' % (name_alnum, id, id))
else: # 源码域名后面是一个 \at 生成的页码
orez_output('<a href="#%s" class="orez-callee-link"># %s @</a>'
% (name_alnum, name))
if __name__=="__main__":
# 解析 yaml
x = None
if len(sys.argv) > 1:
f = open(sys.argv[1])
x = yaml.full_load(f)
f.close()
else:
x = yaml.safe_load(sys.stdin)
# 为代码高亮准备词法解析器的查找表
lexers = {'c':CLexer, 'c++':CppLexer, 'python':Python3Lexer,
'scheme':SchemeLexer, 'lua':LuaLexer, 'tex':TexLexer,
'makefile':MakefileLexer, 'gnuplot':GnuplotLexer,
'plain':TextLexer, 'elisp':EmacsLispLexer, 'bash':BashLexer}
for e in x:
if 'DOC_FRAG' in e:
orez_output(e['DOC_FRAG'].strip("'"))
orez_output("\n\n")
else:
cf = e['CODE_FRAG']
name = cf['NAME'].strip("'")
name_alnum = make_alnum_text(name)
# pre begin
if 'ID' in cf:
orez_output('<pre id="%s%d" class="orez-code-fragment">\n'
% (name_alnum, cf['ID']))
else:
orez_output('<pre id="%s" class="orez-code-fragment">\n' % (name_alnum))
# format code fragment name
orez_output('<span class="orez-code-fragment-name">@ ')
orez_output(name)
orez_output(' #</span>')
# format target label and operator
if 'OPERATOR' in cf:
if 'LABEL_REF' in cf:
label_ref = cf['LABEL_REF'].strip("'")
long_label_ref = name_alnum + '-' + make_alnum_text(label_ref)
orez_output(' <a class="orez-label-ref" ')
orez_output('href="#{0}"><{1}></a>'.format(long_label_ref, label_ref))
orez_output(' <span class="orez-symbol">{0}</span>'.format(cf['OPERATOR']))
# format source label
if 'LABEL' in cf:
label = cf['LABEL'].strip("'")
long_label = name_alnum + '-' + make_alnum_text(label)
orez_output('\n<span id="%s" class="orez-label"><%s></span>'
% (long_label, label))
orez_output("\n")
# format code fragment body
for o_e in cf['CONTENT']:
if 'SNIPPET' in o_e:
lang = 'plain'
snippet = o_e['SNIPPET'].strip("'")
if 'LANG' in cf:
lang = cf['LANG'].lower()
if lang not in lexers:
lang_mark_warn(cf, "There is not lexer for me!")
lang = 'plain'
else:
lang_mark_warn(cf, "No language mark for me!")
lexer = lexers[lang]
hl_code = orez_code_highlight(snippet, lexer)
orez_output(hl_code)
elif 'INDENT' in o_e:
orez_output(o_e['INDENT'])
elif 'REF' in o_e:
format_code_frag_ref(o_e['REF'])
orez_output('\n')
else:
illegal_code_frag_warning(cf)
# if last element is a piece of code snippet,
# a linebreak should be append
if 'SNIPPET' in cf['CONTENT'][-1]:
orez_output('\n')
# format emissions
if 'EMISSIONS' in cf:
for o_e in cf['EMISSIONS']:
emi = o_e['EMISSION']
# 由于要为 emi_name 增加了 '=> ' 前缀,若 emisi_name 为多行文本,为了美观,
# 那么每个换行符后需要增加三个空白字符作为 padding
emi_name = emi['NAME'].strip("'").replace('\n', '\n ')
emi_name_alnum = make_alnum_text(emi_name)
if 'ID' in emi:
emi_link = '<span class="orez-symbol">=></span> ' + \
'<a href="#{0}{1}" class="proc-emissions-name">{2}</a>\n'
orez_output(emi_link.format(emi_name_alnum, emi['ID'], emi_name))
else:
emi_link = '<span class="orez-symbol">=></span> ' + \
'<a href="#{0}" class="proc-emissions-name">{1}</a>\n'
orez_output(emi_link.format(emi_name_alnum, emi_name))
orez_output("</pre>\n\n")