File Coverage

blib/lib/Config/JSON/Enhanced.pm
Criterion Covered Total %
statement 120 135 88.8
branch 43 56 76.7
condition 29 50 58.0
subroutine 10 10 100.0
pod 1 1 100.0
total 203 252 80.5


line stmt bran cond sub pod time code
1             package Config::JSON::Enhanced;
2              
3 15     15   3214277 use 5.010;
  15         64  
4 15     15   90 use strict;
  15         35  
  15         2023  
5 15     15   96 use warnings;
  15         32  
  15         1243  
6              
7             our $VERSION = '0.10';
8              
9 15     15   115 use strict;
  15         67  
  15         417  
10 15     15   82 use warnings;
  15         28  
  15         716  
11              
12             # which loads JSON::XS with a purel-perl JSON fallback
13 15     15   10639 use JSON;
  15         143456  
  15         103  
14              
15 15     15   8730 use Data::Roundtrip qw/json2perl perl2dump no-unicode-escape-permanently/;
  15         1419251  
  15         189  
16              
17 15     15   2184 use Exporter; # we have our own import() don't import it
  15         76  
  15         42275  
18             our @ISA = qw(Exporter);
19             our @EXPORT = qw/
20             config2perl
21             /;
22              
23             # Convert enhanced JSON string into a Perl data structure.
24             # The input parameters hashref:
25             # * specify where is the content to be parsed via:
26             # 'filename',
27             # 'filehandle', or,
28             # 'string'
29             # * optional 'commentstyle' is a string of comma separated
30             # commentstyles (valid styles are C, CPP, shell)
31             # * optional 'variable-substitutions' is a hashref with
32             # keys as template variable names to be substutited
33             # inside the content with their corresponding values.
34             # For example {'xx' => 'hello'} will substitute
35             # <% xx %> with hello
36             # * optional 'remove-comments-in-strings' to remove comments from JSON strings
37             # (both keys and values), default is to KEEP anything inside a string
38             # even if it looks like comments we are supposed to remove (because string
39             # can be a bash script, for example).
40             # * optional 'debug' for setting verbosity, default is zero.
41             #
42             # It returns the created Perl data structure or undef on failure.
43             sub config2perl {
44 611   50 611 1 6832550 my $params = shift // {};
45              
46 611         1483 my $contents;
47 611 100 66     7220 if( exists($params->{'filename'}) && defined(my $infile=$params->{'filename'}) ){
    100 66        
    50 33        
48 19         43 my $fh;
49 19 50   7   2113 if( ! open $fh, '<:encoding(UTF-8)', $infile ){ warn __PACKAGE__.'::configfile2perl()'." (line ".__LINE__.") : error, failed to open file '$infile' for reading, $!"; return undef }
  0         0  
  0         0  
  7         8944  
  7         133  
  7         40  
50 19         10537 { local $/ = undef; $contents = <$fh> }; close $fh;
  19         110  
  19         692  
  19         754  
51             } elsif( exists($params->{'filehandle'}) && defined(my $fh=$params->{'filehandle'}) ){
52 11         25 { local $/ = undef; $contents = <$fh> }
  11         70  
  11         1303  
53             # we are not closing the filehandle, it is caller-specified, so caller responsibility
54             } elsif( exists($params->{'string'}) && defined($params->{'string'}) ){
55 581         1457 $contents = $params->{'string'};
56             }
57 611 50       1742 if( ! defined $contents ){ warn __PACKAGE__.'::configfile2perl()'." (line ".__LINE__.") : error, one of 'filename', 'filehandle' or 'string' must be specified in the parameters hash as the source of the configuration contents."; return undef }
  0         0  
  0         0  
58              
59             my $debug = exists($params->{'debug'}) && defined($params->{'debug'})
60 611 50 33     2456 ? $params->{'debug'} : 0
61             ;
62              
63             my $commentstyle = exists($params->{'commentstyle'}) && defined($params->{'commentstyle'})
64 611 50 33     3778 ? $params->{'commentstyle'} : 'C'
65             ;
66              
67 611         1371 my ($tvop, $tvcl);
68 611 100 66     1982 if( exists($params->{'tags'}) && defined($params->{'tags'}) ){
69 22 100       79 if( ref($params->{'tags'}) ne 'ARRAY' ){ warn __PACKAGE__.'::configfile2perl()'." (line ".__LINE__.") : error, input parameter 'tags' must be an ARRAYref of exactly 2 items and not a '".ref($params->{'tags'})."'."; return undef }
  1         18  
  1         17  
70 21 50       37 if( scalar(@{ $params->{'tags'} }) != 2 ){ warn __PACKAGE__.'::configfile2perl()'." (line ".__LINE__.") : error, input parameter 'tags' must be an ARRAYref of exactly 2 items and not ".scalar(@{ $params->{'tags'} })."."; return undef }
  21         76  
  0         0  
  0         0  
  0         0  
71 21         42 ($tvop, $tvcl) = @{ $params->{'tags'} };
  21         77  
72 589         1084 } else { $tvop = '<%'; $tvcl = '%>' }
  589         1318  
73              
74             # check that the tags for verbatim sections is not the same as comments
75 610         7169 while( $commentstyle =~ /\bcustom\((.+?)\)\((.*?)\)/ig ){
76 1971         4183 my $coop = $1; my $cocl = $2;
  1971         3280  
77 1971 50       3988 if( $debug > 0 ){ warn __PACKAGE__.'::configfile2perl()'." (line ".__LINE__.") : checking comment tags '${coop}' and '${cocl}' not to be the same or contain verbatim/variables tags '${tvop}' and '${tvcl}' ..." }
  0         0  
78 1971 50 100     10512 if( ($tvop eq $coop) || ($tvop eq $cocl)
      66        
      66        
79             || ($tvcl eq $coop) || ($tvcl eq $cocl)
80 3         145 ){ warn __PACKAGE__.'::configfile2perl()'." (line ".__LINE__.") : error, there is a clash (exact match) with verbatim/variable tags ('${tvop}' and '${tvcl}') and comment tags ('${coop}' and '${cocl}')."; return undef }
  3         24  
81             # also check if one contains the other
82 1968 100 66     47560 if( ($tvop =~ /\Q${coop}\E/) || ($tvop =~ /\Q${cocl}\E/)
      66        
      66        
83             || ($tvcl =~ /\Q${coop}\E/) || ($tvcl =~ /\Q${cocl}\E/)
84 3         76 ){ warn __PACKAGE__.'::configfile2perl()'." (line ".__LINE__.") : error, there is a clash (one contains the other) with verbatim/variable tags ('${tvop}' and '${tvcl}') and comment tags ('${coop}' and '${cocl}')."; return undef }
  3         22  
85 1965 100 33     22579 if( ($coop =~ /\Q${tvop}\E/) || ($coop =~ /\Q${tvcl}\E/)
      33        
      66        
86             || ($cocl =~ /\Q${tvop}\E/) || ($cocl =~ /\Q${tvcl}\E/)
87 1         24 ){ warn __PACKAGE__.'::configfile2perl()'." (line ".__LINE__.") : error, there is a clash (one contains the other) with verbatim/variable tags ('${tvop}' and '${tvcl}') and comment tags ('${coop}' and '${cocl}')."; return undef }
  1         10  
88             }
89              
90             my $tsubs = exists($params->{'variable-substitutions'})
91 603 100       1867 ? $params->{'variable-substitutions'} : undef
92             ;
93              
94             # remove comments inside strings? default is NO, keep comments if inside strings
95             # because they may not be our comments (e.g. string contains a bash script)
96             my $remove_comments_in_strings = exists($params->{'remove-comments-in-strings'}) && defined($params->{'remove-comments-in-strings'})
97 603 100 66     3298 ? $params->{'remove-comments-in-strings'} : 0
98             ;
99              
100             # firstly, substitute templated variables if any
101             # with the user-specified data.
102             # This includes ANYTHNING in the input enhanced JSON including
103             # verbatim sections, keys, values, etc.
104             # The opening and closing tags of vars are user-specified
105             # and are NOT allowed to contain spaces in between
106             # (e.g. '< %' will not be matched if '<%' was specified)
107 603         1962 for my $ak (keys %$tsubs){
108 35         97 my $av = $tsubs->{$ak};
109 35 50       3648 if( ($ak =~ /(?:\Q${tvop}\E)|(?:\Q${tvcl}\E)/) ){ warn __PACKAGE__.'::config2perl()'." (line ".__LINE__.") : error, variable names can not contain the specified opening ($tvop) and/or closing ($tvcl) variable name tags."; return undef }
  0         0  
  0         0  
110 35         2106 $contents =~ s!\Q${tvop}\E\s*${ak}\s*\Q${tvcl}\E!${av}!g;
111             }
112             # this is JUST a warning:
113             # we can not be sure if this <% xyz %> is part of the content or a forgotten templated variable
114 603 50       5279 if( $contents =~ /\Q${tvop}\E\s*!(:?(:?begin-verbatim-section)|(:?end-verbatim-section))\s*\Q${tvcl}\E/ ){ print STDERR "--begin content:\n".$contents."\n--end content.\n".__PACKAGE__.'::config2perl()'." (line ".__LINE__.") : warning, there may still be remains of templated variables in the specified content (tags used: '${tvop}' and '${tvcl} -- ignore the enclosing single quotes), see above what remained after all template variables substitutions were done." }
  0         0  
115             # this does not print contents in its warning message
116             # in case Test::More gets confused:
117             #if( $contents =~ /\Q${tvop}\E\s*!(:?(:?begin-verbatim-section)|(:?end-verbatim-section))\s*\Q${tvcl}\E/ ){ print STDERR __PACKAGE__.'::config2perl()'." (line ".__LINE__.") : warning, there may still be remains of templated variables in the specified content (tags used: '${tvop}' and '${tvcl}' -- ignore the enclosing single quotes), see above what remained after all template variables substitutions were done." }
118              
119             # secondly, remove the VERBATIM multiline sections and transform them.
120             # Comments inside the verbatim section will NOT BE touched.
121             # The only thing touched was the templated variables earlier
122             # it substitutes each verbatim section with a code
123             # then does the comments and then replaces the code with the verbatim section at the very end
124 603         955 my @verbs;
125 603         960 my $idx = 0;
126 603         5909 while( $contents =~ s/\Q${tvop}\E\s*begin-verbatim-section\s*\Q${tvcl}\E(.*?)\Q${tvop}\E\s*end-verbatim-section\s*\Q${tvcl}\E/"___my___verbatim-section-${idx}___my___"/s ){
127 72         300 my $vc = $1;
128             # remove from start and end of whole string newlines+spaces
129 72         361 $vc =~ s/^[\n\t ]+//;
130 72         1258 $vc =~ s/[\n\t ]+$//;
131             # remove newlines followed by optional spaces at the beginning of each line
132 72         740 $vc =~ s/\n+[ \t]*/\\n/gs;
133             # escape all double quotes (naively)
134             # but not those which are already escaped (naively)
135 72         364 $vc =~ s/\\"/<%__abcQQxyz__%>/g;
136 72         473 $vc =~ s/"/\\"/g;
137 72         339 $vc =~ s/<%__abcQQxyz__%>/\\\\\\"/g;
138             # so echo "aa \"xx\""
139             # becomes echo \"aa \\\"xx\\\"\"
140 72         173 push @verbs, $vc;
141 72         904 $idx++;
142             }
143              
144             # thirdly, replace all JSON strings (keys or values) with indexed markers
145             # so that their contained comments
146             # to be left intact after the comment substitution which will
147             # be done later on.
148 603         997 my @stringsubs;
149 603 100       1538 if( $remove_comments_in_strings == 0 ){
150 595         3526 $idx = 0;
151 595         7436 while( $contents =~ s/(?
152 4969         10108 push @stringsubs, $1;
153 4969         30884 $idx++;
154             }
155             }
156              
157             # fourthly, remove comments: 'shell' and/or 'C' and/or 'CPP'
158             # and/or multiple instances of 'custom()()'
159 603         1177 my $tc = $commentstyle;
160 603 100       3542 if( $tc =~ s/\bC\b//i ){
161 419         3126 $contents =~ s/\/\*(?:(?!\*\/).)*\*\/\n?//sg;
162             }
163 603 100       3130 if( $tc =~ s/\bCPP\b//i ){
164 421         986 $contents =~ s/\/\*(?:(?!\*\/).)*\*\/\n?//sg;
165 421         2082 $contents =~ s!//.*$!!mg;
166             }
167 603 100       2689 if( $tc =~ s/\bshell\b//i ){
168             # TODO: we must also remove the newline left!
169 423         2047 $contents =~ s/#.*$//mg;
170             }
171              
172             # specify a custom comment style with required opening string
173             # and an optional closing
174             # e.g. custom(required)(optional), custom(<<)(>>) or custom(REM)()
175 603         3188 while( $tc =~ s/\bcustom\((.+?)\)\((.*?)\)//i ){
176             # mulitple custom(opening)(closing) commentstyle are allowed
177             # 'opening' and 'closing' can be any string
178             # And need not be balanced e.g. <<< and >>
179             # And can be the same e.g. <<< and <<<
180 1964         4548 my $coop = $1; my $cocl = $2;
  1964         3122  
181 1964 100       5116 if( $cocl =~ /^\s*$/ ){
182             # TODO: we must also remove the newline left!
183 411         3873 $contents =~ s/\Q${coop}\E.*$//mg;
184             } else {
185 1553         80055 $contents =~ s/\Q${coop}\E(?:(?!\Q${cocl}\E\s*).)*\Q${cocl}\E\s*\n?//sg;
186             }
187             }
188 603 50       1989 if( $tc =~ /[a-z]/i ){ warn __PACKAGE__.'::config2perl()'." (line ".__LINE__.") : error, comments style '${commentstyle}' was not understood, this is what was left after parsing it: '${tc}'."; return undef }
  0         0  
  0         0  
189              
190             # this is JUST a warning:
191             # because we can not be sure if this <% xyz %>
192             # is part of the content or a forgotten templated variable
193             # However, the json2perl below will return undef on any errors
194             # turn it into an error?
195 603 50       4216 if( $contents =~ /\Q${tvop}\E.+?(?:begin|end)-verbatim-section\s*\Q${tvcl}\E/ ){ warn "--begin content:\n".$contents."\n--end content.\n".__PACKAGE__.'::config2perl()'." (line ".__LINE__.") : warning, there may still be remains of templated variables in the specified content, see above what remained after all verbatime sections were removed." }
  0         0  
196              
197 603 100       1645 if( $remove_comments_in_strings == 0 ){
198 595         1053 $idx = 0;
199 595         1783 for($idx=scalar(@stringsubs);$idx-->0;){
200 4969         8738 my $astring = $stringsubs[$idx];
201 4969         60974 $contents =~ s/___my___EJSTRING\($idx\)___my___/"${astring}"/g
202             }
203             }
204              
205             # and now substitute the transformed verbatim sections back
206 603         3146 for($idx=scalar(@verbs);$idx-->0;){
207 72         1052 $contents =~ s/___my___verbatim-section-${idx}___my___/$verbs[$idx]/g;
208             }
209              
210 603 50       1347 if( $debug > 0 ){ warn $contents."\n\n".__PACKAGE__.'::config2perl()'." (line ".__LINE__.") : produced above standard JSON from enhanced JSON content." }
  0         0  
211              
212             # here $contents must contain standard JSON which we parse:
213 603         3189 my $inhash = json2perl($contents);
214 603 100       22248 if( ! defined $inhash ){ warn $contents."\n\n".__PACKAGE__.'::config2perl()'." (line ".__LINE__.") : error, call to ".'Data::Roundtrip::json2perl()'." has failed for above json string and comments style '${commentstyle}'."; return undef }
  1         40  
  1         11  
215 602         3630 return $inhash
216             }
217              
218             =pod
219              
220             =head1 NAME
221              
222             Config::JSON::Enhanced - JSON-based config with C/Shell-style comments, verbatim sections and variable substitutions
223              
224             =head1 VERSION
225              
226             Version 0.10
227              
228             =head1 SYNOPSIS
229              
230             This module provides subroutine C for parsing configuration content,
231             from files or strings, based on, what I call, "enhanced JSON" (see section
232             L for more details). Briefly, it is standard JSON which allows:
233              
234             =over 2
235              
236             =item * C-style, C-style, C-style or custom comments.
237              
238             =item * Template-style variables (e.g. C% appdir %E>)
239             which are substituted with user-specified data during parsing.
240              
241             =item * Verbatim sections which are a sort of here-doc for JSON,
242             allowing strings to span multiple
243             lines, to contain single and double quotes unescaped,
244             to contain template-style variables.
245              
246             =back
247              
248             This module was created because I needed to include
249             long shell scripts containing lots of quotes and newlines,
250             in a configuration file which started as JSON.
251              
252             The process is simple: so-called "enhanced JSON" is parsed
253             by L. Comments are removed, variables are
254             substituted, verbatim sections become one line again
255             and standard JSON is created. This is parsed with
256             L (via L) to
257             produce a Perl data structure which is returned.
258              
259             It has been tested with unicode data
260             (see C)
261             with success. But who knows ?!?!
262              
263             Here is an example:
264              
265             use Config::JSON::Enhanced;
266              
267             # simple "enhanced" JSON with comments in 3 styles: C,shell,CPP
268             my $configdata = <<'EOJ';
269             {
270             /* 'a' is ... */
271             "a" : "abc",
272             # b is ...
273             "b" : [1,2,3],
274             "c" : 12 // c is ...
275             }
276             EOJ
277             my $perldata = config2perl({
278             'string' => $configdata,
279             'commentstyle' => "C,shell,CPP",
280             });
281             die "call to config2perl() has failed" unless defined $perldata;
282             # the standard JSON:
283             # {"a" : "abc","b" : [1,2,3], "c" : 12}
284              
285              
286             # this "enhanced" JSON demonstrates the use of variables
287             # which will be substituted during the transformation to
288             # standard JSON with user-specified data.
289             # Notice that the opening and closing tags enclosing variable
290             # names can be customised using the 'tags' input parameter,
291             # so as to avoid clashes with content in the JSON.
292             my $configdata = <<'EOJ';
293             {
294             "d" : [1,2,<% tempvar0 %>],
295             "configfile" : "<%SCRIPTDIR%>/config/myapp.conf",
296             "username" : "<% username %>"
297             }
298             }
299             EOJ
300             my $perldata = config2perl({
301             'string' => $configdata,
302             'commentstyle' => "C,shell,CPP",
303             # optionally customise the tags enclosing the variables
304             # when you want to avoid clashes with other strings in JSON
305             #'tags' => ['<%', '%>'], # <<< these are the default values
306             # user-specified data to replace the variables in
307             # the "enhanced" JSON above:
308             'variable-substitutions' => {
309             'tempvar0' => 42,
310             'username' => getlogin(),
311             'SCRIPTDIR' => $FindBin::Bin,
312             },
313             });
314             die "call to config2perl() has failed" unless defined $perldata;
315             # the standard JSON
316             # (notice how all variables in <%...%> are now replaced):
317             # {"d" : [1,2,42],
318             # "username" : "yossarian",
319             # "configfile" : "/home/yossarian/B52/config/myapp.conf"
320             # }
321              
322              
323             # this "enhanced" JSON demonstrates "verbatim sections"
324             # the puprose of which is to make more readable JSON strings
325             # by allowing them to span over multiple lines.
326             # There is also no need for escaping double quotes.
327             # template variables (like above) will be substituted
328             # There will be no comments removal from the verbatim sections.
329             my $configdata = <<'EOJ';
330             {
331             "a" : <%begin-verbatim-section%>
332             This is a multiline
333             string
334             "quoted text" and 'quoted like this also'
335             will be retained in the string escaped.
336             White space from beginning and end will be chomped.
337            
338             <%end-verbatim-section%>
339             ,
340             "b" = 123
341             }
342             EOJ
343             my $perldata = config2perl({
344             'string' => $configdata,
345             'commentstyle' => "C,shell,CPP",
346             });
347             die "call to config2perl() has failed" unless defined $perldata;
348             # the standard JSON (notice that "a" value is in a single line,
349             # here printed broken for readability):
350             # {"a" :
351             # "This is a multiline\nstring\n\"quoted text\" and 'quoted like
352             # this also'\nwill be retained in the string escaped.\nComments
353             # will not be removed.\nWhite space from
354             # beginning and end will be chomped.",
355             # "b" : 123
356             # };
357              
358              
359             =head1 EXPORT
360              
361             =over 4
362              
363             =item * C is exported by default.
364              
365             =back
366              
367              
368             =head1 SUBROUTINES
369              
370             =head2 C
371              
372             my $ret = config2perl($params);
373             die unless defined $ret;
374              
375             Arguments:
376              
377             =over 4
378              
379             =item * C<$params> : a hashref of input parameters.
380              
381             =back
382              
383             Return value:
384              
385             =over 4
386              
387             =item * the parsed content as a Perl data structure
388             on success or C on failure.
389              
390             =back
391              
392             Given input content in L, this sub removes comments
393             (as per preferences via input parameters),
394             replaces all template variables, if any,
395             compacts L, if any, into a single-line
396             string and then parses
397             what remains as standard JSON into a Perl data structure
398             which is returned to caller. JSON parsing is done with
399             L, which uses L.
400              
401             Comments outside of JSON fields will always be removed,
402             otherwise JSON can not be parsed.
403              
404             Comments inside of JSON fields, keys, values, strings etc.
405             will not be removed unless input parameter C
406             is set to 1 by the caller.
407              
408             Comments (or what looks like comments with the current input parameters)
409             inside L will never be removed.
410              
411             The input content to-be-parsed can be specified
412             with one of the following input parameters (entries in the
413             C<$params>):
414              
415             =over 4
416              
417             =item * C : content is read from a file with this name.
418              
419             =item * C : content is read from a file which has already
420             been opened for reading by the caller.
421              
422             =item * C : content is contained in this string.
423              
424             =back
425              
426             Additionally, input parameters can contain the following keys:
427              
428             =over 4
429              
430             =item * C : specify what comment style(s) to be expected
431             in the input content (if any) as a B. For example
432             C<'C,CPP,shell,custom(EE)(EE),custom(REM)()'>.
433             These are the values it understands:
434              
435             =over 2
436              
437             =item * C : comments take the form of C-style comments which
438             are exclusively within C. For example C<* I am a comment */>.
439             This is the B if none specified.
440              
441             =item * C : comments can the the form of C++-style comments
442             which are within C or after C until the end of line.
443             For example C, C.
444              
445             =item * C : comments can be after C<#> until the end of line.
446             For example, C<# I am a comment to the end of line>.
447              
448             =item * C : comments are enclosed (or preceded) by custom,
449             user-specified tags. The form is C.
450             C is required. C is optional meaning that
451             the comment extends to the end of line (just like C comments).
452             For example CE)(EE)> or
453             C or C or CEEE)(EE)>.
454             C and C do not need to be of
455             the same character length as it is
456             obvious from the previous example. A word of warning:
457             the regex for identifying comments (and variables and verbatim sections)
458             has the custom tags escaped for special regex characters
459             (with the C<\Q ... \E> construct). So you are pretty safe in using
460             any character. Please report weird behaviour.
461              
462             B : either opening or closing comment tags must not
463             be the same as opening or closing variables / verbatim section tags.
464              
465             =back
466              
467             =item * C : a hashref whose keys are
468             variable names as they occur in the input I content
469             and their corresponding values should substitute them. I,
470             can contain template variables in the form C% my-var-1 %E>. These
471             must be replaced with data which is supplied to the call of C
472             under the parameters key C, for example:
473            
474             config2perl({
475             "variable-substitutions" => {
476             "my-var-1" => 42,
477             "SCRIPTDIR" => "/home/abc",
478             },
479             "string" => '{"a":"<% my-var-1 %>", "b":"<% SCRIPTDIR %>/app.conf"}',
480             });
481              
482             Variable substitution will be performed in both
483             keys and values of the input JSON, including L.
484              
485             =item * C : by default no attempt
486             to remove what-looks-like-comments from JSON strings
487             (both keys and values). However, if this flag is set to
488             C<1> anything that looks like comments (as per the 'C'
489             parameter) will be removed from inside all JSON strings
490             (keys or values) unless they were part of verbatim section.
491              
492             This does not apply for the content verbatim sections.
493             What looks like comments to us, inside verbatim sections
494             will be left intact.
495              
496             For example consider the JSON string C<"hello/*a comment*/">
497             (which can be a key or a value). If C is
498             set to 1, then the JSON string will become C. If set to
499             0 (which is the default) it will be unchanged.
500              
501             =item * C : specify the opening and closing tags for template
502             variables and verbatim section as an ARRAYref of exactly 2 items (the
503             opening and the closing tags). By default the opening tag is C%>
504             and the closing tag is C<%E>. A word of warning:
505             the regex for identifying variables and verbatim sections (and comments)
506             has the custom tags escaped for special regex characters
507             (with the C<\Q ... \E> construct). So you are pretty safe in using
508             any character. Please report weird behaviour.
509              
510             If you set C [ '[::', '::]' ]>
511             then your template variables should look like this: C<{:: var1 ::]> and
512             verbatim sections like this: C<[:: begin-verbatim-section ::]>.
513              
514             =item * C : set this to a positive integer to increase verbosity
515             and dump debugging messages. Default is zero for zero verbosity.
516              
517             =back
518              
519             See section L for details on the format
520             of B I.
521              
522             C returns the parsed content as a Perl data structure
523             on success or C on failure.
524              
525              
526             =head1 ENHANCED JSON FORMAT
527              
528             This is JSON with added reasonable, yet completely ad-hoc, enhancements
529             (from my point of view).
530              
531             These enhancements are:
532              
533             =over 4
534              
535             =item * B:
536              
537             =over 2
538              
539             =item * C-style comments take the form of C-style comments which
540             are exclusively within C. For example C<* I am a comment */>
541              
542             =item * C-style comments can the the form of C++-style comments
543             which are within C or after C until the end of line.
544             For example C, C
545              
546             =item * C-style comments can be after C<#> until the end of line.
547             For example, C<# I am a comment to the end of line.>
548              
549             =item * comments with C, user-specified, opening and
550             optional closing tags
551             which allows fine-tuning the process of deciding on something being a
552             comment.
553              
554             =back
555              
556             =item * B