Skip to content

Commit e37b904

Browse files
committed
Implement tables in documentation parser
Cherry pick from upstream Eluna ElunaLuaEngine@71ddf6c
1 parent a46552b commit e37b904

File tree

4 files changed

+491
-448
lines changed

4 files changed

+491
-448
lines changed

src/LuaEngine/docs/ALEDoc/parser.py

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
import typing
44
import markdown
55
from typedecorator import params, returns, Nullable
6+
from typing import Any, List, TypedDict
67

8+
class TableDict(TypedDict):
9+
columns: List[str]
10+
values: List[List[Any]]
711

812
class ParameterDoc(object):
913
"""The documentation data of a parameter or return value for an ALE method."""
@@ -65,13 +69,24 @@ def __init__(self, name, data_type, description, default_value=None):
6569

6670
class MethodDoc(object):
6771
"""The documentation data of an ALE method."""
68-
@params(self=object, name=str, description=str, prototypes=[str], parameters=[ParameterDoc], returned=[ParameterDoc])
69-
def __init__(self, name, description, prototypes, parameters, returned):
72+
@params(self=object, name=str, description=str, table=TableDict, prototypes=[str], parameters=[ParameterDoc], returned=[ParameterDoc])
73+
def __init__(self, name, description, table, prototypes, parameters, returned):
7074
self.name = name
7175
self.prototypes = prototypes
76+
self.table = table
7277
self.parameters = parameters
7378
self.returned = returned
7479

80+
if table:
81+
# Generate Markdown Table
82+
md_table = '| ' + ' | '.join(table['columns']) + ' |\n' # Header
83+
md_table += '| ' + ' | '.join(['---'] * len(table['columns'])) + ' |\n' # Separator
84+
85+
for row in table['values']:
86+
md_table += '| ' + ' | '.join(row) + ' |\n' # Rows
87+
88+
self.table = markdown.markdown(md_table, extensions=['tables'])
89+
7590
# Parse the description as Markdown.
7691
self.description = markdown.markdown(description)
7792
# Pull the first paragraph out of the description as the short description.
@@ -123,6 +138,11 @@ class ClassParser(object):
123138
body_regex = re.compile(r"\s*\s?\*\s?(.*)") # The "body", i.e. a * and optionally some descriptive text.
124139
# An extra optional space (\s?) was thrown in to make it different from `class_body_regex`.
125140

141+
# Regular expressions for parsing a table.
142+
table_regex = re.compile(r"\s*\*\s@table")
143+
table_columns_regex = re.compile(r"\s*\*\s@columns\s*\[(.+)\]")
144+
table_values_regex = re.compile(r"\s*\*\s@values\s*\[(.+)\]")
145+
126146
param_regex = re.compile(r"""\s*\*\s@param\s # The @param tag starts with opt. whitespace followed by "* @param ".
127147
([^\s]+)\s(\w+)? # The data type, a space, and the name of the param.
128148
(?:\s=\s(\w+))? # The default value: a = surrounded by spaces, followed by text.
@@ -163,6 +183,7 @@ def reset(self):
163183
self.returned = []
164184
self.method_name = None
165185
self.prototypes = []
186+
self.table = {}
166187

167188
def handle_class_body(self, match):
168189
text = match.group(1)
@@ -171,6 +192,21 @@ def handle_class_body(self, match):
171192
def handle_body(self, match):
172193
text = match.group(1)
173194
self.description += text + '\n'
195+
196+
def handle_table(self, line):
197+
self.table = {
198+
"columns": [],
199+
"values": []
200+
}
201+
202+
def handle_table_columns(self, match):
203+
if self.table:
204+
self.table["columns"] = match.group(1).split(", ")
205+
206+
def handle_table_values(self, match):
207+
if self.table:
208+
values = re.findall(r'(?:[^,"]|"(?:\\.|[^"])*")+', match.group(1))
209+
self.table["values"].append([v.strip(' "') for v in values])
174210

175211
def handle_param(self, match):
176212
data_type, name, default, description = match.group(1), match.group(2), match.group(3), match.group(4)
@@ -247,7 +283,7 @@ def make_prototype(parameters):
247283
# Format the method name into each prototype.
248284
self.prototypes = [proto.format(self.method_name) for proto in self.prototypes]
249285

250-
self.methods.append(MethodDoc(self.method_name, self.description, self.prototypes, self.params, self.returned))
286+
self.methods.append(MethodDoc(self.method_name, self.description, self.table, self.prototypes, self.params, self.returned))
251287

252288
# Table of which handler is used to handle each regular expressions.
253289
regex_handlers = {
@@ -256,6 +292,9 @@ def make_prototype(parameters):
256292
class_end_regex: None,
257293
start_regex: None,
258294
body_regex: handle_body,
295+
table_regex: handle_table,
296+
table_columns_regex: handle_table_columns,
297+
table_values_regex: handle_table_values,
259298
param_regex: handle_param,
260299
return_regex: handle_return,
261300
proto_regex: handle_proto,
@@ -270,10 +309,13 @@ def make_prototype(parameters):
270309
class_start_regex: [class_end_regex, class_body_regex],
271310
class_body_regex: [class_end_regex, class_body_regex],
272311
class_end_regex: [],
273-
start_regex: [param_regex, return_regex, proto_regex, comment_end_regex, body_regex],
274-
body_regex: [param_regex, return_regex, proto_regex, comment_end_regex, body_regex],
275-
proto_regex: [param_regex, return_regex, proto_regex, comment_end_regex, body_regex],
276-
param_regex: [param_regex, return_regex, comment_end_regex, body_regex],
312+
start_regex: [table_regex, param_regex, return_regex, proto_regex, comment_end_regex, body_regex],
313+
body_regex: [table_regex, param_regex, return_regex, proto_regex, comment_end_regex, body_regex],
314+
proto_regex: [table_regex, param_regex, return_regex, proto_regex, comment_end_regex, body_regex],
315+
table_regex: [table_regex, table_columns_regex, param_regex, return_regex, comment_end_regex, body_regex],
316+
table_columns_regex: [table_values_regex, param_regex, return_regex, comment_end_regex, body_regex],
317+
table_values_regex: [table_values_regex, param_regex, return_regex, comment_end_regex, body_regex],
318+
param_regex: [table_regex, param_regex, return_regex, comment_end_regex, body_regex],
277319
return_regex: [return_regex, comment_end_regex],
278320
comment_end_regex: [end_regex],
279321
end_regex: [],

src/LuaEngine/docs/ALEDoc/static/main.css

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,41 @@ nav.sub {
155155
min-height: 100%;
156156
}
157157

158-
.content, nav { max-width: 960px; }
158+
.content, nav { max-width: 80vw; }
159+
160+
.docblock .table-container {
161+
width: 100%;
162+
overflow-x: auto;
163+
margin-bottom: 20px;
164+
}
165+
166+
.docblock table {
167+
max-width: 50vw;
168+
border-collapse: collapse !important;
169+
table-layout: auto;
170+
margin-bottom: 20px;
171+
font-family: "Source Code Pro", Menlo, Monaco, Consolas, "DejaVu Sans Mono", Inconsolata, monospace;
172+
}
173+
174+
.docblock th, .docblock td {
175+
padding: 10px;
176+
text-align: left;
177+
border: 1px solid #ddd;
178+
white-space: nowrap;
179+
}
180+
181+
.docblock th {
182+
background-color: #f5f5f5;
183+
font-weight: bold;
184+
}
185+
186+
.docblock tr:nth-child(even) {
187+
background-color: #f9f9f9;
188+
}
189+
190+
.docblock table {
191+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
192+
}
159193

160194
/* Everything else */
161195

src/LuaEngine/docs/ALEDoc/templates/method.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,15 @@ <h2>{{ current_class.name }} Methods</h2>
4747
<p>For temporary documentation, please check the <a href="https://github.com/azerothcore/mod-ale/blob/master/src/LuaEngine/LuaFunctions.cpp">LuaFunctions</a> source file.</p>
4848
{%- endif %}
4949

50+
51+
{%- if current_method.table %}
52+
<div class="table-container">
53+
<p>
54+
{{ current_method.table }}
55+
</p>
56+
</div>
57+
{%- endif %}
58+
5059
<h2 id="synopsis" class='section-header'>
5160
<a href="#synopsis">Synopsis</a>
5261
</h2>

0 commit comments

Comments
 (0)