1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816
|
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<book xmlns:xi="http://www.w3.org/2003/XInclude">
<bookinfo>
<title>Synopsis Tutorial</title>
<releaseinfo>Version 0.1</releaseinfo>
<author>
<firstname>Stefan</firstname>
<surname>Seefeld</surname>
</author>
</bookinfo>
<chapter id="intro">
<title>Introduction</title>
<para>
Synopsis is a source code introspection tool. It provides parsers for a variety
of programming languages (C, C++, Python, IDL), and generates internal representations
of varying granularity. The only <emphasis>stable</emphasis> representation, which
is currently used among others to generate documentation, is an Abstract Syntax Tree.
</para>
<para>
This tutorial is focussed on the AST and the concepts around it. Other representations
are presently being worked on, notably in relation to the C++ parser. To learn more
about those (Parse Tree, Symbol Table, etc.) see the
<ulink url="../DevGuide/index.html">Developer's Guide</ulink>.
</para>
<section>
<title>Inspecting code</title>
<!-- Talk about the problem domain:
code documentation, software metrics, etc. -->
<para></para>
</section>
<section>
<title>The Abstract Syntax Tree</title>
<!-- Talk about source code and its representation
inside synopsis -->
<para>See <xref linkend="ast" /></para>
</section>
<section>
<title>The synopsis processing pipeline</title>
<!-- Talk about AST manipulation as done
in synopsis -->
<para>See <xref linkend="pipeline" /></para>
</section>
</chapter>
<chapter id="using">
<title>Using the synopsis tool</title>
<para>In this section we are going to explore the possibilities
to generate documentation from source code. We will demonstrate
how to use synopsis standalone as well as in conjunction with
existing build systems. Further, we will see how to adapt
synopsis to your coding and commenting style, as well as how
to generate the output in a format and style that fulfills
your needs.</para>
<section id="executable">
<title>The synopsis executable</title>
<para>The synopsis executable is a little convenience frontend
to the larger Synopsis framework consisting of AST related
types as well as processor classes.</para>
<para>While the full power of synopsis is available through
scripting (see <xref linkend="scripting" />), it is possible
to quickly generate simple documentation by means of an
easy-to-use executable, that is nothing more but a little
script with some extra command line argument parsing.</para>
<para>This tool has three processor types it can call:</para>
<variablelist>
<varlistentry>
<term>Parser</term>
<listitem>
<para>A processor that will parse source code into an
internal abstract syntax tree (AST). Various Parsers
have a variety of parameters to control how exactly
they do that.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Linker</term>
<listitem>
<para>A processor that will remove duplicate symbols,
forward declarations, and apply any number of AST
manipulations you want. The user typically specifies
what sub-processors to load to run from the linker.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Formatter</term>
<listitem>
<para>A processor that generates some form of formatted
output from an existing AST, typically html, docbook xml,
or class graphs.</para>
</listitem>
</varlistentry>
</variablelist>
<para>You can run synopsis with a single processor, for example
to parse a C++ file <filename>source.hh</filename> and store
the AST into a file <filename>source.syn</filename>, or you can
combine it directly with linker and or formatter to generate
the output you want in a single call.</para>
<para>While the document generation in a single call is convenient,
for larger projects it is much more sensible to integrate the
document generation into existing build systems and let the build
system itself manage the dependencies between the intermediate files
and the source files.</para>
<para>For example, a typical Makefile fragment that contains the rules
to generate documentation out of multiple source files may look like
this:</para>
<programlisting>
hdr := $(wildcard *.h)
syn := $(patsubst %.h, %.syn, $(hdr))
html: $(syn)
synopsis -f HTML -o $@ $<
%.syn: %.h
synopsis -p Cxx -I../include -o $@ $<
</programlisting>
<para>Here is a listing of all available options:</para>
<variablelist>
<varlistentry>
<term>-h</term>
<term>--help</term>
<listitem>
<para>print out help message</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-V</term>
<term>--version</term>
<listitem>
<para>print out version info and exit</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-v</term>
<term>--verbose</term>
<listitem>
<para>operate verbosely</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-d</term>
<term>--debug</term>
<listitem>
<para>operate in debug mode</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-o</term>
<term>--output</term>
<listitem>
<para>output file / directory</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-p</term>
<term>--parser</term>
<listitem>
<para>select a parser</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-l</term>
<term>--link</term>
<listitem>
<para>link</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-f</term>
<term>--formatter</term>
<listitem>
<para>select a formatter</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-I</term>
<listitem>
<para>set an include search path</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-D</term>
<listitem>
<para>specify a macro for the parser</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-W</term>
<listitem>
<para>pass down additional arguments to a processor.
For example '-Wp,-I.' sends the '-I.' option to the
parser.</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="parsing">
<title>Parsing source code</title>
<para>As synopsis' current focus is on document generation, the
AST it generates from a parsed source file consists of declarations
only. Let's thus in the following consider how synopsis parses
C++ header files.</para>
<para>Let's assume a simple header file, containing some declarations:</para>
<para>
<programlisting><xi:include href="examples/Paths/src/Path.h" parse="text"/>
</programlisting>
</para>
<para>Process this with
<programlisting>synopsis -p Cxx -f HTML -o Paths Path.h</programlisting>
to generate an html document. As you will note, all declarations appear
in the document, each associated with the comment(s) preceding it in the
code. We used here a C++ header (and the associated <type>Cxx</type>
parser), but we could equally well have chosen another supported language.
</para>
<para>While this one-line command is convenient, it is usually better
(and more clear) to separate the individual processing steps. We will now
fine-tune the processing, demonstrating the flexibility of the processers.
</para>
</section>
<section id="comments">
<title>Using comments for documentation</title>
<para>The <filename>Path.h</filename> header contains different kinds of comments,
not all of which are intended to be used as documentation. Here we want
to preserve only those comments starting with '//.'. That's done with the
<type>SSDFilter</type>(read: 'slash slash dot') processor. Further, the
members of the <type>Vertex</type> strcture are commented <emphasis>after</emphasis>
the declaration, with comments using the prefix '//.<'. These are dealt
with by the <type>Previous</type> processor.</para>
<para>The result of
<programlisting>synopsis -p Cxx -l SSDFilter,Previous -o Path.syn Path.h
synopsis -f HTML -o Paths Path.syn
</programlisting>
looks already much better.
</para>
<para>Let us now add more input files:
<programlisting><xi:include href="examples/Paths/src/Polyline.h" parse="text"/>
</programlisting>
This header uses a different comment convention. Here relevant comments
start with '//', so we will use the <type>SSFilter</type> Processor.
Additionally, it uses special tags to group declarations together. As there
is more than one possible grouping syntax, we will use the <type>Grouper1</type>
processor (and discuss the others in <xref linkend="scripting"/>):
<programlisting>synopsis -p Cxx -l SSFilter,Grouper1 -o Polyline.syn Polyline.h
synopsis -f HTML -o Paths Path.syn Polyline.syn
</programlisting>
</para>
<para>Finally, let us look at a header file that is written in javadoc style,
i.e. with java-style comments, and containing special tags:
<programlisting><xi:include href="examples/Paths/src/Nurbs.h" parse="text"/>
</programlisting>
Here, we filter out undesired comments with the <type>JavaFilter</type>
processor, and then parse the comments for @tags with <type>JavaTags</type>:
<programlisting>synopsis -p Cxx -l JavaFilter,JavaTags -o Nurbs.syn Nurbs.h
</programlisting>
Finally, we generate the documentation with all the headers together, with the
additional <option>--javadoc</option> flag that tells the HTML formatter to
include a <type>Javadoc</type> comment processor to generate appropriate links
and other formatting.
<programlisting>synopsis -f HTML --javadoc -o Paths Path.syn Polyline.syn Bezier.syn Nurbs.syn
</programlisting>
</para>
<para>The full code together with the Makefile can be found <ulink url="examples/Paths">here</ulink>
</para>
</section>
<section id="misc">
<title>Miscellaneous</title>
<para>As discussed earlier, there is a variety of processors available in the
Synopsis distribution. There are a number of parsers (for IDL, Python, and C++,
a C parser is in development), some formatters (HTML is probably the most popular
one, but others such as ASCII, Texinfo, Docbook, or Dot may be useful, too),
and a number of linker processors.</para>
<para>To find out about the available options of each of them, use the <option>--help</option>
option. For example
<programlisting>synopsis -f Dot --help</programlisting>
will tell us how to use the Dot formatter. To pass these options to the Dot formatter,
simply append them via the <option>-Wf</option> option, and they will be forwarded.
</para>
<para>If we want to generate a (UML) class diagram, we could for example run
<programlisting>synopsis -f Dot -Wf,--title="class diagram" -Wf,--format=ps \
-Wf,hide_operations=False,hide_attributes=False \
-o Paths.ps Paths.syn</programlisting>
</para>
<para>But passing options via the command line has its limits, both, in terms of
usability, as well as for the robustness of the interface (all data have to be
passed as strings !). Therefor, for any tasks demanding more flexibility a
scripting interface is provided, which will be discussed in the next chapter.</para>
</section>
</chapter>
<chapter id="scripting">
<title>Scripting and extending synopsis</title>
<para>Often it isn't enough to provide textual options to the synopsis tool.
The processors that are at the core of the synopsis framework are highly
configurable. They can be passed simple string / integer / boolean type
parameters, but some of them are also composed of objects that could be
passed along as parameters.</para>
<para>While synopsis provides a lot of such building blocks already, you may
want to extend them by subclassing your own.</para>
<para>In all these cases scripting is a much more powerful way to let
synopsis do what you want. This chapter explains the basic design
of the framework, and demonstrates how to write scripts using the
built-in building blocks as well as user extensions</para>
<section id="ast">
<title>The AST</title>
<para>At the core of synopsis is a representation of
the source code to be analyzed called an abstract syntax
tree (AST). Language specific syntax gets translated into
and abstract tree of statements, annotated with all the necessary
metadata to recover the important details during further processing.</para>
<para>At this time only one particular type of statements is translated
into an AST: declarations. This can be declarations of types, functions,
variables, etc. Attached to a declaration is a set of comments that was
found in the source code before the declaration. It is thus possible
to provide other metadata (such as code documentation) as part of these
comments. A variety of comment processors exist to extract such metadata
from comments.</para>
<mediaobject>
<imageobject>
<imagedata fileref="images/ast.svg" format="SVG" scale="80" />
</imageobject>
<imageobject>
<imagedata fileref="images/ast.png" format="PNG" />
</imageobject>
</mediaobject>
</section>
<section id="processor">
<title>The Processor class</title>
<!-- Talk about the Processor class design -->
<para>The Processor class is at the core of the synopsis framework. It
is the basic building block out of which processing pipelines can be
composed.</para>
<mediaobject>
<imageobject>
<imagedata fileref="images/processor.svg" format="SVG" scale="80" />
</imageobject>
<imageobject>
<imagedata fileref="images/processor.png" format="PNG" />
</imageobject>
</mediaobject>
<para>The requirement that processors can be composed into a pipeline
has some important consequences for its design. The process method takes
an ast argument, which it will operate on, and then return. It is this
ast that forms the backbone of the pipeline, as it is passed along from
one processor to the next. Additionally, parameters may be passed to the
processor, such as input and output.</para>
<programlisting>def process(self, ast, **keywords):
self.set_parameters(keywords)
self.ast = self.merge_input(ast)
# do the work here...
return self.output_and_return_ast()</programlisting>
<para>Depending on the nature of the processor, it may parse the input
file as source code, or simply read it in from a persistent state. In
any case, the result of the input reading is merged in with the existing
ast.</para>
<programlisting>def process(self, ast, **keywords):
self.set_parameters(keywords)
for file in self.input:
self.ast.merge(self.parse(file))
return self.output_and_return_ast()</programlisting>
<para>Similarly with the output: if an output parameter is defined, the
ast may be stored in that file before it is returned. Or, if the
processor is a formatter, the output parameter may indicate the file /
directory name to store the formatted output in.</para>
<programlisting>def process(self, ast, **keywords):
self.set_parameters(keywords)
self.ast = self.merge_input(ast)
self.format(self.output)
return set.ast</programlisting>
</section>
<section id="pipeline">
<title>Composing a pipeline</title>
<para>With such a design, processors can simply be chained together:</para>
<mediaobject>
<imageobject>
<imagedata fileref="images/pipeline.svg" format="SVG" scale="80" />
</imageobject>
<imageobject>
<imagedata fileref="images/pipeline.png" format="PNG" />
</imageobject>
</mediaobject>
<para>A parser creates an AST, which is passed to the linker (creating
a table of contents on the fly) which passes it further down to a
formatter.</para>
<programlisting>parser = ...
linker = ...
formatter = ...
ast = AST()
ast = parser.process(ast, input=['source.hh'])
ast = linker.process(ast)
ast = formatter.process(ast, output='html')</programlisting>
<para>And, to be a little bit more scalable, and to allow the use of
dependency tracking build tools such as make, the intermediate asts can
be persistet into files. Thus, the above pipeline is broken up into multiple
pipelines, where the 'output' parameter of the parser is used to
point to ast stores, and the 'input' parameter of the linker/formatter
pipeline then contains a list of these ast store files.</para>
<mediaobject>
<imageobject>
<imagedata fileref="images/pipelines.svg" format="SVG" scale="80" />
</imageobject>
<imageobject>
<imagedata fileref="images/pipelines.png" format="PNG" />
</imageobject>
</mediaobject>
<para>Parse <filename>source1.hh</filename> and write the ast to <filename>source1.syn</filename>:</para>
<programlisting>parser.process(AST(), input = ['source1.hh'], output = 'source1.syn')</programlisting>
<para>Parse <filename>source2.hh</filename> and write the ast to <filename>source2.syn</filename>:</para>
<programlisting>parser.process(AST(), input = ['source2.hh'], output = 'source2.syn')</programlisting>
<para>Read in <filename>source1.syn</filename> and <filename>source2.syn</filename>, then link and format
into the <filename>html</filename> directory:</para>
<programlisting>formatter.process(linker.process(AST(), input = ['source1.syn', 'source2.syn']), output = 'html')</programlisting>
</section>
<section id="script">
<title>Writing your own synopsis script</title>
<para>The synopsis framework provides a function <function>process</function>
that lets you declare and expose processors as commands so they can be
used per command line:
<programlisting><xi:include href="examples/Paths/doc1/synopsis.py" parse="text"/>
</programlisting>
</para>
<para>With such a script <filename>synopsis.py</filename> it is possible
to call
<programlisting>python synopsis.py cxx_ssd --output=Bezier.syn Bezier.h
</programlisting>
to do the same as in <xref linkend="using"/>, but with much more
flexibility. Let's have a closer look at how this script works:</para>
<section id="importing">
<title>Importing all desired processors</title>
<para>As every conventional python script, the first thing to do is
to pull in all the definitions that are used later on, in our case
the definition of the <function>process</function> function, together
with a number of predefined processors.
</para>
</section>
<section id="composing">
<title>Composing new processors</title>
<para>As outlined in <xref linkend="pipeline"/>, processors can be
composed into pipelines, which are themselfs new (composite) processors.
Synopsis provides a <type>Composite</type> type for convenient pipeline
construction. Its constructor takes a list of processors that the
process method will iterate over.
</para>
</section>
<section id="extending">
<title>Defining new processors</title>
<para>New processors can be defined by deriving from <type>Processor</type>
or any of its subclasses. As outlined in <xref linkend="processor"/>,
it has only to respect the semantics of the <function>process</function>
method.</para>
</section>
<section id="process">
<title>Exposing the commands</title>
<para>With all these new processrs defined, they need to be made accessible
to be called per command line. That is done with the <function>process</function>
function. It sets up a dictionary of named processors, with which the script
can be invoked as
<programlisting>python synopsis.py joker
</programlisting>
which will invoke the joker's <function>process</function> method with
any argument that was provided passed as a named value (keyword).
</para>
</section>
</section>
</chapter>
<chapter>
<title>Processor design</title>
<section id="python-parser">
<title>Python Parser</title>
</section>
<section id="idl-parser">
<title>IDL Parser</title>
<para>The IDL parser parses CORBA IDL.</para>
</section>
<section id="cpp-parser">
<title>Cpp Parser</title>
<para>The Cpp parser preprocesses C and C++ files. As any normal preprocessor,
it will generate a file suitable as input for a C or C++ parser, i.e. it
processes include and macro statements. However, it will store the encountered
preprocessor directives in the AST for further analysis.</para>
<para>As the list of included files may grow rather large, there exist two mechanisms
to restrict the number of files for which information is retained. The <type>main_file_only</type>
parameter is used to indicate that only the top-level file being parsed should be included.
The <type>base_path</type> parameter, on the other hand, will restrict the number files if
<type>main_file_only</type> is set to <type>False</type>. In this case, the <type>base_path</type>
is used as a prefix, and only those file whose name starts with that prefix are marked as
<type>main</type>.
</para>
<para>For each included file, a <type>SourceFile</type> object is created and added
to the parent's <type>Include</type> list. Further, all macro declarations, as well
as macro calls, are recorded. While most useful in conjunction with the C and Cxx processors,
these data can be of use stand-alone, too. For example consider a tool that reports file
dependencies based on <type>#include</type> statements. The Dot formatter (see <xref linkend="dot-formatter"/>)
can generate a file dependency graph from the Cpp processor output alone:
</para>
<mediaobject>
<imageobject>
<imagedata fileref="images/Files.png" format="PNG" />
</imageobject>
</mediaobject>
<para>Particular care has been taken in order to emulate system compilers, as these
all provide their own sets of macros, include paths, etc. Thus, the Cpp parser can
be trained to understand these compiler-specific settings.</para>
<para>For details about the parameters see <xref linkend="Cpp-Parser-ref"/>.</para>
</section>
<section id="cc-parser">
<title>C Parser</title>
<para>The C parser parses C.</para>
</section>
<section id="cxx-parser">
<title>Cxx Parser</title>
<para>The Cxx parser parses C++. If the <type>preprocess</type> parameter is set, it will
call the preprocessor (see <xref linkend="cpp-parser"/>). Its main purpose is to generate
an AST containing all declarations. However, it can store more detailed information about
the source code to be used in conjunction with the HTML parser to generate a cross-referenced
view of the code. The <type>syntax_prefix</type> and <type>xref_prefix</type> parameters are
used to indicate directories within which to store information about the source files being
parsed. For a view of the processing pipeline to generate cross-referenced code see
<xref linkend="cross-referencing"/>.</para>
</section>
<section id="linker">
<title>Linker</title>
<para>The Linker recursively traverses the AST using the Visitor
pattern, and replaces any duplicate types with their originals, and
removes duplicate declarations. References to the removed declarations
are replaced with a reference to the original. This action is largely
unncessary due to the -m flags, but can still be useful in some
situations, such as when you have nested classes defined in separate
files. It also converts AST.Modules into AST.MetaModules, which list all
the files a module is defined in.</para>
</section>
<section id="comment-parsers">
<title>Comment Parsers</title>
</section>
<section id="dump-formatter">
<title>Dump Formatter</title>
<para>The Dump formatter's main goal is to provide a format
that is as close to the AST tree, is easily browsable to the
naked eye, and provides the means to do validation or other
analysis.</para>
<para>It generates an xml tree that can be browsed via mozilla (it
uses a stylesheet for convenient display), or it can be analyzed
with some special tools using xpath expressions.</para>
<para>It is used right now for all unit tests.</para>
</section>
<section id="ascii-formatter">
<title>ASCII Formatter</title>
<para>The ASCII formatter attempts to output the AST in a format that is
suitable for recompilation, or close to. You can use this to check
that your code and comments are getting parsed correctly, or out of
interest to see the structure of the AST after Linking. Like the DUMP
formatter, this is mostly of use for debugging.</para>
</section>
<section id="docbook-formatter">
<title>Docbook Formatter</title>
</section>
<section id="dot-formatter">
<title>Dot Formatter</title>
<para>The Dot formatter can generate graphs for various types and output formats.
Among the supported output formats are <type>png</type>, <type>svg</type>, and
<type>html</type>.</para>
<para>A typical use is the generation of UML class (inheritance and aggregation)
diagrams:</para>
<mediaobject>
<imageobject>
<imagedata fileref="images/Classes3.png" format="PNG" />
</imageobject>
</mediaobject>
<para>But it can also be used to generate a graphical representation of file
inclusions:</para>
<mediaobject>
<imageobject>
<imagedata fileref="images/Files.png" format="PNG" />
</imageobject>
</mediaobject>
</section>
<section id="html-formatter">
<title>HTML Formatter</title>
<para>The HTML formatter generates html output. It is designed
in a modular way, to let users customize in much detail how
to format the AST. It formats the AST into a number of views, which highlight
different aspects of the AST. Some views show the file / directory layout,
others group declarations by scopes, or provide an annotated source view.</para>
<mediaobject>
<imageobject>
<imagedata fileref="images/html-classes.svg" format="SVG" scale="80" />
</imageobject>
<imageobject>
<imagedata fileref="images/html-classes.png" format="PNG" />
</imageobject>
</mediaobject>
<para>The <type>views</type> parameter is used to specify the list of View objects to be
used by the formatter. Each is a <type>Parametrized</type>, so you can pass parameters to
the views, too. Here are the most important <type>View</type> types:</para>
<variablelist>
<varlistentry>
<term>FramesIndex</term>
<listitem>
<para>While arguably not really a view in itself, this is right now the master view, organizing other views in frames.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>FileDetails</term>
<listitem>
<para>Shows details about a given file, such as what other files are included, what declarations it contains, etc.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>DirBrowse</term>
<listitem>
<para>Presents a directory (of source files).</para>
</listitem>
</varlistentry>
<varlistentry>
<term>FileTreeJS</term>
<listitem>
<para>A tree view containing source files.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>InheritanceGraph</term>
<listitem>
<para>A UML-like inheritance diagram for all classes.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>ModuleIndexer</term>
<listitem>
<para>A tree containing all modules.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>NameIndex</term>
<listitem>
<para>A global index of all declared names (macros, variables, types, ...)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Scope</term>
<listitem>
<para>The content of a given scope.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Source</term>
<listitem>
<para>A cross-referenced view of a source file.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>XRef</term>
<listitem>
<para>A listing of symbols with links to their documentation, definition, and reference.</para>
</listitem>
</varlistentry>
</variablelist>
<section id="scope-formatter">
<title>The Scope View</title>
<para>
The most important view for documentation purposes is doubtless the <type>Scope</type>view. It presents all declaration
in a given scope, together with a number of references to other views if appropriate. The <type>Scope</type>
view is subdivided into <type>Parts</type>, which are (for flexibility's sake) further subdivided into
<type>Fragments</type>.
</para>
</section>
<section id="cross-referencing">
<title>SourceCode Cross Referencing</title>
<para>
A particularly interesting feature of the C++ parser and the HTML formatter is the ability to
generate a cross-referenced view on the entire source code. Since the AST itself only stores
declarations, the two processors need to share some other external data containing all the
remaining details about the code, i.e. where the various types and variables are declared and
where they are referenced from.
</para>
<para>
Here is a diagram for the data flow used to generate these views:
</para>
<mediaobject>
<imageobject>
<imagedata fileref="images/xref.svg" format="SVG" scale="80" />
</imageobject>
<imageobject>
<imagedata fileref="images/xref.png" format="PNG" />
</imageobject>
</mediaobject>
<para>
Use the <type>syntax_prefix</type> and <type>xref_prefix</type> parameters in both, the C++ parser
as well as the XRef and Source views to specify the files to pass source file detail information.
</para>
</section>
</section>
<section id="sxr-formatter">
<title>SXR Formatter</title>
<para>The SXR formatter is a variant of the HTML formatter.</para>
<mediaobject>
<imageobject>
<imagedata fileref="images/html-classes.svg" format="SVG" scale="80" />
</imageobject>
<imageobject>
<imagedata fileref="images/html-classes.png" format="PNG" />
</imageobject>
</mediaobject>
<para></para>
</section>
</chapter>
<chapter>
<title>Extending synopsis with the C++ API</title>
<section id="cxx-api">
<para>The C++ API tries to get as close as possible to the python API
for the AST and Type module (see <xref linkend="ast" />). Two factories,
an <type>ASTKit</type> and a <type>TypeKit</type> allow the creation of
all the AST objects.</para>
<para></para>
</section>
</chapter>
<appendix><title>Listing of all Processors and their parameters</title>
<para>
This is a listing of all processors with their respective parameters
that can be set as described in <xref linkend="script" />.
</para>
<xi:include href="Synopsis.Parsers.Python.Parser.xml">
<xi:fallback>The Python parser reference...</xi:fallback>
</xi:include>
<xi:include href="Synopsis.Parsers.IDL.Parser.xml">
<xi:fallback>The IDL parser reference...</xi:fallback>
</xi:include>
<xi:include href="Synopsis.Parsers.Cpp.Parser.xml">
<xi:fallback>The Cpp parser reference...</xi:fallback>
</xi:include>
<xi:include href="Synopsis.Parsers.C.Parser.xml">
<xi:fallback>The C parser reference...</xi:fallback>
</xi:include>
<xi:include href="Synopsis.Parsers.Cxx.Parser.xml">
<xi:fallback>The Cxx parser reference...</xi:fallback>
</xi:include>
<xi:include href="Synopsis.Processors.Linker.xml">
<xi:fallback>The Linker reference...</xi:fallback>
</xi:include>
<xi:include href="Synopsis.Formatters.Dot.Formatter.xml">
<xi:fallback>The Dot formatter reference...</xi:fallback>
</xi:include>
<xi:include href="Synopsis.Formatters.Dump.Formatter.xml">
<xi:fallback>The Dump formatter reference...</xi:fallback>
</xi:include>
<xi:include href="Synopsis.Formatters.Docbook.Formatter.xml">
<xi:fallback>The Docbook formatter reference...</xi:fallback>
</xi:include>
<xi:include href="Synopsis.Formatters.Texinfo.Formatter.xml">
<xi:fallback>The Texinfo formatter reference...</xi:fallback>
</xi:include>
<xi:include href="Synopsis.Formatters.HTML.Formatter.xml">
<xi:fallback>The HTML formatter reference...</xi:fallback>
</xi:include>
<xi:include href="Synopsis.Formatters.SXR.Formatter.xml">
<xi:fallback>The SXR formatter reference...</xi:fallback>
</xi:include>
</appendix>
</book>
|