File Coverage

lib/Wiki/JSON.pm
Criterion Covered Total %
statement 33 34 97.0
branch 1 2 50.0
condition 8 10 80.0
subroutine 11 12 91.6
pod 2 2 100.0
total 55 60 91.6


line stmt bran cond sub pod time code
1             package Wiki::JSON;
2              
3 8     8   3493859 use v5.16.3;
  8         32  
4              
5 8     8   48 use strict;
  8         12  
  8         319  
6 8     8   112 use warnings;
  8         16  
  8         525  
7              
8 8     8   5244 use Moo;
  8         70380  
  8         43  
9 8     8   14838 use Data::Dumper;
  8         16  
  8         487  
10 8     8   4422 use Const::Fast;
  8         24279  
  8         51  
11 8     8   6433 use Wiki::JSON::Parser;
  8         27  
  8         395  
12 8     8   5824 use Wiki::JSON::HTML;
  8         35  
  8         2896  
13              
14             our $VERSION = "0.0.32";
15              
16             const my $MAX_HX_SIZE => 6;
17             const my $EXTRA_CHARACTERS_BOLD_AND_ITALIC_WHEN_ITALIC => 3;
18             const my $LIST_ELEMENT_INTERRUPT_NUMBER_OF_CHARACTERS_TO_IGNORE => 3;
19             const my $MINIMUM_LINK_SEARCH => 3;
20             const my $MINIMUM_TEMPLATE_SEARCH => 3;
21             const my $LIST_ELEMENT_DELIMITER => "\n* ";
22              
23             sub parse {
24 123 50   123 1 180946 if (@_ < 2) {
25 0         0 die 'Parse arguments: <$self> <$wiki_text> [$options]';
26             }
27 123         300 my ( $self, $wiki_text, $options ) = @_;
28 123   100     502 $options //= {};
29 123         3863 return Wiki::JSON::Parser->new->parse($wiki_text, $options);
30             }
31              
32             sub pre_html {
33 52     52 1 94684 my ($self, $wiki_text, $template_callbacks) = @_;
34 52   100     291 $template_callbacks //= {};
35 52   66 2   388 $template_callbacks->{is_inline} //= sub { return 1; };
  2         2  
36 52   66 0   274 $template_callbacks->{generate_elements} //= sub {};
37 52         1750 return Wiki::JSON::HTML->new->pre_html_json($wiki_text, $template_callbacks);
38             }
39             1;
40              
41             =encoding utf8
42              
43             =head1 NAME
44              
45             Wiki::JSON - Parse wiki-like articles to a data-structure transformable to JSON.
46              
47             =head1 SYNOPSIS
48              
49             use Wiki::JSON;
50              
51             my $structure = Wiki::JSON->new->parse(<<'EOF');
52             = This is a wiki title =
53             '''This is bold'''
54             ''This is italic''
55             '''''This is bold and italic'''''
56             == This is a smaller title, the user can use no more than 6 equal signs ==
57             ''This is printed without expanding the special characters
58             * This
59             * Is
60             * A
61             * Bullet
62             * Point
63             * List
64             {{foo|Templates are generated|with their arguments}}
65             {{stub|This is under heavy development}}
66             The parser has some quirks == This will generate a title ==
67             ''' == '' Unterminated syntaxes will still be parsed until the end of file
68             This is a link to a wiki article: [[Cool Article]]
69             This is a link to a wiki article with an alias: [[Cool Article|cool article]]
70             This is a link to a URL with an alias: [[https://example.com/cool-source.html|cool article]]
71             This is a link to a Image [[File:https:/example.com/img.png|50x50px|frame|This is a caption]]
72             EOF
73              
74             =head1 DESCRIPTION
75              
76             A parser for a subset of a mediawiki-like syntax, quirks include some
77             supposedly inline elements are parsed multi-line like headers, templates*,
78             italic and bolds.
79              
80             Lists are only one level and not everything in mediawiki is supported by the
81             moment.
82              
83             =head2 INSTALLING
84              
85             cpanm https://github.com/sergiotarxz/Perl-Wiki-JSON.git
86              
87             =head2 USING AS A COMMAND
88              
89             wiki2json file.wiki > output.json
90              
91             =head1 INSTANCE METHODS
92              
93             =head2 new
94              
95             my $wiki_parser = Wiki::JSON->new;
96              
97             =head1 SUBROUTINES/METHODS
98              
99             =head2 parse
100              
101             my $structure = $wiki_parser->parse($wiki_string);
102              
103             Parses the wiki format into a serializable to JSON or YAML Perl data structure.
104              
105             =head2 pre_html
106              
107             my $template_callbacks = {
108             generate_elements => sub {
109             my ( $template, $options, $parse_sub, $open_html_element_sub,
110             $close_html_element_sub )
111             = @_;
112             my @dom;
113             if ( $element->{template_name} eq 'stub' ) {
114             push @dom,
115             $open_html_element_sub->( 'span', 0, { style => 'color: red;' } );
116             push @dom, @{ $element->{output} };
117             push @dom, $close_html_element_sub->('span');
118             }
119             return \@dom;
120             },
121             is_inline => sub {
122             my ($template) = @_;
123             if ($template->{template_name} eq 'stub') {
124             return 1;
125             }
126             if ($template->{template_name} eq 'videoplayer') {
127             return 0;
128             }
129             }
130             };
131              
132             my $structure = $wiki_parser->pre_html($wiki_string, $template_callbacks);
133              
134             Retrieves an ArrayRef containing just HashRefs without nesting describing how HTML tags should be open and closed for a wiki text.
135              
136             =head3 template_callbacks
137              
138             An optional hashref containing any or both of this two keys pointing to subrefs
139              
140             =head1 RETURN FROM METHODS
141              
142             =head2 parse
143              
144             The return is an ArrayRef in which each element is either a string or a HashRef.
145              
146             HashRefs can be classified by the key type which can be one of these:
147              
148             =head3 hx
149              
150             A header to be printed as h1..h6 in HTML, has the following fields:
151              
152             =over 4
153              
154             =item hx_level
155              
156             A number from 1 to 6 defining the header level.
157              
158             =item output
159              
160             An ArrayRef defined by the return from parse.
161              
162             =back
163              
164             =head3 template
165              
166             A template thought for developer defined expansions of how some data shoudl be represented.
167              
168             =over 4
169              
170             =item template_name
171              
172             The name of the template.
173              
174             =item output
175              
176             An ArrayRef defined by the return from parse.
177              
178             =back
179              
180             =head3 bold
181              
182             A set of elements that must be represented as bold text.
183              
184             =over 4
185              
186             =item output
187              
188             An ArrayRef defined by the return from parse.
189              
190             =back
191              
192             =head3 italic
193              
194             A set of elements that must be represented as italic text.
195              
196             =over 4
197              
198             =item output
199              
200             An ArrayRef defined by the return from parse.
201              
202             =back
203              
204             =head3 bold_and_italic
205              
206             A set of elements that must be represented as bold and italic text.
207              
208             =over 4
209              
210             =item output
211              
212             An ArrayRef defined by the return from parse.
213              
214             =back
215              
216             =head3 unordered_list
217              
218             A bullet point list.
219              
220             =over 4
221              
222             =item output
223              
224             A ArrayRef of HashRefs from the type list_element.
225              
226             =back
227              
228             =head3 list_element
229              
230             An element in a list, this element must not appear outside of the output element of a list.
231              
232             =over 4
233              
234             =item output
235              
236             An ArrayRef defined by the return from parse.
237              
238             =back
239              
240             =head3 link
241              
242             An URL or a link to other Wiki Article.
243              
244             =over 4
245              
246             =item link
247              
248             The String containing the URL or link to other Wiki Article.
249              
250             =item title
251              
252             The text that should be used while showing this URL to point the user where it is going to be directed.
253              
254             =back
255              
256             =head3 image
257              
258             An Image, PDF, or Video.
259              
260             =over 4
261              
262             =item link
263              
264             Where to find the File.
265              
266             =item caption
267              
268             What to show the user if the image is requested to explain to the user what he is seeing.
269              
270             =item options
271              
272             =back
273              
274             Undocumented by the moment.
275              
276             =head1 DEPENDENCIES
277              
278             The module will pull all the dependencies it needs on install, the minimum supported Perl is v5.16.3, although latest versions are mostly tested for 5.38.2
279              
280             =head1 CONFIGURATION AND ENVIRONMENT
281              
282             If your OS Perl is too old perlbrew can be used instead.
283              
284             =head1 BUGS AND LIMITATIONS
285              
286             The author thinks it is possible the parser hanging forever, use it in
287             a subprocess the program can kill if it takes too long.
288              
289             The developer can use fork, waitpid, pipe, and non-blocking IO for that.
290              
291             =head1 DIAGNOSTICS
292              
293             If a string halting forever this module is found, send it to me in the Github issue tracker.
294              
295             =head1 LICENSE AND COPYRIGHT
296              
297             Copyright ©Sergiotarxz (2025)
298              
299             Licensed under the The GNU General Public License, Version 3, June 2007 L.
300              
301             You can use this software under the terms of the GPLv3 license or a new later
302             version provided by the FSF or the GNU project.
303              
304             =head1 INCOMPATIBILITIES
305              
306             None known.
307              
308             =head1 VERSION
309              
310             0.0.x
311              
312             =head1 AUTHOR
313              
314             Sergio Iglesias
315              
316             =head1 SEE ALSO
317              
318             Look what is supported and how in the tests: L
319              
320             =cut