NAME Config::JSON::Enhanced - JSON-based config with C/Shell-style comments, verbatim sections and variable substitutions VERSION Version 0.02 SYNOPSIS This module provides subroutine config2perl() for parsing configuration content, from files or strings, based on, what I call, "enhanced JSON" (see section "ENHANCED JSON FORMAT" for more details). Briefly, it is standard JSON which allows: * C-style, C++-style or shell-style comments. * template variables (e.g. <% appdir %>) which are substituted with user-specified data. * verbatim sections which are a sort of here-doc for JSON which may be spanning multiple lines and contained single and double quotes are not required to be escaped. This enhances the readbility of long JSON which may contain, in my case, long shell scripts with lots of quotes and newlines. It has been tested with unicode data (see t/25-config2perl-complex-utf8.t) with success. But who knows ?!?! Here is an example: use Config::JSON::Enhanced qw/config2perl/; my $configdata = 'EOJ'; { "a" : "abc", "b" : { /* this is a comment */ "c" : <%begin-verbatim-section%> This is a multiline string /* all spaces between the start of the line and the first char will be erased. Newlines are escaped and kept. */ with "quoted text" and 'this also' and comments like /* this */ or # this will be retained in the string /* white space from beginning and end will be erased */ <%end-verbatim-section%> , "d" : [1,2,<% tempvar0 %>], "e" : "< % tempvar1 % > user and <%tempvar2%>!" } } EOJ my $perldata = config2perl({ 'string' => $configdata, 'commentstyle' => "C,shell,CPP", 'variable-substitutions' => { # substitutions do not add extra quotes 'tempvar0' => 42, 'tempvar1' => 'hello', 'tempvar2' => 'goodbye', }, }); die "call to config2perl() has failed" unless defined $perldata; # and here is the dump of the perl data structure $perldata { "b" => { "d" => [1,2,42], "c" => "This is a multiline string\n\nwith \"quoted text\" and 'this also'\nand comments like or\n# this\nwill be retained in the string\n", "e" => "hello user and goodbye!" }, "a" => "abc" } EXPORT * config2perl SUBROUTINES config2perl my $ret = config2perl($params); Arguments: * $params Return value: * $ret on success or undef on failure. Given Enhanced JSON content it removes any comments, it replaces all template strings, if any, and then parses what remains as standard JSON into a Perl data structure which is returned. JSON content to-be-parsed can be specified with one of the following keys in the input parameters hashref ($params): * filename : content is read from a file with this name. * filehandle : content is read from a file which has already been opened for reading by the caller. * string : content is contained in this string. Additionally, input parameters can contain the following keys: * commentstyle : specify what comment style(s) to be expected in the input content (if any) as a comma-separated string. These are the values it understands: * C : comments take the form of C-style comments which are exclusively within /* and */. For example * I am a comment */. This is the default comment style if none specified. * CPP : comments can the the form of C++-style comments which are within /* and */ or after // until the end of line. For example /* I am a comment */, // I am a comment to the end of line. * shell : comments can be after # until the end of line. For example, # I am a comment to the end of line. * variable-substitutions : a hashref whose keys are variable names as they occur in the input Enhanced JSON content and their corresponding values should substitute them. Enhanced JSON, can contain template variables in the form <% my-var-1 %>. These must be replaced with data which is supplied to the call of config2perl() under the parameters key variable-substitutions, e.g.:: config2perl({ "variable-substitutions" => { "my-var-1" => 42 }, "string" => '{ "xyz" : "<% my-var-1 %>" }', }); Variable substitution will be performed in keys and values of the input JSON. See section "ENHANCED JSON FORMAT" for details on the format of what I call enhanced JSON. config2perl returns the parsed content as a Perl data structure on success or undef on failure. ENHANCED JSON FORMAT This is JSON with added reasonable, yet completely ad-hoc, enhancements (from my point of view). These enhancements are: * Comments are allowed: * C-style comments take the form of C-style comments which are exclusively within /* and */. For example * I am a comment */ * C++-style comments can the the form of C++-style comments which are within /* and */ or after // until the end of line. For example /* I am a comment */, // I am a comment to the end of line. * shell-style comments can be after # until the end of line. For example, # I am a comment to the end of line. * Template variables support : template variables in the form of <%HOMEDIR%> will be substituded with their actual values specified by the user during parsing. Note that variable names are case sensitive, they can contain spaces, hyphens etc. and the tags enclosing such variables can contain spaces, for example: % < abc-123 xyz %> (the variable name is abc-123 xyz (notice the multiple spaces between 123 and xyz). * Unfortunately, there is not support for ignoring superfluous commas in JSON, in the manner of glorious Perl. Verbatim Sections A Verbaitm Section in this ad-hoc, so-called Enhanced JSON is content enclosed within <%begin-verbatim-section%> and <%end-verbatim-section%> tags. This content may span multiple lines (which when converted to JSON will preserve them by escaping), can contain comments (see the beginning of this section) and can contain template variables to be substituted with user-specified data. Here is an example of enhanced JSON which contains comments, a verbatim section and template variables: my $con = <<'EOC'; { "long bash script" : ["/usr/bin/bash", /* This is a verbatim section */ <%begin-verbatim-section%> pushd . &> /dev/null echo "My 'appdir' is \"<%appdir%>\"" echo "My current dir: " $(echo $PWD) " and bye" popd &> /dev/null <%end-verbatim-section%> ], // this is an example of a template variable "expected result" : "<% expected-res123 %>" } EOC # Which, can be processed thusly: my $res = config2perl({ 'string' => $con, 'commentstyle' => 'C,CPP', 'variable-substitutions' => { 'appdir' => Cwd::abs_path($FindBin::Bin), 'expected-res123' => 42 }, }); die "call to config2perl() has failed" unless defined $res; # the dump of $res is: { "expected result" => 42, "long bash script" => [ "/usr/bin/bash", "pushd . &> /dev/null\necho \"My 'appdir' is \\\"/home/andreas/PROJECTS/CPAN/Config-JSON-Enhanced/t\\\"\"\necho \"My current dir: \" \$(echo \$PWD) \" and bye\"\npopd &> /dev/null" ] }; AUTHOR Andreas Hadjiprocopis, BUGS Please report any bugs or feature requests to bug-config-json-enhanced at rt.cpan.org, or through the web interface at https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Config-JSON-Enhanced. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. SUPPORT You can find documentation for this module with the perldoc command. perldoc Config::JSON::Enhanced You can also look for information at: * RT: CPAN's request tracker (report bugs here) https://rt.cpan.org/NoAuth/Bugs.html?Dist=Config-JSON-Enhanced * CPAN Ratings https://cpanratings.perl.org/d/Config-JSON-Enhanced * Search CPAN https://metacpan.org/release/Config-JSON-Enhanced ACKNOWLEDGEMENTS LICENSE AND COPYRIGHT This software is Copyright (c) 2023 by Andreas Hadjiprocopis. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible)