Skip to content

Commit d8225dc

Browse files
committed
fix function simplify_transclusion()
1 parent c0f5cbd commit d8225dc

9 files changed

Lines changed: 146 additions & 81 deletions

File tree

_test suite/test.js

Lines changed: 71 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4321,11 +4321,15 @@ function test_wiki() {
43214321
wikitext = "'''b''bi'''"; parsed = CeL.wiki.parser(wikitext).parse();
43224322
assert([wikitext, parsed.toString()]);
43234323
assert(['bold', parsed[0].type], "''' bold '''");
4324-
// '''''t''''' → <i><b>t</b></i>
4324+
// '''''ib''''' → <i><b>ib</b></i>
43254325
wikitext = "'''''Italic and bold formatting'''''"; parsed = CeL.wiki.parser(wikitext).parse();
43264326
assert([wikitext, parsed.toString()]);
4327-
assert(['italic', parsed[0].type], "'''''t''''' will render as <i><b>t</b></i>");
4327+
assert(['italic', parsed[0].type], "'''''ib''''' will render as <i><b>ib</b></i>");
43284328
assert(['bold', parsed[0][1].type]);
4329+
// '''''bi''b''' → <b><i>bi</i>b</b>
4330+
wikitext = "'''''bi''b'''"; parsed = CeL.wiki.parser(wikitext).parse();
4331+
assert([wikitext, parsed.toString()]);
4332+
assert(['bold', parsed[0].type], "'''''bi''b''' will render as <b><i>bi</i>b</b>");
43294333
wikitext = "''Italic'''Italic and bold formatting'''Italic''"; parsed = CeL.wiki.parser(wikitext).parse();
43304334
assert([wikitext, parsed.toString()]);
43314335
assert(['italic', parsed[0].type], "'' '''t''' '' will render as <i><b>t</b></i>");
@@ -5807,10 +5811,39 @@ function test_wiki() {
58075811
var test_name = 'enwiki: expand_transclusion';
58085812
_setup_test(test_name);
58095813

5814+
var options = CeL.wiki.add_session_to_options(enwiki, { on_page_title: 'ABC', allow_promise: true });
58105815
var promise = Promise.resolve();
58115816

58125817
promise = promise.then(function () {
5813-
var options = CeL.wiki.add_session_to_options(enwiki, { on_page_title: 'ABC', allow_promise: true });
5818+
return Promise.all([
5819+
'{{Ifsubst|yes|no}}',
5820+
'{{issubst}}'
5821+
].map(function (wikitext) {
5822+
return CeL.wiki.expand_transclusion(wikitext, options);
5823+
}));
5824+
}).then(function (results) {
5825+
//console.trace(results);
5826+
var i = 0;
5827+
assert(['no', results[i++].toString()], test_name + ': CeL.wiki.expand_transclusion( {{Ifsubst}} )');
5828+
assert(['', results[i++].toString()], test_name + ': CeL.wiki.expand_transclusion( {{issubst}} )');
5829+
5830+
5831+
// https://zh.wikipedia.org/wiki/Special:ApiSandbox#action=expandtemplates&format=json&text=%7B%7BIfsubst%7Cyes%7Cno%7D%7D&formatversion=2
5832+
var parsed = CeL.wiki.expand_transclusion('{{safesubst:Ifsubst|yes1|no1}}', options);
5833+
assert(['no1', parsed.toString()], test_name + ': CeL.wiki.expand_transclusion( {{safesubst:Ifsubst}} )');
5834+
5835+
var PST_options = Object.assign({ mode: 'PST' }, options);
5836+
parsed = CeL.wiki.expand_transclusion('{{safesubst:Ifsubst|yes2|no2}}', PST_options);
5837+
assert(['yes2', parsed.toString()], test_name + ': CeL.wiki.expand_transclusion( {{safesubst:Ifsubst}}, mode: PST )');
5838+
5839+
parsed = CeL.wiki.expand_transclusion('{{safesubst:issubst}}', options);
5840+
assert(['', parsed.toString()], test_name + ': CeL.wiki.expand_transclusion( {{safesubst:issubst}} )');
5841+
5842+
parsed = CeL.wiki.expand_transclusion('{{safesubst:issubst}}', PST_options);
5843+
assert(['yes', parsed.toString()], test_name + ': CeL.wiki.expand_transclusion( {{safesubst:issubst}}, mode: PST )');
5844+
});
5845+
5846+
promise = promise.then(function () {
58145847
return Promise.all([
58155848
'{{w|ABC}}{{w|ABC|DEF}}',
58165849
'{{str right |Lorem ipsum dolor sit amet |10}}',
@@ -6132,45 +6165,48 @@ function test_wiki() {
61326165
var promise = Promise.resolve();
61336166

61346167
promise = promise.then(function () {
6135-
return CeL.wiki.expand_transclusion('{{Ifsubst|yes|no}}', options);
6136-
}).then(function (parsed) {
6137-
//console.trace(parsed);
6138-
assert(['no', parsed.toString()], 'CeL.wiki.expand_transclusion( {{Ifsubst}} )');
6139-
});
6168+
return Promise.all([
6169+
'{{Ifsubst|yes|no}}',
6170+
'{{issubst}}'
6171+
].map(function (wikitext) {
6172+
return CeL.wiki.expand_transclusion(wikitext, options);
6173+
}));
6174+
}).then(function (results) {
6175+
//console.trace(results);
6176+
var i = 0;
6177+
assert(['no', results[i++].toString()], test_name + ': CeL.wiki.expand_transclusion( {{Ifsubst}} )');
6178+
assert(['', results[i++].toString()], test_name + ': CeL.wiki.expand_transclusion( {{issubst}} )');
6179+
61406180

6141-
promise = promise.then(function () {
61426181
// https://zh.wikipedia.org/wiki/Special:ApiSandbox#action=expandtemplates&format=json&text=%7B%7BIfsubst%7Cyes%7Cno%7D%7D&formatversion=2
6143-
return CeL.wiki.expand_transclusion('{{safesubst:Ifsubst|yes|no}}', options);
6144-
}).then(function (parsed) {
6145-
//console.trace(parsed);
6146-
assert(['no', parsed.toString()], 'CeL.wiki.expand_transclusion( {{safesubst:Ifsubst}} )');
6147-
});
6182+
var parsed = CeL.wiki.expand_transclusion('{{safesubst:Ifsubst|yes1|no1}}', options);
6183+
assert(['no1', parsed.toString()], test_name + ': CeL.wiki.expand_transclusion( {{safesubst:Ifsubst}} )');
61486184

6149-
promise = promise.then(function () {
6150-
var _options = Object.assign({ mode: 'PST' }, options);
6151-
return CeL.wiki.expand_transclusion('{{safesubst:Ifsubst|yes|no}}', _options);
6152-
}).then(function (parsed) {
6153-
//console.trace(parsed);
6154-
assert(['yes', parsed.toString()], 'CeL.wiki.expand_transclusion( {{safesubst:Ifsubst}}, mode: PST )');
6155-
});
6185+
var PST_options = Object.assign({ mode: 'PST' }, options);
6186+
parsed = CeL.wiki.expand_transclusion('{{safesubst:Ifsubst|yes2|no2}}', PST_options);
6187+
assert(['yes2', parsed.toString()], test_name + ': CeL.wiki.expand_transclusion( {{safesubst:Ifsubst}}, mode: PST )');
61566188

6157-
promise = promise.then(function () {
6158-
return CeL.wiki.expand_transclusion('{{a|條目|顯示文字|name=錨點名稱}}', options);
6159-
}).then(function (parsed) {
6160-
//console.trace(parsed);
6161-
assert(['<span id="錨點名稱"></span>[[條目|顯示文字]]', parsed.toString()], 'CeL.wiki.expand_transclusion() using wiki.template_functions: {{a}}');
6162-
});
6189+
parsed = CeL.wiki.expand_transclusion('{{safesubst:issubst}}', options);
6190+
assert(['', parsed.toString()], test_name + ': CeL.wiki.expand_transclusion( {{safesubst:issubst}} )');
61636191

6164-
promise = promise.then(function () {
6165-
return CeL.wiki.expand_transclusion('{{Kai|指引}}改为{{Kai|论述}}', options);
6166-
}).then(function (parsed) {
6167-
assert(['<templatestyles src="Template:楷體/styles.css" /><span class="template-kai">指引</span>改为<templatestyles src="Template:楷體/styles.css" /><span class="template-kai">论述</span>', parsed.toString()], 'CeL.wiki.expand_transclusion() fetch page #1');
6192+
parsed = CeL.wiki.expand_transclusion('{{safesubst:issubst}}', PST_options);
6193+
assert(['yes', parsed.toString()], test_name + ': CeL.wiki.expand_transclusion( {{safesubst:issubst}}, mode: PST )');
61686194
});
61696195

61706196
promise = promise.then(function () {
6171-
return CeL.wiki.expand_transclusion('{{U|user}}\n', options);
6172-
}).then(function (parsed) {
6173-
assert(['[[User:user|user]]\n', parsed.toString()], 'CeL.wiki.expand_transclusion() fetch page #2');
6197+
return Promise.all([
6198+
'{{a|條目|顯示文字|name=錨點名稱}}',
6199+
'{{Kai|指引}}改为{{Kai|论述}}',
6200+
'{{U|user}}\n'
6201+
].map(function (wikitext) {
6202+
return CeL.wiki.expand_transclusion(wikitext, options);
6203+
}));
6204+
}).then(function (results) {
6205+
//console.trace(results);
6206+
var i = 0;
6207+
assert(['<span id="錨點名稱"></span>[[條目|顯示文字]]', results[i++].toString()], 'CeL.wiki.expand_transclusion() using wiki.template_functions: {{a}}');
6208+
assert(['<templatestyles src="Template:楷體/styles.css" /><span class="template-kai">指引</span>改为<templatestyles src="Template:楷體/styles.css" /><span class="template-kai">论述</span>', results[i++].toString()], 'CeL.wiki.expand_transclusion() fetch page #1');
6209+
assert(['[[User:user|user]]\n', results[i++].toString()], 'CeL.wiki.expand_transclusion() fetch page #2');
61746210
});
61756211

61766212
promise = promise.then(function () {
@@ -6268,7 +6304,7 @@ function test_wiki() {
62686304
});
62696305

62706306
promise = promise.then(function () {
6271-
var _options = Object.assign({}, options);
6307+
var _options = Object.assign({ mode: 'PST' }, options);
62726308
_options.max_template_depth = 1;
62736309
return CeL.wiki.expand_transclusion('{{subst:subst test 1}}', _options);
62746310
}).then(function (parsed) {

application/net/wiki/namespace.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3148,7 +3148,8 @@ function module_code(library_namespace) {
31483148
var url_pattern = url.replace(PATTERN_language_of_wiki_url,
31493149
'//__language_code__.');
31503150
url_pattern = convert_url_parameters(url_pattern);
3151-
url_pattern = url_pattern.replace('__language_code__', '([^.]+)');
3151+
url_pattern = url_pattern.replace('__language_code__\\.',
3152+
'([^.]+)\\.(?:m\\.)?');
31523153
if (Array.isArray(family_with_language[url_pattern])) {
31533154
family_with_language[url_pattern].push(interwikimap_data);
31543155
} else {

application/net/wiki/parser/evaluate.js

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,15 @@ function module_code(library_namespace) {
150150
if (typeof token === 'string') {
151151
// 經過解析,替代數值為無特殊作用之 plain text。
152152
} else {
153+
// incase token.type === 'parameter', itself is a parameter
153154
// set_shell(token[1])
154155
token = [ token ];
156+
155157
token = convert_parameter(token, parameters, options);
156-
// assert: token.length === 1
157-
token = token[0];
158+
if (token.length === 1
159+
&& (!token.type || token.type === 'plain')) {
160+
token = token[0];
161+
}
158162
}
159163
if (/subst:/i.test(token))
160164
need_re_parse = true;
@@ -200,6 +204,7 @@ function module_code(library_namespace) {
200204

201205
if (!token.need_subst && options.mode === 'PST' && !(token.name in {
202206
'#invoke' : true,
207+
SUBST : true,
203208
SAFESUBST : true
204209
})) {
205210
return;
@@ -485,9 +490,14 @@ function module_code(library_namespace) {
485490
var _parsed = wiki_API.parse(wikitext, options);
486491
if (false && template_depth_now >= (options.max_template_depth
487492
// ↑ false: subst 無視 max_template_depth,都會展開。
488-
|| DEFAULT_MAX_TEMPLATE_DEPTH)
493+
|| DEFAULT_MAX_TEMPLATE_DEPTH)) {
494+
_parsed = null;
495+
}
496+
if (!_parsed || _parsed.type !== 'transclusion'
489497
//
490-
|| !_parsed || _parsed.type !== 'transclusion') {
498+
&& (_parsed.type !== 'magic_word_function'
499+
//
500+
|| options.mode !== 'PST')) {
491501
// `page_data ?`: 為了維持cache與第一次執行的輸出相同。
492502
// 例如在 `await CeL.wiki.expand_transclusion(
493503
// '{{Namespace detect|main=Article text}}')`
@@ -496,10 +506,14 @@ function module_code(library_namespace) {
496506

497507
// _parsed.need_subst = true;
498508
// expand template
499-
_parsed = expand_transclusion(_parsed, Object.assign(Object
509+
_parsed = expand_transclusion(_parsed,
510+
//
511+
_parsed.type === 'transclusion' ? Object.assign(Object
500512
.clone(options), {
513+
// caller
501514
template_token_called : _parsed
502-
}) // , template_depth_now
515+
}) : options
516+
// , template_depth_now
503517
);
504518
return _parsed;
505519
}, {
@@ -625,8 +639,8 @@ function module_code(library_namespace) {
625639
if (false) {
626640
token = expand_transclusion(promise.toString(),
627641
// 不用 wiki_API.parse() 以容許 token.expand() 回傳 templates。
628-
Object.assign(Object.create(null), options, {
629-
// valler
642+
Object.assign(Object.clone(options), {
643+
// caller
630644
template_token_called : token
631645
}), template_depth_now);
632646

@@ -804,7 +818,8 @@ function module_code(library_namespace) {
804818
token = wiki_API.parse(token.toString(), options);
805819
token = repeatedly_expand_template_token(token, options,
806820
template_depth_now);
807-
if (token.type === 'plain' && token.length === 1)
821+
if (token.length === 1
822+
&& (!token.type || token.type === 'plain'))
808823
token = token[0];
809824
// console.trace(token);
810825
}
@@ -856,6 +871,7 @@ function module_code(library_namespace) {
856871
var max_template_depth = options.max_template_depth
857872
|| DEFAULT_MAX_TEMPLATE_DEPTH;
858873
if (!token.need_subst
874+
// ↑ subst 無視 max_template_depth,都會展開。
859875
&& (template_depth_now >= max_template_depth || get_template_depth_now_of_token(token) >= max_template_depth)
860876
&& (!options.ignore_template_depth_limit || options
861877
.ignore_template_depth_limit(token))) {

application/net/wiki/parser/misc.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ function module_code(library_namespace) {
202202
url = new library_namespace.URI(url);
203203
}
204204
var host = url.host;
205-
return host.replace(/^[^.]+/, '');
205+
return host.replace(/^[^.]+\.(?:m\.)?/, '.');
206206
}
207207

208208
var prefix, name, interwikimap_data, interwikimap_data_list;
@@ -246,6 +246,11 @@ function module_code(library_namespace) {
246246
// TODO: 檢查非正規 interwiki links
247247
// e.g., http://語言前綴.wikipedia.org/w/index.php?title=頁面標題
248248
// @see [[w:zh:Template:Fullurl]]
249+
if (url.includes('wikipedia') && !url.includes('/https://')) {
250+
// https://web.archive.org/web/20161012200259/https://zh.wikipedia.org/wiki/%E5%89%8D%E7%94%B0%E5%88%A9%E5%AE%B6
251+
library_namespace.debug('Non-standard interwiki link? '
252+
+ url, 6, 'parse_interwiki_url');
253+
}
249254
return;
250255
}
251256

application/net/wiki/parser/section.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1771,7 +1771,7 @@ function module_code(library_namespace) {
17711771
wiki_API.expand_transclusion(wikitext, options))
17721772
//
17731773
.then(function(wikitext) {
1774-
var _options = Object.assign(Object.create(null), options);
1774+
var _options = Object.clone(options);
17751775

17761776
// ↓ 不可這麼做:會造成章節標題不被展開。
17771777
// Do not need expand templates any more.

application/net/wiki/parser/wikitext.js

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4390,8 +4390,30 @@ function module_code(library_namespace) {
43904390

43914391
wikitext = '';
43924392
var tokens_to_resolve = [];
4393+
function add_to_queue(type, unit, this_token) {
4394+
var count = type === 'bold' ? 3 : 2;
4395+
var token = _set_wiki_type([ unit[1].slice(0, count), '' ],
4396+
type);
4397+
unit[1] = unit[1].slice(count);
4398+
tokens_to_resolve.push(token);
4399+
queue.push(token);
4400+
var mark = include_mark + (queue.length - 1) + end_mark;
4401+
if (this_token) {
4402+
token.apostrophe_parent = this_token;
4403+
this_token[KEY_apostrophe_element_content] += mark;
4404+
} else {
4405+
wikitext += mark;
4406+
}
4407+
// this_token = token;
4408+
return token;
4409+
}
4410+
43934411
for (var index = 0, this_token = undefined; index < unit_list.length; index++) {
4394-
var unit = unit_list[index], switch_italic = unit.switch_italic, switch_bold = unit.switch_bold;
4412+
var unit = unit_list[index];
4413+
/** 改變 italic 的狀態 */
4414+
var switch_italic = unit.switch_italic;
4415+
/** 改變 bold 的狀態 */
4416+
var switch_bold = unit.switch_bold;
43954417
if (!switch_italic && !switch_bold) {
43964418
// assert: unit[1].length === 3 || unit[1].length === 4
43974419
// 標記b: 其他未設定的都填b
@@ -4495,43 +4517,28 @@ function module_code(library_namespace) {
44954517

44964518
// assert: 皆為重新開始 quote,沒有結束的。
44974519

4498-
// MediaWiki 把 <b> 放在 <i> 中: <i><b></b></i>
4520+
// MediaWiki 把 <b> 放在 <i> 中:
4521+
// ''''ib''''' → <i><b>ib</b></i>
4522+
// 因此先從<i>開始。
44994523
if (switch_italic) {
45004524
// assert: !this_token || this_token.type === 'bold'
45014525
// assert: unit[1].length === 2 || unit[1].length === 5
4502-
var token = _set_wiki_type([ unit[1].slice(0, 2), '' ],
4503-
'italic');
4504-
// if (switch_bold)
4505-
unit[1] = unit[1].slice(2);
4506-
tokens_to_resolve.push(token);
4507-
queue.push(token);
4508-
var mark = include_mark + (queue.length - 1) + end_mark;
4509-
if (this_token) {
4510-
token.apostrophe_parent = this_token;
4511-
this_token[KEY_apostrophe_element_content] += mark;
4512-
} else {
4513-
wikitext += mark;
4526+
if (switch_bold && !this_token && unit_list[index + 1]
4527+
&& unit_list[index + 1][1].length === 2) {
4528+
// '''''bi''b''' → <b><i>bi</i>b</b>
4529+
this_token = add_to_queue('bold', unit, this_token);
4530+
// 已設定過粗體。
4531+
switch_bold = false;
45144532
}
4515-
this_token = token;
4533+
this_token = add_to_queue('italic', unit, this_token);
45164534
}
45174535

45184536
if (switch_bold) {
45194537
// assert: !this_token || this_token.type === 'italic'
45204538
// assert: unit[1].length === 3
4521-
var token = _set_wiki_type([ unit[1], '' ], 'bold');
4522-
// needless
4523-
// unit[1] = unit[1].slice(3);
4524-
tokens_to_resolve.push(token);
4525-
queue.push(token);
4526-
var mark = include_mark + (queue.length - 1) + end_mark;
4527-
if (this_token) {
4528-
token.apostrophe_parent = this_token;
4529-
this_token[KEY_apostrophe_element_content] += mark;
4530-
} else {
4531-
wikitext += mark;
4532-
}
4533-
this_token = token;
4539+
this_token = add_to_queue('bold', unit, this_token);
45344540
}
4541+
// assert: unit[1].length === 0
45354542
}
45364543

45374544
tokens_to_resolve.forEach(function(token) {
@@ -5194,11 +5201,6 @@ function module_code(library_namespace) {
51945201
// 可跨行。
51955202
parse_behavior_switch);
51965203

5197-
// 若是要處理<b>, <i>這兩項,也必須調整 wiki_API.section_link()。
5198-
5199-
// ''''b''''' → <i><b>b</b></i>
5200-
// 因此先從<b>開始找。
5201-
52025204
// 再解析一次。
52035205
// e.g., for `[[{{T|P}}]]`, `[[{{#if:A|A|B}}]]`
52045206
wikitext = wikitext.replace_till_stable(
@@ -5211,6 +5213,7 @@ function module_code(library_namespace) {
52115213
// → split_text_apostrophe_unit()
52125214
// 注意: '''{{font color}}''', '''{{tsl}}''', '''{{text}}'''
52135215

5216+
// 若是要處理<b>, <i>這兩項,也必須調整 wiki_API.section_link()。
52145217
if (!options.inside_apostrophe) {
52155218
// '''~''' ''~'' 不能跨行。
52165219
wikitext = wikitext.split('\n').map(split_text_apostrophe_unit)

application/net/wiki/task.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4874,7 +4874,7 @@ function module_code(library_namespace) {
48744874
// deprecated:
48754875

48764876
// https://www.mediawiki.org/w/api.php?action=help&modules=login
4877-
var token = Object.assign(Object.create(null), session.token);
4877+
var token = Object.clone(session.token);
48784878
// console.log(token);
48794879
// .csrftoken 是本函式為 cache 加上的,非正規 parameter。
48804880
delete token.csrftoken;

0 commit comments

Comments
 (0)