Graph::Easy::Marpa - A Marpa-based parser for Graph::Easy::Marpa-style Graphviz files
#!/usr/bin/env perl use strict; use warnings; use Graph::Easy::Marpa; use Getopt::Long; use Pod::Usage; # ----------------------------------------------- my($option_parser) = Getopt::Long::Parser -> new(); my(%option); if ($option_parser -> getoptions ( \%option, 'description=s', 'dot_input_file=s', 'format=s', 'help', 'input_file=s', 'logger=s', 'maxlevel=s', 'minlevel=s', 'output_file=s', 'rankdir=s', 'report_tokens=i', 'token_file=s', ) ) { pod2usage(1) if ($option{'help'}); # Return 0 for success and 1 for failure. exit Graph::Easy::Marpa -> new(%option) -> run; } else { pod2usage(2); }
This is shipped as scripts/parse.pl, although the shipped version has built-in help.
scripts/parse.pl
Run 'perl -Ilib scripts/parse.pl -h' for sample demos.
Unpack the distro and copy html/*.html and html/*.svg to your web server's doc root directory.
Then, point your browser at 127.0.0.1/index.html.
Or, hit http://savage.net.au/Perl-modules/html/graph.easy.marpa/index.html.
The current module, which documents the set of modules.
It uses Graph::Easy::Marpa::Parser and Graph::Easy::Marpa::Renderer::GraphViz2, and 'dot', to render a Graph::Easy::Marpa-syntax file into a (by default) *.svg file.
Graph::Easy::Marpa
See scripts/parse.pl and scripts/parse.sh.
See Graph::Easy::Marpa::Parser.
Accepts a graph definition in the Graph::Easy::Marpa language and builds a data structure representing the graph.
This is the default renderer, and can output a dot file, suitable for inputting to the dot program.
dot
Also, it can use GraphViz2 to call dot and write dot's output to yet another file.
This is a file of methods called by Marpa::R2 as callbacks, during the parse.
End-users have no need to call any of its methods.
This manages the config file, which contains a HTML template used by scripts/generate.index.pl.
scripts/generate.index.pl
Methods to help with reading sets of files.
Methods to help with testing and generating the demo page.
See http://savage.net.au/Perl-modules/html/graph.easy.marpa/index.html.
Graph::Easy::Marpa provides a Marpa-based parser for Graph::Easy::Marpa-style graph definitions.
Such graph definitions are wrappers around Graphviz's DOT language. Therefore this module is a pre-processor for DOT files.
The default renderer mentioned above, Graph::Easy::Marpa::Renderer::GraphViz2, can be used to convert the graph into a image.
See "Data Files and Scripts" for details.
This module is available as a Unix-style distro (*.tgz).
See http://savage.net.au/Perl-modules/html/installing-a-module.html for help on unpacking and installing distros.
Install Graph::Easy::Marpa as you would for any Perl module:
Perl
Run:
cpanm Graph::Easy::Marpa
or run:
sudo cpan Graph::Easy::Marpa
or unpack the distro, and then either:
perl Build.PL ./Build ./Build test sudo ./Build install
or:
perl Makefile.PL make (or dmake or nmake) make test make install
new() is called as my($parser) = Graph::Easy::Marpa -> new(k1 => v1, k2 => v2, ...).
new()
my($parser) = Graph::Easy::Marpa -> new(k1 => v1, k2 => v2, ...)
It returns a new object of type Graph::Easy::Marpa.
Key-value pairs accepted in the parameter list (see corresponding methods for details [e.g. maxlevel()]):
Specify a string for the graph definition.
You are strongly encouraged to surround this string with '...' to protect it from your shell.
See also the input_file key to read the graph from a file.
The description key takes precedence over the input_file key.
The value for description is passed to Graph::Easy::Marpa::Parser.
Default: ''.
Specify the name of a file that the rendering engine can write to, which will contain the input to dot (or whatever). This is good for debugging.
If '', the file will not be created.
The value for dot_input_file is passed to Graph::Easy::Marpa::Renderer::GraphViz2.
This is the format of the output file, to be created by the renderer.
The value for format is passed to Graph::Easy::Marpa::Renderer::GraphViz2.
Default: 'svg'.
Read the graph definition from this file.
See also the description key to read the graph from the command line.
The whole file is slurped in as a single graph.
The first few lines of the file can start with /^\s*#/, and will be discarded as comments.
The value for input_file is passed to Graph::Easy::Marpa::Parser.
Specify a logger object.
The default value triggers creation of an object of type Log::Handler which outputs to the screen.
To disable logging, just set logger to the empty string.
The value for logger is passed to Graph::Easy::Marpa::Parser and to Graph::Easy::Marpa::Renderer::GraphViz2.
Default: undef.
This option is only used if an object of type Log::Handler is created. See logger above.
See also Log::Handler::Levels.
The value for maxlevel is passed to Graph::Easy::Marpa::Parser and to Graph::Easy::Marpa::Renderer::GraphViz2.
Default: 'info'. A typical value is 'debug'.
The value for minlevel is passed to Graph::Easy::Marpa::Parser and to Graph::Easy::Marpa::Renderer::GraphViz2.
Default: 'error'.
No lower levels are used.
If an output file name is supplied, and a rendering object is also supplied, then this call is made:
$self -> renderer -> run(format => $self -> format, items => [$self -> items -> print], output_file => $file_name);
This is how the plotted graph is actually created.
The value for output_file is passed to Graph::Easy::Marpa::Renderer::GraphViz2.
$direction must be one of: LR or RL or TB or BT.
Specify the rankdir of the graph as a whole.
The value for rankdir is passed to Graph::Easy::Marpa::Renderer::GraphViz2.
Default: 'TB'.
This is the object whose run() method will be called to render the result of parsing the input graph.
The format of the parameters passed to the renderer are documented in "run(%arg)" in Graph::Easy::Marpa::Renderer::GraphViz2, which is the default value for this object.
Reports, via the log, the tokens recognized by the parser.
The value for report_tokens is passed to Graph::Easy::Marpa::Parser.
Default: 0.
This is the name of the file to write containing the tokens (items) output from Graph::Easy::Marpa::Parser.
The value for token_file is passed to Graph::Easy::Marpa::Parser.
The parser works like this:
Call Graph::Easy::Marpa::Parser -> new(%options).
Graph::Easy::Marpa::Parser -> new(%options)
Call Graph::Easy::Marpa -> new(%options).
Graph::Easy::Marpa -> new(%options)
Of course, the renderer is only called if the parser exits without error.
Details:
This comes from the description parameter to new(), or is read from a file with the input_file parameter.
See new(input_file => $graph_file_name) or new(description => $graph_string) above for details.
A definition looks like '[node.1]{a:b;c:d}->{e:f;}->{g:h}[node.2]{i:j}->[node.3]{k:l}'.
Here, node names are: node.1, node.2 and node.3.
Edge names are: '->' for directed graphs, or '--' for undirected graphs.
Nodes and edges can have attributes, very much like CSS. The attributes in this sample are meaningless, and are just to demonstrate the syntax.
And yes, unlike the original Graph::Easy syntax, you can use a series of edges between 2 nodes, with different attributes, as above.
See http://www.graphviz.org/content/attrs for a long list of the attributes available for Graphviz.
After the parser runs successfully, the parser object holds a Set::Array object of tokens representing the graph.
See "How is the parsed graph stored in RAM?" in Graph::Easy::Marpa::Parser for details.
See new(token_file => $csv_file_name) above for details.
Sample input files for the parser are in data/*.ge. Sample output files are in data/*.tokens.
These use Graph::Easy::Marpa::Parser.
They run the parser on one *.ge input file, and produce an arrayref of items.
Run scripts/parse.pl -h for samples of how to drive it.
Try:
cat data/node.05.ge perl -Ilib scripts/parse.pl -i data/node.05.ge -t data/node.05.tokens -re 1
You can use scripts/parse.sh to simplify this process:
scripts/parse.sh data/node.05.ge data/node.05.tokens -re 1 scripts/parse.sh data/subgraph.12.ge data/subgraph.12.tokens -re 1
Here, the [] indicate an optional parameter.
Get or set the string for the graph definition.
See also the input_file() method to read the graph from a file, below.
The value supplied to the description() method takes precedence over the value read from the input file.
Get or set the name of the file into which the rendering engine will write to input to dot (or whatever).
Get or set the format of the output file, to be created by the renderer.
Get or set the name of the file to read the graph definition from.
See also the description() method.
Calls $self -> logger -> log($level => $s) if ($self -> logger).
Up until V 1.11, this used to call $self -> logger -> $level($s), but the change was made to allow simpler loggers, meaning they did not have to implement all the methods covered by $level(). See CHANGES for details. For more on log levels, see Log::Handler::Levels.
Get or set the logger object.
This logger is passed to Graph::Easy::Marpa::Parser and Graph::Easy::Marpa::Renderer::GraphViz2.
Get or set the value used by the logger object.
This option is only used if an object of type Log::Handler is created. See Log::Handler::Levels.
Get or set the name of the file to which the renderer will write to resultant graph.
If no renderer is supplied, or no output file is supplied, nothing is written.
Get or set the rankdir of the graph as a whole.
The default is 'TB' (top to bottom).
Get or set the rendering object.
This is the object whose run() method will be called to render the result of parsing the input file.
Get or set the flag to report, via the log, the items recognized in the tokens file.
Calls "report()" in Graph::Easy::Marpa::Parser to do the reporting.
Get or set the name of the file to write containing the tokens (items) output from Graph::Easy::Marpa::Parser.
Yes:
The test data files are shipped as data/*.ge.
Of course, you can use any input file name you wish.
The output files of parsed tokens are shipped as data/*.tokens.
Of course, you can use any output file name you wish.
The output files, data/*.dot, are now shipped.
http://jeffreykegler.github.io/Ocean-of-Awareness-blog/.
I've included in this article a section which is aimed at helping us think about this issue.
It's a complete re-write of Graph::Easy, designed to make on-going support for the Graph::Easy::Marpa language much, much easier.
In short, it means a text string containing a definition of a graph, using a cleverly designed language, that can be used to describe the sort of graph you wish to plot. Then, Graph::Easy::Marpa does the plotting by calling Graph::Easy::Marpa::Renderer::GraphViz2.
See "What is the Graph::Easy::Marpa language?" in Graph::Easy::Marpa::Parser.
[node_1]{color: red; style: circle} -> {class: fancy;} [node_2]{color: green;}
See "FAQ" in Graph::Easy::Marpa::Parser.
Since the scan of the input stream is linear, any attribute detected belongs to the nearest preceeding node(s) or edge.
The only attributes which can be passed to a subgraph (group) are those that 'dot' accepts under the 'graph' part of a subgraph definition.
This means the attribute 'rank' cannot be passed, yet.
See data/*.ge and the corresponding data/*.tokens and html/*.svg.
Note: Some files contain deliberate mistakes. See above for scripts/parse.pl and scripts/parse.sh.
I have no plans to support such formats. Nevertheless, having written these modules, it should be fairly easy to derive classes which perform that sort of work.
See scripts/generate.index.pl.
GraphViz2 -> new ( edge => $class{edge} || {color => 'grey'}, global => $class{global} || {directed => 1}, graph => $class{graph} || {rankdir => $self -> rankdir}, logger => $self -> logger, node => $class{node} || {shape => 'oval'}, verbose => 0, )
where $class($name) is taken from the class declarations at the start of the input stream.
The file Changes was converted into Changelog.ini by Module::Metadata::Changes.
Version numbers < 1.00 represent development versions. From 1.00 up, they are production versions.
Many thanks are due to the people who worked on Graph::Easy.
Jeffrey Kegler wrote Marpa, and has been helping me via private emails.
Email the author, or log a bug on RT:
https://rt.cpan.org/Public/Dist/Display.html?Name=Graph::Easy::Marpa.
Graph::Easy::Marpa was written by Ron Savage <ron@savage.net.au> in 2011.
Home page: http://savage.net.au/index.html.
Australian copyright (c) 2011, Ron Savage.
All Programs of mine are 'OSI Certified Open Source Software'; you can redistribute them and/or modify them under the terms of The Artistic License, a copy of which is available at: http://www.opensource.org/licenses/index.html
To install Graph::Easy::Marpa, copy and paste the appropriate command in to your terminal.
cpanm
CPAN shell
perl -MCPAN -e shell install Graph::Easy::Marpa
For more information on module installation, please visit the detailed CPAN module installation guide.