Skip to content

Commit 3e54e6f

Browse files
Fix "00" arg name and whitespace around template arg in el edition
Trim whitespace around frame args after expanding them Check out wikitextprocessor PR #363 Issue was that in some Greek templates, we had a ton of `{{#if:...}}` templates as template arguments, and they were written with spaces in between: `| {{#if:...}} {{#if:...}} |`. The ifs left magic characters which prevented stripping before they were expanded into empty strings, so the trimming has to be done later. Co-authored-by: xxyzz <gitpull@protonmail.com>
1 parent c40eb85 commit 3e54e6f

File tree

5 files changed

+81
-19
lines changed

5 files changed

+81
-19
lines changed

src/wikitextprocessor/core.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,7 +1212,7 @@ def expand_args(coded: str, argmap: TemplateArgs) -> str:
12121212
expand_args(args[0], argmap), parent, True
12131213
).strip()
12141214
self.expand_stack.pop()
1215-
if k.isdigit():
1215+
if k.isdigit() and int(k) > 0:
12161216
k = int(k)
12171217
else:
12181218
k = re.sub(r"\s+", " ", k).strip()
@@ -1428,7 +1428,7 @@ def expander(arg: str) -> str:
14281428
# https://en.wikipedia.org/wiki/Help:Template
14291429
# (but not around unnamed parameters)
14301430
k, arg = m2.groups()
1431-
if k.isdigit():
1431+
if k.isdigit() and int(k) > 0:
14321432
k = int(k)
14331433
else:
14341434
self.expand_stack.append("ARGNAME")

src/wikitextprocessor/lua/_sandbox_phase2.lua

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,37 @@ assert(_new_loadData ~= nil)
1010

1111
local function frame_args_index(new_args, key)
1212
-- print("frame_args_index", key)
13-
local i = tonumber(key)
14-
if key ~= "inf" and key ~= "nan" and i ~= nil then
15-
key = i
16-
end
1713
local v = new_args._orig[key]
1814
if v == nil then
19-
return nil
15+
local i = tonumber(key)
16+
if i ~= nil then
17+
key = i
18+
else
19+
return nil
20+
end
21+
v = new_args._orig[key]
22+
if v == nil then
23+
return nil
24+
end
2025
end
2126
if not new_args._preprocessed[key] then
2227
local frame = new_args._frame
23-
v = frame:preprocess(v)
28+
if type(v) == "userdata" then
29+
-- Python tuple in luaexec.call_lua_sandbox.make_frame()
30+
local is_named = v[1]
31+
v = frame:preprocess(v[0])
32+
-- https://en.wikipedia.org/wiki/Help:Template#Whitespace_handling
33+
if is_named then
34+
v = v:match "^%s*(.-)%s*$"
35+
end
36+
else
37+
v = frame:preprocess(v)
38+
end
2439
-- Cache preprocessed value so we only preprocess each argument once
2540
new_args._preprocessed[key] = true
2641
new_args._orig[key] = v
2742
end
28-
-- print("frame_args_index", key, "->", v)
43+
-- print("frame_args_index", key, "->", "'"..v.."'")
2944
return v
3045
end
3146

src/wikitextprocessor/luaexec.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ def recurse(x: Union[list, tuple, dict]) -> Any:
135135
# Convert numeric keys to integers and see if we can make it a
136136
# table with sequential integer keys.
137137
for k, v in list(x.items()):
138-
if k.isdigit():
138+
if k.isdigit() and int(k) > 0:
139139
del x[k]
140140
x[int(k)] = recurse(v)
141141
else:
@@ -429,29 +429,31 @@ def make_frame(
429429
frame_args = {}
430430
for k, arg in args.items():
431431
arg = re.sub(r"(?si)(<\s*noinclude\s*/\s*>|\n$)", "", arg)
432-
frame_args[k] = arg
432+
frame_args[k] = (arg, False)
433433
else:
434434
assert isinstance(args, (list, tuple))
435435
frame_args = {}
436436
num = 1
437437
for arg in args:
438438
# |-separated strings in {{templates|arg=value|...}}
439439
m = re.match(r"""(?s)^\s*([^<>="']+?)\s*=\s*(.*?)\s*$""", arg)
440-
if m:
441-
# Have argument name
440+
if m is not None:
441+
# named parameter
442442
k, arg = m.groups()
443-
if k.isdigit():
443+
if k.isdigit() and int(k) > 0:
444+
# Greek wiktionary uses '0', '00' and '000' as
445+
# parameter names...
444446
k = int(k)
445-
if k < 1 or k > 1000:
447+
if k > 1000:
446448
ctx.warning(
447-
f"Template argument index <1 or >1000: {k=!r}",
449+
f"Template argument index >1000: {k=!r}",
448450
sortid="luaexec/477/20230710",
449451
)
450452
k = 1000
451453
if num <= k:
452454
num = k + 1
453455
else:
454-
# No argument name
456+
# unnamed parameter
455457
k = num
456458
num += 1
457459
if k in frame_args:
@@ -465,7 +467,7 @@ def make_frame(
465467
# does not always like them (e.g., remove_links() in
466468
# Module:links).
467469
arg = re.sub(r"(?si)(<\s*noinclude\s*/\s*>|\n$)", "", arg)
468-
frame_args[k] = arg
470+
frame_args[k] = (arg, m is not None)
469471
frame_args_lt: "_LuaTable" = lua.table_from(frame_args) # type: ignore[union-attr]
470472

471473
def extensionTag(frame: "_LuaTable", *args: Any) -> str:

src/wikitextprocessor/parser.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,10 @@ def template_parameters(self) -> TemplateParameters:
632632
parameter_value = parameter[
633633
equal_sign_index + 1 :
634634
].strip()
635-
if parameter_name.isdigit(): # value contains "="
635+
if (
636+
parameter_name.isdigit()
637+
and int(parameter_name) > 0
638+
): # value contains "="
636639
parameter_name = int(parameter_name)
637640
is_named = False
638641
if len(parameter_value) > 0:

tests/test_lua.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,3 +598,45 @@ def test_mw_uri_anchorEncode(self):
598598
return export""",
599599
)
600600
self.assertEqual(self.wtp.expand("{{#invoke:test|test}}"), "**")
601+
602+
def test_el_zero_arg(self):
603+
# https://el.wiktionary.org/wiki/Πρότυπο:ετ
604+
# Unnamed template parameters and numbered parameters can only
605+
# be positive non-zero integers; zero or "00" or negative is a string
606+
self.wtp.start_page("θηλυκός")
607+
self.wtp.add_page(
608+
"Module:test",
609+
828,
610+
"""local export = {}
611+
function export.test(frame)
612+
return tostring(frame.args['0']) .. "|" ..
613+
--tostring(frame.args[0]) .. "|" ..
614+
tostring(frame.args['00']) .. "|" ..
615+
tostring(frame.args[1]) .. "|" ..
616+
tostring(frame.args[2]) .. "|" ..
617+
tostring(frame.args['named'])
618+
end
619+
return export""",
620+
)
621+
self.assertEqual(
622+
self.wtp.expand(
623+
"{{#invoke:test|test|0= 0 |00= 00 | first |2= second |named= named }}" # noqa: E501
624+
),
625+
"0|00| first |second|named",
626+
)
627+
628+
def test_el_strip_arg(self):
629+
self.wtp.start_page("θηλυκός")
630+
self.wtp.add_page(
631+
"Module:test",
632+
828,
633+
"""local export = {}
634+
function export.test(frame)
635+
return tostring(frame.args['foo'])
636+
end
637+
return export""",
638+
)
639+
self.assertEqual(
640+
self.wtp.expand("{{#invoke:test|test|foo= {{#if||}} {{#if||}} }}"),
641+
"",
642+
)

0 commit comments

Comments
 (0)