3
3
using System . Collections . ObjectModel ;
4
4
using System . Linq ;
5
5
using System . Text ;
6
+ using System . Text . RegularExpressions ;
6
7
using System . Threading . Tasks ;
7
8
using MwParserFromScratch . Nodes ;
8
9
@@ -32,6 +33,11 @@ public class WikitextParserOptions
32
33
"br" , "wbr" , "hr" , "meta" , "link"
33
34
} ) ;
34
35
36
+ public static readonly IReadOnlyList < string > DefaultImageNamespaceNames = new ReadOnlyCollection < string > ( new [ ]
37
+ {
38
+ "File" , "Image"
39
+ } ) ;
40
+
35
41
internal static readonly HashSet < string > DefaultCaseInsensitiveMagicTemplatesSet =
36
42
new HashSet < string > ( StringComparer . OrdinalIgnoreCase )
37
43
{
@@ -198,6 +204,7 @@ public class WikitextParserOptions
198
204
"DEFAULTCATEGORYSORT" ,
199
205
"PAGESINNS"
200
206
} ;
207
+
201
208
#endregion
202
209
203
210
public static readonly IReadOnlyList < MagicTemplateNameInfo > DefaultMagicTemplateNames
@@ -207,12 +214,20 @@ public static readonly IReadOnlyList<MagicTemplateNameInfo> DefaultMagicTemplate
207
214
. ToArray ( ) ) ;
208
215
209
216
private static readonly HashSet < string > DefaultParserTagsSet = new HashSet < string > ( DefaultParserTags , StringComparer . OrdinalIgnoreCase ) ;
210
- private static readonly HashSet < string > DefaultSelfClosingOnlyTagsSet = new HashSet < string > ( DefaultSelfClosingOnlyTags , StringComparer . OrdinalIgnoreCase ) ;
217
+
218
+ private static readonly HashSet < string > DefaultSelfClosingOnlyTagsSet =
219
+ new HashSet < string > ( DefaultSelfClosingOnlyTags , StringComparer . OrdinalIgnoreCase ) ;
220
+
221
+ private static readonly HashSet < string > DefaultImageNamespaceNamesSet =
222
+ new HashSet < string > ( DefaultImageNamespaceNames , StringComparer . OrdinalIgnoreCase ) ;
223
+
224
+ private static readonly string DefaultImageNamespaceNameRegexp = string . Join ( "|" , DefaultImageNamespaceNames . Select ( Regex . Escape ) ) ;
211
225
212
226
internal static WikitextParserOptions DefaultOptionsCopy = new WikitextParserOptions ( ) . DefensiveCopy ( ) ;
213
227
214
228
private IEnumerable < string > _ParserTags ;
215
229
private IEnumerable < string > _SelfClosingOnlyTags ;
230
+ private IEnumerable < string > _ImageNamespaceNames ;
216
231
private IEnumerable < MagicTemplateNameInfo > _MagicTemplateNames ;
217
232
private bool _AllowEmptyTemplateName ;
218
233
private bool _AllowEmptyWikiLinkTarget ;
@@ -276,7 +291,11 @@ public IEnumerable<MagicTemplateNameInfo> MagicTemplateNames
276
291
public bool AllowEmptyTemplateName
277
292
{
278
293
get { return _AllowEmptyTemplateName ; }
279
- set { _AllowEmptyTemplateName = value ; _DefensiveCopy = null ; }
294
+ set
295
+ {
296
+ _AllowEmptyTemplateName = value ;
297
+ _DefensiveCopy = null ;
298
+ }
280
299
}
281
300
282
301
/// <summary>
@@ -286,7 +305,11 @@ public bool AllowEmptyTemplateName
286
305
public bool AllowEmptyWikiLinkTarget
287
306
{
288
307
get { return _AllowEmptyWikiLinkTarget ; }
289
- set { _AllowEmptyWikiLinkTarget = value ; _DefensiveCopy = null ; }
308
+ set
309
+ {
310
+ _AllowEmptyWikiLinkTarget = value ;
311
+ _DefensiveCopy = null ;
312
+ }
290
313
}
291
314
292
315
/// <summary>
@@ -299,22 +322,49 @@ public bool AllowEmptyWikiLinkTarget
299
322
public bool AllowEmptyExternalLinkTarget
300
323
{
301
324
get { return _AllowEmptyExternalLinkTarget ; }
302
- set { _AllowEmptyExternalLinkTarget = value ; _DefensiveCopy = null ; }
325
+ set
326
+ {
327
+ _AllowEmptyExternalLinkTarget = value ;
328
+ _DefensiveCopy = null ;
329
+ }
303
330
}
304
331
305
332
/// <summary>
306
- /// When parsing for wikilinks, templates, and HTML tags , allows inference of missing close marks.
333
+ /// When parsing for wikilinks and templates , allows inference of missing close marks. Defaults to <c>false</c> .
307
334
/// </summary>
308
335
public bool AllowClosingMarkInference
309
336
{
310
337
get { return _AllowClosingMarkInference ; }
311
- set { _AllowClosingMarkInference = value ; _DefensiveCopy = null ; }
338
+ set
339
+ {
340
+ _AllowClosingMarkInference = value ;
341
+ _DefensiveCopy = null ;
342
+ }
343
+ }
344
+
345
+ /// <summary>
346
+ /// Namespace names that will cause <see cref="WikiLink"/> expression parsed as <see cref="WikiImageLink"/> expression.
347
+ /// </summary>
348
+ /// <value>A list of namespace names. OR <c>null</c> to use the default settings. Name comparison is case-insensitive.</value>
349
+ /// <remarks>Default value is <c>["File", "Image"]</c>.</remarks>
350
+ public IEnumerable < string > ImageNamespaceNames
351
+ {
352
+ get { return _ImageNamespaceNames ; }
353
+ set
354
+ {
355
+ _ImageNamespaceNames = value ;
356
+ _DefensiveCopy = null ;
357
+ }
312
358
}
313
359
314
360
public bool WithLineInfo
315
361
{
316
362
get { return _WithLineInfo ; }
317
- set { _WithLineInfo = value ; _DefensiveCopy = null ; }
363
+ set
364
+ {
365
+ _WithLineInfo = value ;
366
+ _DefensiveCopy = null ;
367
+ }
318
368
}
319
369
320
370
internal ISet < string > ParserTagsSet => ( ISet < string > ) ParserTags ;
@@ -325,6 +375,10 @@ public bool WithLineInfo
325
375
326
376
internal ISet < string > CaseInsensitiveMagicTemplateNamesSet { get ; private set ; }
327
377
378
+ internal ISet < string > ImageNamespaceNamesSet => ( ISet < string > ) ImageNamespaceNames ;
379
+
380
+ internal string ImageNamespaceRegexp { get ; private set ; }
381
+
328
382
internal WikitextParserOptions DefensiveCopy ( )
329
383
{
330
384
// This method should be thread-safe when there are concurrent DefensiveCopy calls.
@@ -334,10 +388,21 @@ internal WikitextParserOptions DefensiveCopy()
334
388
inst . _ParserTags = ParserTags == null || ReferenceEquals ( ParserTags , DefaultParserTags )
335
389
? DefaultParserTagsSet
336
390
: new HashSet < string > ( ParserTags , StringComparer . OrdinalIgnoreCase ) ;
337
- inst . _SelfClosingOnlyTags = SelfClosingOnlyTags == null ||
338
- ReferenceEquals ( SelfClosingOnlyTags , DefaultSelfClosingOnlyTags )
391
+ inst . _SelfClosingOnlyTags = SelfClosingOnlyTags == null || ReferenceEquals ( SelfClosingOnlyTags , DefaultSelfClosingOnlyTags )
339
392
? DefaultSelfClosingOnlyTagsSet
340
393
: new HashSet < string > ( SelfClosingOnlyTags , StringComparer . OrdinalIgnoreCase ) ;
394
+ if ( ImageNamespaceNames == null || ReferenceEquals ( ImageNamespaceNames , DefaultImageNamespaceNames ) )
395
+ {
396
+ inst . _ImageNamespaceNames = DefaultImageNamespaceNamesSet ;
397
+ inst . ImageNamespaceRegexp = DefaultImageNamespaceNameRegexp ;
398
+ }
399
+ else
400
+ {
401
+ var collection = ImageNamespaceNames as ICollection < string > ?? ImageNamespaceNames . ToList ( ) ;
402
+ inst . ImageNamespaceRegexp = string . Join ( "|" , collection . Select ( Regex . Escape ) ) ;
403
+ inst . _ImageNamespaceNames = new HashSet < string > ( collection , StringComparer . OrdinalIgnoreCase ) ;
404
+ }
405
+
341
406
if ( inst . MagicTemplateNames == null || ReferenceEquals ( MagicTemplateNames , DefaultMagicTemplateNames ) )
342
407
{
343
408
inst . CaseSensitiveMagicTemplateNamesSet = DefaultCaseSensitiveMagicTemplatesSet ;
@@ -353,6 +418,7 @@ internal WikitextParserOptions DefensiveCopy()
353
418
else inst . CaseInsensitiveMagicTemplateNamesSet . Add ( tn . Name ) ;
354
419
}
355
420
}
421
+
356
422
inst . _MagicTemplateNames = null ;
357
423
_DefensiveCopy = inst ;
358
424
return inst ;
0 commit comments