Commit c22d77a7 authored by Dimitri van Heesch's avatar Dimitri van Heesch

Release-1.7.6.1-20120122

parent fd8b446f
DOXYGEN Version 1.7.6.1-20120110 DOXYGEN Version 1.7.6.1-20120122
Please read the installation section of the manual Please read the installation section of the manual
(http://www.doxygen.org/install.html) for instructions. (http://www.doxygen.org/install.html) for instructions.
-------- --------
Dimitri van Heesch (10 January 2012) Dimitri van Heesch (22 January 2012)
DOXYGEN Version 1.7.6.1_20120110 DOXYGEN Version 1.7.6.1_20120122
Please read INSTALL for compilation instructions. Please read INSTALL for compilation instructions.
...@@ -26,4 +26,4 @@ forum. ...@@ -26,4 +26,4 @@ forum.
Enjoy, Enjoy,
Dimitri van Heesch (dimitri@stack.nl) (10 January 2012) Dimitri van Heesch (dimitri@stack.nl) (22 January 2012)
...@@ -20,7 +20,7 @@ doxygen_version_minor=7 ...@@ -20,7 +20,7 @@ doxygen_version_minor=7
doxygen_version_revision=6.1 doxygen_version_revision=6.1
#NOTE: Setting version_mmn to "NO" will omit mmn info from the package. #NOTE: Setting version_mmn to "NO" will omit mmn info from the package.
doxygen_version_mmn=20120110 doxygen_version_mmn=20120122
bin_dirs=`echo $PATH | sed -e "s/:/ /g"` bin_dirs=`echo $PATH | sed -e "s/:/ /g"`
......
...@@ -19,19 +19,21 @@ HTML_FOOTER = ...@@ -19,19 +19,21 @@ HTML_FOOTER =
QUIET = NO QUIET = NO
WARNINGS = YES WARNINGS = YES
DISABLE_INDEX = YES DISABLE_INDEX = YES
GENERATE_TREEVIEW = YES
EXTRACT_ALL = NO EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO EXTRACT_PRIVATE = NO
GENERATE_MAN = NO GENERATE_MAN = NO
GENERATE_LATEX = YES GENERATE_LATEX = YES
GENERATE_HTML = YES GENERATE_HTML = YES
GENERATE_HTMLHELP = YES GENERATE_HTMLHELP = NO
GENERATE_RTF = NO GENERATE_RTF = NO
GENERATE_XML = NO GENERATE_XML = NO
HTML_COLORSTYLE_SAT = 0
ENABLED_SECTIONS = logo_on ENABLED_SECTIONS = logo_on
ENABLE_PREPROCESSING = NO ENABLE_PREPROCESSING = NO
CASE_SENSE_NAMES = NO CASE_SENSE_NAMES = NO
IMAGE_PATH = . IMAGE_PATH = .
INPUT = index.doc install.doc starting.doc docblocks.doc lists.doc \ INPUT = index.doc install.doc starting.doc docblocks.doc markdown.doc \
grouping.doc formulas.doc diagrams.doc preprocessing.doc \ grouping.doc formulas.doc diagrams.doc preprocessing.doc \
autolink.doc output.doc searching.doc customize.doc custcmd.doc \ autolink.doc output.doc searching.doc customize.doc custcmd.doc \
external.doc faq.doc trouble.doc features.doc \ external.doc faq.doc trouble.doc features.doc \
...@@ -48,3 +50,4 @@ SEARCHENGINE = NO ...@@ -48,3 +50,4 @@ SEARCHENGINE = NO
PDF_HYPERLINKS = YES PDF_HYPERLINKS = YES
USE_PDFLATEX = YES USE_PDFLATEX = YES
STRIP_CODE_COMMENTS = NO STRIP_CODE_COMMENTS = NO
HTML_STYLESHEET = doxygen_manual.css
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
\verbatim <a href="linkURL">link text</a> \endverbatim \verbatim <a href="linkURL">link text</a> \endverbatim
which will be automatically translated to other output formats by Doxygen. which will be automatically translated to other output formats by Doxygen.
\section linkclass Links to classes. \section linkclass Links to classes
All words in the documentation that correspond to a documented class and All words in the documentation that correspond to a documented class and
contain at least one non-lower case character will automatically be contain at least one non-lower case character will automatically be
...@@ -48,14 +48,14 @@ ...@@ -48,14 +48,14 @@
should put a \% in front of the word. should put a \% in front of the word.
To link to an all lower case symbol, use \ref cmdref "\\ref". To link to an all lower case symbol, use \ref cmdref "\\ref".
\section linkfile Links to files. \section linkfile Links to files
All words that contain a dot (<tt>.</tt>) that is not the last character All words that contain a dot (<tt>.</tt>) that is not the last character
in the word are considered to be file names. in the word are considered to be file names.
If the word is indeed the name of a documented input file, a link will If the word is indeed the name of a documented input file, a link will
automatically be created to the documentation of that file. automatically be created to the documentation of that file.
\section linkfunc Links to functions. \section linkfunc Links to functions
Links to functions are created if one of the following patterns is Links to functions are created if one of the following patterns is
encountered: encountered:
...@@ -101,7 +101,7 @@ ...@@ -101,7 +101,7 @@
that matches the pattern. that matches the pattern.
</ol> </ol>
\section linkother Links to variables, typedefs, enum types, enum values and defines. \section linkother Links to other members
All of these entities can be linked to in the same way as described in the All of these entities can be linked to in the same way as described in the
previous section. For sake of clarity it is advised to only use previous section. For sake of clarity it is advised to only use
......
...@@ -2140,13 +2140,35 @@ Commands for visual enhancements ...@@ -2140,13 +2140,35 @@ Commands for visual enhancements
To have multiple words in typewriter font use \<tt\>multiple words\</tt\>. To have multiple words in typewriter font use \<tt\>multiple words\</tt\>.
<hr> <hr>
\section cmdcode \\code \section cmdcode \\code [ '{'<word>'}']
\addindex \\code \addindex \\code
Starts a block of code. A code block is treated differently Starts a block of code. A code block is treated differently
from ordinary text. It is interpreted as C/C++ code. The names of the from ordinary text. It is interpreted as source code. The names of
classes and members that are documented are automatically replaced by classes and members and other documented entities are automatically
links to the documentation. replaced by links to the documentation.
By default the language that is assumed for syntax highlighting is based
on the location where the \\code block was found. If this part of
a Python file for instance, the syntax highlight will be done according
to the Python syntax.
If it unclear from the context which language is meant (for instance the
comment is in a .txt or .markdown file) then you can also explicitly
indicate the language, by putting the file extension typically
that doxygen associated with the language in curly brackets after the
code block. Here is an example:
\verbatim
\code{.py}
class Python:
pass
\endcode
\code{.cpp}
class Cpp {};
\endcode
\endverbatim
\sa section \ref cmdendcode "\\endcode" and section \ref cmdverbatim "\\verbatim". \sa section \ref cmdendcode "\\endcode" and section \ref cmdverbatim "\\verbatim".
......
...@@ -16,19 +16,30 @@ ...@@ -16,19 +16,30 @@
*/ */
/*! \page docblocks Documenting the code /*! \page docblocks Documenting the code
\section specialblock Special documentation blocks This chapter covers two topics:
1. How to put comments in your code such that doxygen incorporates them in
the documentation it generates.
This is further detailed in the \ref specialblock "next section".
2. Ways to structure the contents of a comment block such that the output
looks good, as explained in section \ref docstructure.
A special documentation block is a C or C++ style comment block with some \section specialblock Special comment blocks
additional markings, so doxygen knows it is a piece of documentation that
needs to end up in the generated documentation. For Python, VHDL, Fortran, and
Tcl code there are different comment conventions, which can be found in sections
\ref pythonblocks, \ref vhdlblocks, \ref fortranblocks, and \ref tclblocks
respectively.
For each code item there are two (or in some cases three) types of descriptions, A special comment block is a C or C++ style comment block with some
which together form the documentation: a \e brief description and \e detailed additional markings, so doxygen knows it is a piece of structured text that
needs to end up in the generated documentation. The \ref cppblock "next" section
presents the various styles supported by doxygen.
For Python, VHDL, Fortran, and Tcl code there are different commenting
conventions, which can be found in sections \ref pythonblocks, \ref vhdlblocks,
\ref fortranblocks, and \ref tclblocks respectively.
\subsection cppblock Comment blocks for C-like languages (C/C++/C#/Objective-C/PHP/Java)
For each entity in the code there are two (or in some cases three) types of descriptions,
which together form the documentation for that entity; a *brief* description and *detailed*
description, both are optional. For methods and functions there is also a third description, both are optional. For methods and functions there is also a third
type of description, the so called "in body" description, which consists of type of description, the so called *in body* description, which consists of
the concatenation of all comment blocks found within the body of the method or function. the concatenation of all comment blocks found within the body of the method or function.
Having more than one brief or detailed description is allowed (but not recommended, Having more than one brief or detailed description is allowed (but not recommended,
...@@ -39,7 +50,7 @@ a short one-liner, whereas the detailed description provides longer, ...@@ -39,7 +50,7 @@ a short one-liner, whereas the detailed description provides longer,
more detailed documentation. An "in body" description can also act as a detailed more detailed documentation. An "in body" description can also act as a detailed
description or can describe a collection of implementation details. description or can describe a collection of implementation details.
For the HTML output brief descriptions are also For the HTML output brief descriptions are also
use to provide tooltips at places where an item is referenced. used to provide tooltips at places where an item is referenced.
There are several ways to mark a comment block as a detailed description: There are several ways to mark a comment block as a detailed description:
<ol> <ol>
...@@ -183,49 +194,6 @@ They will be joined. Note that this is also the case if the descriptions ...@@ -183,49 +194,6 @@ They will be joined. Note that this is also the case if the descriptions
are at different places in the code! In this case the order will depend are at different places in the code! In this case the order will depend
on the order in which doxygen parses the code. on the order in which doxygen parses the code.
Here is an example of a documented piece of C++ code using the Qt style:
\include qtstyle.cpp
\htmlonly
Click <a href="$(DOXYGEN_DOCDIR)/examples/qtstyle/html/class_test.html">here</a>
for the corresponding HTML documentation that is generated by doxygen.
\endhtmlonly
The one-line comments contain a brief description,
whereas the multi-line comment blocks contain a more detailed description.
The brief descriptions are included in the member overview of a
class, namespace or file and are printed using a small italic font
(this description can be hidden by setting
\ref cfg_brief_member_desc "BRIEF_MEMBER_DESC" to \c NO in
the config file). By default the brief descriptions become the first
sentence of the detailed descriptions
(but this can be changed by setting the \ref cfg_repeat_brief "REPEAT_BRIEF"
tag to \c NO). Both the brief and the detailed descriptions are optional
for the Qt style.
By default a JavaDoc style documentation block behaves the same way as a
Qt style documentation block. This is not according the JavaDoc specification
however, where the first sentence of the documentation block is automatically
treated as a brief description. To enable this behavior you should set
\ref cfg_javadoc_autobrief "JAVADOC_AUTOBRIEF" to YES in the configuration
file. If you enable this option and want to put a dot in the middle of a
sentence without ending it, you should put a backslash and a space after it.
Here is an example:
\verbatim
/** Brief description (e.g.\ using only a few words). Details follow. */
\endverbatim
Here is the same piece of code as shown above, this time documented using the
JavaDoc style and \ref cfg_javadoc_autobrief "JAVADOC_AUTOBRIEF" set to YES:
\include jdstyle.cpp
\htmlonly
Click <a href="$(DOXYGEN_DOCDIR)/examples/jdstyle/html/class_test.html">here</a>
for the corresponding HTML documentation that is generated by doxygen.
\endhtmlonly
Similarly, if one wishes the first sentence of a Qt style documentation
block to automatically be treated as a brief description, one may set
\ref cfg_qt_autobrief "QT_AUTOBRIEF" to YES in the configuration file.
Unlike most other documentation systems, doxygen also allows you to put Unlike most other documentation systems, doxygen also allows you to put
the documentation of members (including global functions) in front of the documentation of members (including global functions) in front of
...@@ -235,10 +203,9 @@ implementer of the members more direct access to the documentation. ...@@ -235,10 +203,9 @@ implementer of the members more direct access to the documentation.
As a compromise the brief description could be placed before the As a compromise the brief description could be placed before the
declaration and the detailed description before the member definition. declaration and the detailed description before the member definition.
\section memberdoc Putting documentation after members \subsubsection memberdoc Putting documentation after members
If you want to document the members of a file, struct, union, class, or enum, If you want to document the members of a file, struct, union, class, or enum,
and you want to put the documentation for these members inside the compound,
it is sometimes desired to place the documentation block after the member it is sometimes desired to place the documentation block after the member
instead of before. For this purpose you have to put an additional \< marker instead of before. For this purpose you have to put an additional \< marker
in the comment block. Note that this also works for the parameters in the comment block. Note that this also works for the parameters
...@@ -275,7 +242,7 @@ or ...@@ -275,7 +242,7 @@ or
int var; ///< Brief description after the member int var; ///< Brief description after the member
\endverbatim \endverbatim
For functions one can use \@param to document the parameters For functions one can use the \ref cmdparam "\@param" command to document the parameters
and then use <code>[in]</code>, <code>[out]</code>, <code>[in,out]</code> and then use <code>[in]</code>, <code>[out]</code>, <code>[in,out]</code>
to document the direction. For inline documentation this is also possible to document the direction. For inline documentation this is also possible
by starting with the direction attribute, e.g. by starting with the direction attribute, e.g.
...@@ -302,11 +269,54 @@ Here is an example of the use of these comment blocks: ...@@ -302,11 +269,54 @@ Here is an example of the use of these comment blocks:
(like <code>\\class</code>) are not allowed (like <code>\\class</code>) are not allowed
inside these comment blocks. inside these comment blocks.
\section structuralcommands Documentation at other places \subsubsection docexamples Examples
Here is an example of a documented piece of C++ code using the Qt style:
\include qtstyle.cpp
\htmlonly
Click <a href="$(DOXYGEN_DOCDIR)/examples/qtstyle/html/class_test.html">here</a>
for the corresponding HTML documentation that is generated by doxygen.
\endhtmlonly
The brief descriptions are included in the member overview of a
class, namespace or file and are printed using a small italic font
(this description can be hidden by setting
\ref cfg_brief_member_desc "BRIEF_MEMBER_DESC" to \c NO in
the config file). By default the brief descriptions become the first
sentence of the detailed descriptions
(but this can be changed by setting the \ref cfg_repeat_brief "REPEAT_BRIEF"
tag to \c NO). Both the brief and the detailed descriptions are optional
for the Qt style.
By default a JavaDoc style documentation block behaves the same way as a
Qt style documentation block. This is not according the JavaDoc specification
however, where the first sentence of the documentation block is automatically
treated as a brief description. To enable this behavior you should set
\ref cfg_javadoc_autobrief "JAVADOC_AUTOBRIEF" to YES in the configuration
file. If you enable this option and want to put a dot in the middle of a
sentence without ending it, you should put a backslash and a space after it.
Here is an example:
\verbatim
/** Brief description (e.g.\ using only a few words). Details follow. */
\endverbatim
Here is the same piece of code as shown above, this time documented using the
JavaDoc style and \ref cfg_javadoc_autobrief "JAVADOC_AUTOBRIEF" set to YES:
\include jdstyle.cpp
\htmlonly
Click <a href="$(DOXYGEN_DOCDIR)/examples/jdstyle/html/class_test.html">here</a>
for the corresponding HTML documentation that is generated by doxygen.
\endhtmlonly
Similarly, if one wishes the first sentence of a Qt style documentation
block to automatically be treated as a brief description, one may set
\ref cfg_qt_autobrief "QT_AUTOBRIEF" to YES in the configuration file.
\subsubsection structuralcommands Documentation at other places
So far we have assumed that the documentation blocks are always located \e in In the examples in the previous section the comment blocks were always located *in
\e front of the declaration or definition of a file, class or namespace or in front* of the declaration or definition of a file, class or namespace or *in
front or after one of its members. front* or *after* one of its members.
Although this is often comfortable, there may sometimes be reasons to put the Although this is often comfortable, there may sometimes be reasons to put the
documentation somewhere else. For documenting a file this is even documentation somewhere else. For documenting a file this is even
required since there is no such thing as "in front of a file". required since there is no such thing as "in front of a file".
...@@ -321,7 +331,7 @@ structural command inside the documentation block, which leads to some ...@@ -321,7 +331,7 @@ structural command inside the documentation block, which leads to some
duplication of information. So in practice you should \e avoid the use of duplication of information. So in practice you should \e avoid the use of
structural commands \e unless other requirements force you to do so. structural commands \e unless other requirements force you to do so.
Structural commands (like all other commands) start with a backslash Structural commands (like \ref cmd_intro "all other commands") start with a backslash
(<tt>\\</tt>), or an at-sign (<tt>\@</tt>) if you prefer JavaDoc style, (<tt>\\</tt>), or an at-sign (<tt>\@</tt>) if you prefer JavaDoc style,
followed by a command name and one or more parameters. followed by a command name and one or more parameters.
For instance, if you want to document the class \c Test in the example For instance, if you want to document the class \c Test in the example
...@@ -384,7 +394,7 @@ using structural commands: ...@@ -384,7 +394,7 @@ using structural commands:
in comment blocks which are place in front of a function. This is clearly in comment blocks which are place in front of a function. This is clearly
a case where the \\fn command is redundant and will only lead to problems. a case where the \\fn command is redundant and will only lead to problems.
\section pythonblocks Special documentation blocks in Python \subsection pythonblocks Comment blocks in Python
For Python there is a standard way of documenting the code using For Python there is a standard way of documenting the code using
so called documentation strings. Such strings are stored in \c __doc__ so called documentation strings. Such strings are stored in \c __doc__
...@@ -423,7 +433,7 @@ Go to the <a href="lists.html">next</a> section or return to the ...@@ -423,7 +433,7 @@ Go to the <a href="lists.html">next</a> section or return to the
<a href="index.html">index</a>. <a href="index.html">index</a>.
\endhtmlonly \endhtmlonly
\section vhdlblocks Special documentation blocks in VHDL \subsection vhdlblocks Comment blocks in VHDL
For VHDL a comment normally start with "--". Doxygen will extract comments For VHDL a comment normally start with "--". Doxygen will extract comments
starting with "--!". There are only two types of comment blocks in VHDL; starting with "--!". There are only two types of comment blocks in VHDL;
...@@ -449,7 +459,7 @@ config file. This will also affect a number of other settings. When they ...@@ -449,7 +459,7 @@ config file. This will also affect a number of other settings. When they
were not already set correctly doxygen will produce a warning telling which were not already set correctly doxygen will produce a warning telling which
settings where overruled. settings where overruled.
\section fortranblocks Special documentation blocks in Fortran \subsection fortranblocks Comment blocks in Fortran
When using doxygen for Fortran code you should When using doxygen for Fortran code you should
set \ref cfg_optimize_for_fortran "OPTIMIZE_FOR_FORTRAN" to \c YES. set \ref cfg_optimize_for_fortran "OPTIMIZE_FOR_FORTRAN" to \c YES.
...@@ -481,7 +491,7 @@ C> input parameter ...@@ -481,7 +491,7 @@ C> input parameter
end function A end function A
\endverbatim \endverbatim
\section tclblocks Documentation blocks in Tcl \subsection tclblocks Comment blocks in Tcl
Doxygen documentation can be included in normal Tcl comments. Doxygen documentation can be included in normal Tcl comments.
...@@ -548,4 +558,42 @@ Go to the <a href="lists.html">next</a> section or return to the ...@@ -548,4 +558,42 @@ Go to the <a href="lists.html">next</a> section or return to the
<a href="index.html">index</a>. <a href="index.html">index</a>.
\endhtmlonly \endhtmlonly
\section docstructure Anatomy of a comment block
The previous section focussed on how to make the comments in your code known
to doxygen, it explained the difference between a brief and a detailed description, and
the use of structural commands.
In this section we look at the contents of the comment block itself.
Doxygen supports various styles of formatting your comments.
The simplest form is to use plain text. This will appear as-is in the output
and is ideal for a short description.
For longer descriptions you often will find the
need for some more structure, like a block of verbatim text, a list, or a
simple table. For this doxygen supports the
<a href="http://daringfireball.net/projects/markdown/syntax">Markdown</a>
syntax, including parts of the
<a href="http://michelf.com/projects/php-markdown/extra/">Markdown Extra</a>
extension.
Markdown is designed to be very easy to read and write.
It's formatting is inspired by plain text mail.
Markdown works great for simple, generic formatting, like an introduction
page for your project. Doxygen also supports reading of markdown files
directly. See \ref markdown "here" for more details regards Markdown support.
For programming language specific formatting doxygen has two
forms of additional markup on top of Markdown formatting.
1. <a href="http://en.wikipedia.org/wiki/Javadoc">Javadoc</a> like markup.
See \ref cmd_intro "here" for a complete overview of all commands supported by doxygen.
2. <a href="http://en.wikipedia.org/wiki/C_Sharp_(programming_language)#XML_documentation_system">XML</a> markup
as specified in the C# standard. See \ref xmlcmds "here" for the XML commands supported by doxygen.
If this is still not enough doxygen also supports a \ref htmlcmds "subset" of
the <a href="http://en.wikipedia.org/wiki/HTML">HTML</a> markup language.
*/ */
...@@ -39,8 +39,8 @@ ...@@ -39,8 +39,8 @@
\fancyhead[RO]{\fancyplain{}{\bfseries\thepage}} \fancyhead[RO]{\fancyplain{}{\bfseries\thepage}}
\fancyfoot[LE]{\fancyplain{}{}} \fancyfoot[LE]{\fancyplain{}{}}
\fancyfoot[CE]{\fancyplain{}{}} \fancyfoot[CE]{\fancyplain{}{}}
\fancyfoot[RE]{\fancyplain{}{\bfseries\scriptsize Generated on Fri Dec 16 2011 21\-:40\-:27 for My Project by Doxygen }} \fancyfoot[RE]{\fancyplain{}{\bfseries\scriptsize Generated by Doxygen }}
\fancyfoot[LO]{\fancyplain{}{\bfseries\scriptsize Generated on Fri Dec 16 2011 21\-:40\-:27 for My Project by Doxygen }} \fancyfoot[LO]{\fancyplain{}{\bfseries\scriptsize Generated by Doxygen }}
\fancyfoot[CO]{\fancyplain{}{}} \fancyfoot[CO]{\fancyplain{}{}}
\fancyfoot[RO]{\fancyplain{}{}} \fancyfoot[RO]{\fancyplain{}{}}
%---------- Internal commands used in this style file ---------------- %---------- Internal commands used in this style file ----------------
......
/* The standard CSS for doxygen */
body, table, div, p, dl {
font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif;
font-size: 13px;
line-height: 1.3;
}
/* @group Heading Levels */
h1 {
font-size: 150%;
}
.title {
font-size: 150%;
font-weight: bold;
margin: 10px 2px;
}
h2 {
font-size: 120%;
}
h3 {
font-size: 100%;
}
dt {
font-weight: bold;
}
div.multicol {
-moz-column-gap: 1em;
-webkit-column-gap: 1em;
-moz-column-count: 3;
-webkit-column-count: 3;
}
p.startli, p.startdd, p.starttd {
margin-top: 2px;
}
p.endli {
margin-bottom: 0px;
}
p.enddd {
margin-bottom: 4px;
}
p.endtd {
margin-bottom: 2px;
}
/* @end */
caption {
font-weight: bold;
}
span.legend {
font-size: 70%;
text-align: center;
}
h3.version {
font-size: 90%;
text-align: center;
}
div.qindex, div.navtab{
background-color: #F1F1F1;
border: 1px solid #BDBDBD;
text-align: center;
}
div.qindex, div.navpath {
width: 100%;
line-height: 140%;
}
div.navtab {
margin-right: 15px;
}
/* @group Link Styling */
a {
color: #646494;
font-weight: normal;
text-decoration: none;
}
.contents a:visited {
color: #7474A4;
}
a:hover {
text-decoration: underline;
}
a.qindex {
font-weight: bold;
}
a.qindexHL {
font-weight: bold;
background-color: #B8B8B8;
color: #ffffff;
border: 1px double #A8A8A8;
}
.contents a.qindexHL:visited {
color: #ffffff;
}
a.el {
font-weight: bold;
}
a.elRef {
}
a.code, a.code:visited {
color: #4665A2;
}
a.codeRef, a.codeRef:visited {
color: #4665A2;
}
/* @end */
dl.el {
margin-left: -1cm;
}
.fragment {
font-family: monospace, fixed;
font-size: 105%;
}
pre.fragment {
border: 1px solid #D5D5D5;
background-color: #FCFCFC;
padding: 4px 6px;
margin: 4px 8px 4px 2px;
overflow: auto;
word-wrap: break-word;
font-size: 9pt;
line-height: 125%;
}
div.ah {
background-color: black;
font-weight: bold;
color: #ffffff;
margin-bottom: 3px;
margin-top: 3px;
padding: 0.2em;
border: solid thin #333;
border-radius: 0.5em;
-webkit-border-radius: .5em;
-moz-border-radius: .5em;
box-shadow: 2px 2px 3px #999;
-webkit-box-shadow: 2px 2px 3px #999;
-moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));
background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000);
}
div.groupHeader {
margin-left: 16px;
margin-top: 12px;
font-weight: bold;
}
div.groupText {
margin-left: 16px;
font-style: italic;
}
body {
background-color: #CCCCCC;
color: black;
margin: 0;
}
div.contents {
margin-bottom: 10px;
padding: 8px;
margin-left: auto;
margin-right: auto;
width: 800px;
background-color: white;
-moz-border-radius-bottomleft: 8px;
-moz-border-radius-bottomright: 8px;
/* firefox specific markup */
-moz-box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 5px;
/* webkit specific markup */
-webkit-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.15);
}
td.indexkey {
background-color: #F1F1F1;
font-weight: bold;
border: 1px solid #D5D5D5;
margin: 2px 0px 2px 0;
padding: 2px 10px;
white-space: nowrap;
vertical-align: top;
}
td.indexvalue {
background-color: #F1F1F1;
border: 1px solid #D5D5D5;
padding: 2px 10px;
margin: 2px 0px;
}
tr.memlist {
background-color: #F2F2F2;
}
p.formulaDsp {
text-align: center;
}
img.formulaDsp {
}
img.formulaInl {
vertical-align: middle;
}
div.center {
text-align: center;
margin-top: 0px;
margin-bottom: 0px;
padding: 0px;
}
div.center img {
border: 0px;
}
address.footer {
text-align: right;
padding-right: 12px;
background-color: #8080A0;
color: white;
}
img.footer {
border: 0px;
vertical-align: middle;
}
/* @group Code Colorization */
span.keyword {
color: #008000
}
span.keywordtype {
color: #604020
}
span.keywordflow {
color: #e08000
}
span.comment {
color: #800000
}
span.preprocessor {
color: #806020
}
span.stringliteral {
color: #002080
}
span.charliteral {
color: #008080
}
span.vhdldigit {
color: #ff00ff
}
span.vhdlchar {
color: #000000
}
span.vhdlkeyword {
color: #700070
}
span.vhdllogic {
color: #ff0000
}
blockquote {
background-color: #F9F9F9;
border-left: 2px solid #B8B8B8;
margin: 0 24px 0 4px;
padding: 0 12px 0 16px;
}
/* @end */
/*
.search {
color: #003399;
font-weight: bold;
}
form.search {
margin-bottom: 0px;
margin-top: 0px;
}
input.search {
font-size: 75%;
color: #000080;
font-weight: normal;
background-color: #e8eef2;
}
*/
td.tiny {
font-size: 75%;
}
.dirtab {
padding: 4px;
border-collapse: collapse;
border: 1px solid #BDBDBD;
}
th.dirtab {
background: #F1F1F1;
font-weight: bold;
}
hr {
height: 0px;
border: none;
border-top: 1px solid #7A7A7A;
}
hr.footer {
display: none;
}
/* @group Member Descriptions */
table.memberdecls {
border-spacing: 0px;
padding: 0px;
}
.mdescLeft, .mdescRight,
.memItemLeft, .memItemRight,
.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
background-color: #FAFAFA;
border: none;
margin: 4px;
padding: 1px 0 0 8px;
}
.mdescLeft, .mdescRight {
padding: 0px 8px 4px 8px;
color: #555;
}
.memItemLeft, .memItemRight, .memTemplParams {
border-top: 1px solid #D5D5D5;
}
.memItemLeft, .memTemplItemLeft {
white-space: nowrap;
}
.memItemRight {
width: 100%;
}
.memTemplParams {
color: #747474;
white-space: nowrap;
}
/* @end */
/* @group Member Details */
/* Styles for detailed member documentation */
.memtemplate {
font-size: 80%;
color: #747474;
font-weight: normal;
margin-left: 9px;
}
.memnav {
background-color: #F1F1F1;
border: 1px solid #BDBDBD;
text-align: center;
margin: 2px;
margin-right: 15px;
padding: 2px;
}
.mempage {
width: 100%;
}
.memitem {
padding: 0;
margin-bottom: 10px;
margin-right: 5px;
}
.memname {
white-space: nowrap;
font-weight: bold;
margin-left: 6px;
}
.memproto, dl.reflist dt {
border-top: 1px solid #C0C0C0;
border-left: 1px solid #C0C0C0;
border-right: 1px solid #C0C0C0;
padding: 6px 0px 6px 0px;
color: #3D3D3D;
font-weight: bold;
text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
/* opera specific markup */
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
border-top-right-radius: 8px;
border-top-left-radius: 8px;
/* firefox specific markup */
-moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
-moz-border-radius-topright: 8px;
-moz-border-radius-topleft: 8px;
/* webkit specific markup */
-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
-webkit-border-top-right-radius: 8px;
-webkit-border-top-left-radius: 8px;
background-image:url('nav_f.png');
background-repeat:repeat-x;
background-color: #EAEAEA;
}
.memdoc, dl.reflist dd {
border-bottom: 1px solid #C0C0C0;
border-left: 1px solid #C0C0C0;
border-right: 1px solid #C0C0C0;
padding: 2px 5px;
background-color: #FCFCFC;
border-top-width: 0;
/* opera specific markup */
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
/* firefox specific markup */
-moz-border-radius-bottomleft: 8px;
-moz-border-radius-bottomright: 8px;
-moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F9F9F9 95%, #F2F2F2);
/* webkit specific markup */
-webkit-border-bottom-left-radius: 8px;
-webkit-border-bottom-right-radius: 8px;
-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F9F9F9), to(#F2F2F2));
}
dl.reflist dt {
padding: 5px;
}
dl.reflist dd {
margin: 0px 0px 10px 0px;
padding: 5px;
}
.paramkey {
text-align: right;
}
.paramtype {
white-space: nowrap;
}
.paramname {
color: #602020;
white-space: nowrap;
}
.paramname em {
font-style: normal;
}
.params, .retval, .exception, .tparams {
border-spacing: 6px 2px;
}
.params .paramname, .retval .paramname {
font-weight: bold;
vertical-align: top;
}
.params .paramtype {
font-style: italic;
vertical-align: top;
}
.params .paramdir {
font-family: "courier new",courier,monospace;
vertical-align: top;
}
/* @end */
/* @group Directory (tree) */
/* for the tree view */
.ftvtree {
font-family: sans-serif;
margin: 0px;
}
/* these are for tree view when used as main index */
.directory {
font-size: 9pt;
font-weight: bold;
margin: 5px;
}
.directory h3 {
margin: 0px;
margin-top: 1em;
font-size: 11pt;
}
/*
The following two styles can be used to replace the root node title
with an image of your choice. Simply uncomment the next two styles,
specify the name of your image and be sure to set 'height' to the
proper pixel height of your image.
*/
/*
.directory h3.swap {
height: 61px;
background-repeat: no-repeat;
background-image: url("yourimage.gif");
}
.directory h3.swap span {
display: none;
}
*/
.directory > h3 {
margin-top: 0;
}
.directory p {
margin: 0px;
white-space: nowrap;
}
.directory div {
display: none;
margin: 0px;
}
.directory img {
vertical-align: -30%;
}
/* these are for tree view when not used as main index */
.directory-alt {
font-size: 100%;
font-weight: bold;
}
.directory-alt h3 {
margin: 0px;
margin-top: 1em;
font-size: 11pt;
}
.directory-alt > h3 {
margin-top: 0;
}
.directory-alt p {
margin: 0px;
white-space: nowrap;
}
.directory-alt div {
display: none;
margin: 0px;
}
.directory-alt img {
vertical-align: -30%;
}
/* @end */
div.dynheader {
margin-top: 8px;
}
address {
font-style: normal;
color: #464646;
}
table.doxtable {
border-collapse:collapse;
margin-top: 4px;
margin-bottom: 4px;
}
table.doxtable td, table.doxtable th {
border: 1px solid #4A4A4A;
padding: 3px 7px 2px;
}
table.doxtable th {
background-color: #5B5B5B;
color: #FFFFFF;
font-size: 110%;
padding-bottom: 4px;
padding-top: 5px;
text-align:left;
}
table.fieldtable {
width: 100%;
margin-bottom: 10px;
border: 1px solid #C0C0C0;
border-spacing: 0px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
-moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
-webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
}
.fieldtable td, .fieldtable th {
padding: 3px 7px 2px;
}
.fieldtable td.fieldtype, .fieldtable td.fieldname {
white-space: nowrap;
border-right: 1px solid #C0C0C0;
border-bottom: 1px solid #C0C0C0;
vertical-align: top;
}
.fieldtable td.fielddoc {
border-bottom: 1px solid #C0C0C0;
width: 100%;
}
.fieldtable tr:last-child td {
border-bottom: none;
}
.fieldtable th {
background-image:url('nav_f.png');
background-repeat:repeat-x;
background-color: #EAEAEA;
font-size: 90%;
color: #3D3D3D;
padding-bottom: 4px;
padding-top: 5px;
text-align:left;
-moz-border-radius-topleft: 4px;
-moz-border-radius-topright: 4px;
-webkit-border-top-left-radius: 4px;
-webkit-border-top-right-radius: 4px;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
border-bottom: 1px solid #C0C0C0;
}
.tabsearch {
top: 0px;
left: 10px;
height: 36px;
background-image: url('tab_b.png');
z-index: 101;
overflow: hidden;
font-size: 13px;
}
.navpath ul
{
font-size: 11px;
background-image:url('tab_b.png');
background-repeat:repeat-x;
height:30px;
line-height:30px;
color:#ABABAB;
border:solid 1px #D3D3D3;
overflow:hidden;
margin:0px;
padding:0px;
}
.navpath li
{
list-style-type:none;
float:left;
padding-left:10px;
padding-right:15px;
background-image:url('bc_s.png');
background-repeat:no-repeat;
background-position:right;
color:#595959;
}
.navpath li.navelem a
{
height:32px;
display:block;
text-decoration: none;
outline: none;
}
.navpath li.navelem a:hover
{
color:#929292;
}
.navpath li.footer
{
list-style-type:none;
float:right;
padding-left:10px;
padding-right:15px;
background-image:none;
background-repeat:no-repeat;
background-position:right;
color:#595959;
font-size: 8pt;
}
div.summary
{
float: right;
font-size: 8pt;
padding-right: 5px;
width: 50%;
text-align: right;
}
div.summary a
{
white-space: nowrap;
}
div.ingroups
{
margin-left: 5px;
font-size: 8pt;
padding-left: 5px;
width: 50%;
text-align: left;
}
div.ingroups a
{
white-space: nowrap;
}
div.header
{
background-image:url('nav_h.png');
background-repeat:repeat-x;
background-color: #FAFAFA;
border-bottom: 1px solid #D5D5D5;
margin-left: auto;
margin-right: auto;
width: 800px;
padding-left: 8px;
padding-right: 8px;
/* firefox specific markup */
-moz-box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 5px;
/* webkit specific markup */
-webkit-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.15);
}
div.headertitle
{
padding: 5px 5px 5px 7px;
}
dl
{
padding: 0 0 0 10px;
}
dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug
{
border-left:4px solid;
padding: 0 0 0 6px;
}
dl.note
{
border-color: #D0C000;
}
dl.warning, dl.attention
{
border-color: #FF0000;
}
dl.pre, dl.post, dl.invariant
{
border-color: #00D000;
}
dl.deprecated
{
border-color: #505050;
}
dl.todo
{
border-color: #00C0E0;
}
dl.test
{
border-color: #3030E0;
}
dl.bug
{
border-color: #C08050;
}
#projectlogo
{
text-align: center;
vertical-align: bottom;
border-collapse: separate;
}
#projectlogo img
{
border: 0px none;
}
#projectname
{
font: 300% Tahoma, Arial,sans-serif;
margin: 0px;
padding: 2px 0px;
}
#projectbrief
{
font: 120% Tahoma, Arial,sans-serif;
margin: 0px;
padding: 0px;
}
#projectnumber
{
font: 50% Tahoma, Arial,sans-serif;
margin: 0px;
padding: 0px;
}
#titlearea
{
padding: 0px;
margin: 0px;
width: 100%;
border-bottom: 1px solid #848484;
}
.image
{
text-align: center;
}
.dotgraph
{
text-align: center;
}
.mscgraph
{
text-align: center;
}
.caption
{
font-weight: bold;
}
div.zoom
{
border: 1px solid #AFAFAF;
}
dl.citelist {
margin-bottom:50px;
}
dl.citelist dt {
color:#545454;
float:left;
font-weight:bold;
margin-right:10px;
padding:5px;
}
dl.citelist dd {
margin:2px 0;
padding:5px 0;
}
@media print
{
#top { display: none; }
#side-nav { display: none; }
#nav-path { display: none; }
body { overflow:visible; }
h1, h2, h3, h4, h5, h6 { page-break-after: avoid; }
.summary { display: none; }
.memitem { page-break-inside: avoid; }
#doc-content
{
margin-left:0 !important;
height:auto !important;
width:auto !important;
overflow:inherit;
display:inline;
}
pre.fragment
{
overflow: visible;
text-wrap: unrestricted;
white-space: -moz-pre-wrap; /* Moz */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
white-space: pre-wrap; /* CSS3 */
word-wrap: break-word; /* IE 5.5+ */
}
}
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
\usepackage{graphicx} \usepackage{graphicx}
\usepackage{multicol} \usepackage{multicol}
\usepackage{float} \usepackage{float}
\usepackage{geometry}
\usepackage{listings} \usepackage{listings}
\usepackage{color} \usepackage{color}
\usepackage{ifthen} \usepackage{ifthen}
...@@ -79,7 +80,7 @@ Written by Dimitri van Heesch\\[2ex] ...@@ -79,7 +80,7 @@ Written by Dimitri van Heesch\\[2ex]
\chapter{Installation}\label{install}\hypertarget{install}{}\input{install} \chapter{Installation}\label{install}\hypertarget{install}{}\input{install}
\chapter{Getting Started}\label{starting}\hypertarget{starting}{}\input{starting} \chapter{Getting Started}\label{starting}\hypertarget{starting}{}\input{starting}
\chapter{Documenting the code}\label{docblocks}\hypertarget{docblocks}{}\input{docblocks} \chapter{Documenting the code}\label{docblocks}\hypertarget{docblocks}{}\input{docblocks}
\chapter{Lists}\label{lists}\hypertarget{lists}{}\input{lists} \chapter{Markdown}\label{markdown}\hypertarget{markdown}{}\input{markdown}
\chapter{Grouping}\label{grouping}\hypertarget{grouping}{}\input{grouping} \chapter{Grouping}\label{grouping}\hypertarget{grouping}{}\input{grouping}
\chapter{Including Formulas}\label{formulas}\hypertarget{formulas}{}\input{formulas} \chapter{Including Formulas}\label{formulas}\hypertarget{formulas}{}\input{formulas}
\chapter{Graphs and diagrams}\label{diagrams}\hypertarget{diagrams}{}\input{diagrams} \chapter{Graphs and diagrams}\label{diagrams}\hypertarget{diagrams}{}\input{diagrams}
......
...@@ -19,25 +19,26 @@ ...@@ -19,25 +19,26 @@
\addindex features \addindex features
<UL> <UL>
<li>Requires very little overhead from the writer of the documentation. <li>Requires very little overhead from the writer of the documentation.
Plain text will do, but for more fancy or structured output HTML tags Plain text will do, Markdown is support, and for more fancy or
and/or some of doxygen's special commands can be used. structured output HTML tags and/or some of doxygen's special commands
<li>Cross platform: works on Windows and many Unices (including Linux and can be used.
<li>Cross platform: works on Windows and many Unix flavors (including Linux and
MacOSX). MacOSX).
<li>Indexes, organizes and generates browsable and cross-referenced <li>Indexes, organizes and generates browsable and cross-referenced
output even from undocumented code. output even from undocumented code.
<li>Generates structured XML output for parsed sources, which can be <li>Generates structured XML output for parsed sources, which can be
used by external tools. used by external tools.
<li>Supports C/C++, Java, (Corba and Microsoft) Java, Python, VHDL, PHP <li>Supports C/C++, Java, (Corba and Microsoft) Java, Python, VHDL, PHP
IDL, C#, Objective-C 2.0, and to some extent D and Fortran sources. IDL, C#, Fortran, TCL, Objective-C 2.0, and to some extent D sources.
<li>Supports documentation of files, namespaces, packages, classes, <li>Supports documentation of files, namespaces, packages, classes,
structs, unions, templates, variables, functions, typedefs, enums and structs, unions, templates, variables, functions, typedefs, enums and
defines. defines.
<li>JavaDoc (1.1), qdoc3 (partially), and ECMA-334 (C# spec.) compatible. <li>JavaDoc (1.1), qdoc3 (partially), and ECMA-334 (C# spec.) compatible.
<li>Comes with a GUI frontend (Doxywizard) to ease editing the options and run doxygen. <li>Comes with a GUI frontend (Doxywizard) to ease editing the options and
The GUI is available on Windows, Linux, and MacOSX. run doxygen. The GUI is available on Windows, Linux, and MacOSX.
<li>Automatically generates class and collaboration diagrams in HTML (as clickable <li>Automatically generates class and collaboration diagrams in HTML (as clickable
image maps) and \f$\mbox{\LaTeX}\f$ (as Encapsulated PostScript images). image maps) and \f$\mbox{\LaTeX}\f$ (as Encapsulated PostScript images).
<li>Uses the dot tool of the Graphviz tool kit to generate <li>Uses the `dot` tool of the Graphviz tool kit to generate
include dependency graphs, collaboration diagrams, call graphs, directory structure include dependency graphs, collaboration diagrams, call graphs, directory structure
graphs, and graphical class hierarchy graphs. graphs, and graphical class hierarchy graphs.
<li>Allows grouping of entities in modules and creating a hierarchy of modules. <li>Allows grouping of entities in modules and creating a hierarchy of modules.
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* input used in their production; they are not affected by this license. * input used in their production; they are not affected by this license.
* *
*/ */
/*! \mainpage /*! \mainpage Doxygen Manual
\if logo_on \if logo_on
<center> <center>
\htmlonly \htmlonly
...@@ -44,7 +44,7 @@ It can help you in three ways: ...@@ -44,7 +44,7 @@ It can help you in three ways:
You can also visualize the relations between the various elements You can also visualize the relations between the various elements
by means of include dependency graphs, inheritance diagrams, by means of include dependency graphs, inheritance diagrams,
and collaboration diagrams, which are all generated automatically. and collaboration diagrams, which are all generated automatically.
<li> You can even `abuse' doxygen for creating normal documentation (as I did <li> You can also use doxygen for creating normal documentation (as I did
for this manual). for this manual).
</ol> </ol>
...@@ -65,7 +65,7 @@ The first part forms a user manual: ...@@ -65,7 +65,7 @@ The first part forms a user manual:
documentation quickly. documentation quickly.
<li>Section \ref docblocks demonstrates the various ways that code can <li>Section \ref docblocks demonstrates the various ways that code can
be documented. be documented.
<li>Section \ref lists show various ways to create lists. <li>Section \ref markdown show the Markdown formatting supported by doxygen.
<li>Section \ref grouping shows how to group things together. <li>Section \ref grouping shows how to group things together.
<li>Section \ref formulas shows how to insert formulas in the documentation. <li>Section \ref formulas shows how to insert formulas in the documentation.
<li>Section \ref diagrams describes the diagrams and graphs that doxygen can generate. <li>Section \ref diagrams describes the diagrams and graphs that doxygen can generate.
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
\addindex installation \addindex installation
First go to the First go to the
<a href="http://www.doxygen.org/download.html">download</a> page <a href="http://www.doxygen.org/download.html">download</a> page
\latexonly({\tt http://www.doxygen.org/download.html})\endlatexonly
to get the latest distribution, if you did not have it already. to get the latest distribution, if you did not have it already.
This section is divided into the following sections: This section is divided into the following sections:
...@@ -45,7 +44,6 @@ following to build the executable: ...@@ -45,7 +44,6 @@ following to build the executable:
\addindex strip \addindex strip
<li>In order to generate a Makefile for your platform, you need <li>In order to generate a Makefile for your platform, you need
<a href="http://www.perl.com/">perl</a> <a href="http://www.perl.com/">perl</a>
\latexonly(see {\tt http://www.perl.com/})\endlatexonly.
\addindex perl \addindex perl
<li>The configure script assume the availability of standard UNIX tools such <li>The configure script assume the availability of standard UNIX tools such
as sed, date, find, uname, mv, cp, cat, echo, tr, cd, and rm. as sed, date, find, uname, mv, cp, cat, echo, tr, cd, and rm.
...@@ -57,17 +55,14 @@ tools should be installed. ...@@ -57,17 +55,14 @@ tools should be installed.
<ul> <ul>
<li>Qt Software's GUI toolkit <li>Qt Software's GUI toolkit
<a href="http://qt.nokia.com/">Qt</A> <a href="http://qt.nokia.com/">Qt</A>
\latexonly(see {\tt http://qt.nokia.com/})\endlatexonly
\addindex Qt \addindex Qt
version 4.3 or higher. version 4.3 or higher.
This is needed to build the GUI front-end doxywizard. This is needed to build the GUI front-end doxywizard.
<li>A \f$\mbox{\LaTeX}\f$ distribution: for instance <li>A \f$\mbox{\LaTeX}\f$ distribution: for instance
<a href="http://www.tug.org/interest.html#free">teTeX 1.0</a> <a href="http://www.tug.org/interest.html#free">teTeX 1.0</a>
\latexonly (see {\tt http://www.tug.org/interest.html\#free})\endlatexonly.
This is needed for generating LaTeX, Postscript, and PDF output. This is needed for generating LaTeX, Postscript, and PDF output.
<li><a href="http://www.graphviz.org/"> <li><a href="http://www.graphviz.org/">
the Graph visualization toolkit version 1.8.10 or higher</a> the Graph visualization toolkit version 1.8.10 or higher</a>
\latexonly (see {\tt http://www.graphviz.org/})\endlatexonly.
Needed for the include dependency graphs, Needed for the include dependency graphs,
the graphical inheritance graphs, and the collaboration graphs. the graphical inheritance graphs, and the collaboration graphs.
If you compile graphviz yourself, make sure you do include If you compile graphviz yourself, make sure you do include
...@@ -83,18 +78,14 @@ tools should be installed. ...@@ -83,18 +78,14 @@ tools should be installed.
Compilation is now done by performing the following steps: Compilation is now done by performing the following steps:
<ol> <ol>
<li> Unpack the archive, unless you already have done that: <li>Unpack the archive, unless you already have done that:
\verbatim gunzip doxygen-$VERSION.src.tar.gz # uncompress the archive
gunzip doxygen-$VERSION.src.tar.gz # uncompress the archive tar xf doxygen-$VERSION.src.tar # unpack it
tar xf doxygen-$VERSION.src.tar # unpack it
\endverbatim
<li>Run the configure script: <li>Run the configure script:
\verbatim sh ./configure
sh ./configure
\endverbatim
The script tries to determine the platform you use, the make tool The script tries to determine the platform you use, the make tool
(which \e must be GNU make) and the perl (which \e must be GNU make) and the perl
...@@ -103,9 +94,7 @@ Compilation is now done by performing the following steps: ...@@ -103,9 +94,7 @@ Compilation is now done by performing the following steps:
To override the auto detected platform and compiler you can run To override the auto detected platform and compiler you can run
configure as follows: configure as follows:
\verbatim configure --platform platform-type
configure --platform platform-type
\endverbatim
See the <code>PLATFORMS</code> file for a list of possible platform See the <code>PLATFORMS</code> file for a list of possible platform
options. options.
...@@ -114,21 +103,15 @@ Compilation is now done by performing the following steps: ...@@ -114,21 +103,15 @@ Compilation is now done by performing the following steps:
front-end, you should run the configure script with front-end, you should run the configure script with
the <code>--with-doxywizard</code> option: the <code>--with-doxywizard</code> option:
\verbatim configure --with-doxywizard
configure --with-doxywizard
\endverbatim
For an overview of other configuration options use For an overview of other configuration options use
\verbatim configure --help
configure --help
\endverbatim
<li>Compile the program by running make: <li>Compile the program by running make:
\verbatim make
make
\endverbatim
The program should compile without problems and the binaries The program should compile without problems and the binaries
(<code>doxygen</code> and optionally <code>doxywizard</code>) (<code>doxygen</code> and optionally <code>doxywizard</code>)
...@@ -136,9 +119,7 @@ Compilation is now done by performing the following steps: ...@@ -136,9 +119,7 @@ Compilation is now done by performing the following steps:
<li>Optional: Generate the user manual. <li>Optional: Generate the user manual.
\verbatim make docs
make docs
\endverbatim
To let doxygen generate the HTML documentation. To let doxygen generate the HTML documentation.
...@@ -152,9 +133,7 @@ Compilation is now done by performing the following steps: ...@@ -152,9 +133,7 @@ Compilation is now done by performing the following steps:
(you will need <code>pdflatex</code>, <code>makeindex</code>, and (you will need <code>pdflatex</code>, <code>makeindex</code>, and
<code>egrep</code> for this). <code>egrep</code> for this).
\verbatim make pdf
make pdf
\endverbatim
The PDF manual <code>doxygen_manual.pdf</code> will be located The PDF manual <code>doxygen_manual.pdf</code> will be located
in the latex directory of the distribution. Just in the latex directory of the distribution. Just
...@@ -168,10 +147,8 @@ Compilation is now done by performing the following steps: ...@@ -168,10 +147,8 @@ Compilation is now done by performing the following steps:
to install doxygen. If you downloaded the binary distribution for UNIX, to install doxygen. If you downloaded the binary distribution for UNIX,
type: type:
\verbatim ./configure
./configure make install
make install
\endverbatim
Binaries are installed into the directory <code>\<prefix\>/bin</code>. Binaries are installed into the directory <code>\<prefix\>/bin</code>.
Use <code>make install_docs</code> to install the Use <code>make install_docs</code> to install the
...@@ -204,14 +181,13 @@ directory pointed to by QTDIR on some systems ...@@ -204,14 +181,13 @@ directory pointed to by QTDIR on some systems
libs are in /usr/lib). libs are in /usr/lib).
The solution: go to the root of the doxygen distribution and do: The solution: go to the root of the doxygen distribution and do:
\verbatim
mkdir qt mkdir qt
cd qt cd qt
ln -s your-qt-include-dir-here include ln -s your-qt-include-dir-here include
ln -s your-qt-lib-dir-here lib ln -s your-qt-lib-dir-here lib
ln -s your-qt-bin-dir-here bin ln -s your-qt-bin-dir-here bin
export QTDIR=$PWD export QTDIR=$PWD
\endverbatim
If you have a csh-like shell you should use <code>setenv QTDIR \$PWD</code> If you have a csh-like shell you should use <code>setenv QTDIR \$PWD</code>
instead of the <code>export</code> command above. instead of the <code>export</code> command above.
...@@ -239,24 +215,23 @@ config file). ...@@ -239,24 +215,23 @@ config file).
<b>HP-UX \& Digital UNIX problems</b> <b>HP-UX \& Digital UNIX problems</b>
If you are compiling for HP-UX with aCC and you get this error: If you are compiling for HP-UX with aCC and you get this error:
\verbatim
/opt/aCC/lbin/ld: Unsatisfied symbols: /opt/aCC/lbin/ld: Unsatisfied symbols:
alloca (code) alloca (code)
\endverbatim
then you should (according to Anke Selig) edit <code>ce_parse.cpp</code> then you should (according to Anke Selig) edit <code>ce_parse.cpp</code>
and replace and replace
\verbatim
extern "C" { extern "C" {
void *alloca (unsigned int); void *alloca (unsigned int);
}; };
\endverbatim
with with
\verbatim
#include <alloca.h> #include <alloca.h>
\endverbatim
If that does not help, try removing <code>ce_parse.cpp</code> and let If that does not help, try removing <code>ce_parse.cpp</code> and let
bison rebuild it (this worked for me). bison rebuild it (this worked for me).
If you are compiling for Digital UNIX, the same problem can be solved If you are compiling for Digital UNIX, the same problem can be solved
(according to Barnard Schmallhof) by replacing the following in (according to Barnard Schmallhof) by replacing the following in
...@@ -308,7 +283,7 @@ not have access to a Solaris machine with this compiler. With GNU compiler ...@@ -308,7 +283,7 @@ not have access to a Solaris machine with this compiler. With GNU compiler
it does work and installing Sun patch 111679-13 has also been reported it does work and installing Sun patch 111679-13 has also been reported
as a way to fix the problem. as a way to fix the problem.
when configuring with <code>--static</code> I got: when configuring with `--static` I got:
\verbatim \verbatim
Undefined first referenced Undefined first referenced
...@@ -318,13 +293,11 @@ dlsym /usr/lib/libc.a(nss_deffinder.o) ...@@ -318,13 +293,11 @@ dlsym /usr/lib/libc.a(nss_deffinder.o)
dlopen /usr/lib/libc.a(nss_deffinder.o) dlopen /usr/lib/libc.a(nss_deffinder.o)
\endverbatim \endverbatim
Manually adding <code>-Bdynamic</code> after the target rule in Manually adding `-Bdynamic` after the target rule in
<code>Makefile.doxygen</code> will fix this: `Makefile.doxygen` will fix this:
\verbatim $(TARGET): $(OBJECTS) $(OBJMOC)
$(TARGET): $(OBJECTS) $(OBJMOC) $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) -Bdynamic
$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) -Bdynamic
\endverbatim
<b>GCC compiler problems</b> <b>GCC compiler problems</b>
...@@ -456,11 +429,9 @@ Here is what is required: ...@@ -456,11 +429,9 @@ Here is what is required:
<li>The GNU tools flex, bison, and sed. <li>The GNU tools flex, bison, and sed.
To get these working on Windows you should install the To get these working on Windows you should install the
<a href="http://sources.redhat.com/cygwin/">cygwin tools</a> <a href="http://sources.redhat.com/cygwin/">cygwin tools</a>
\latexonly(see {\tt http://sources.redhat.com/cygwin/})\endlatexonly
Alternatively, you can also choose to Alternatively, you can also choose to
download only a <a href="http://www.doxygen.org/dl/cygwin_tools.zip">small subset</a> download only a <a href="http://www.doxygen.org/dl/cygwin_tools.zip">small subset</a>
\latexonly(see {\tt http://www.doxygen.org/dl/cygwin\_tools.zip})\endlatexonly
of the cygwin tools that I put together just to compile doxygen. of the cygwin tools that I put together just to compile doxygen.
As a third alternative one could use the GNUWin32 tools that can be As a third alternative one could use the GNUWin32 tools that can be
...@@ -648,7 +619,6 @@ features: ...@@ -648,7 +619,6 @@ features:
<li><a href="http://www.graphviz.org/"> <li><a href="http://www.graphviz.org/">
the Graph visualization toolkit version 1.8.10</a><br> the Graph visualization toolkit version 1.8.10</a><br>
\latexonly(see {\tt http://www.graphviz.org/})\endlatexonly.
Needed for the include dependency graphs, the graphical inheritance graphs, Needed for the include dependency graphs, the graphical inheritance graphs,
and the collaboration graphs. and the collaboration graphs.
</ul> </ul>
......
...@@ -4,15 +4,16 @@ Doxygen provides a number of ways to create lists of items. ...@@ -4,15 +4,16 @@ Doxygen provides a number of ways to create lists of items.
<b>Using dashes</b> <b>Using dashes</b>
By putting a number of column-aligned minus (-) signs at the start of a By putting a number of column-aligned minus (-) signs at the start of a
line, a bullet list will automatically be generated. Instead of the minus line, a bullet list will automatically be generated. Instead of the minus
sign also plus (+) or asterix (\*) can be used. sign also plus (+) or asterix (\*) can be used.
Numbered lists can also be generated by using a minus followed by a hash Numbered lists can also be generated by using a minus followed by a hash
or by using a number followed by a dot. or by using a number followed by a dot.
Nesting of lists is allowed and is based on indentation of the items.<p>
Here is an example:
Nesting of lists is allowed and is based on indentation of the items.<p>
Here is an example:
\verbatim \verbatim
/*! /*!
* A list of events: * A list of events:
......
/******************************************************************************
*
*
*
* Copyright (C) 1997-2011 by Dimitri van Heesch.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation under the terms of the GNU General Public License is hereby
* granted. No representations are made about the suitability of this software
* for any purpose. It is provided "as is" without express or implied warranty.
* See the GNU General Public License for more details.
*
* Documents produced by Doxygen are derivative works derived from the
* input used in their production; they are not affected by this license.
*
*/
/*! \page markdown Markdown support
Table of contents
- \ref markdown_std
- \ref md_para
- \ref md_headers
- \ref md_blockquotes
- \ref md_lists
- \ref md_codeblock
- \ref md_rulers
- \ref md_emphasis
- \ref md_codespan
- \ref md_links
- \ref md_inlinelinks
- \ref md_reflinks
- \ref md_images
- \ref md_autolink
- \ref markdown_extra
- \ref md_tables
- \ref md_fenced
- \ref md_header_id
- \ref markdown_dox
- \ref md_page_header
- \ref md_html_blocks
- \ref mddox_code_blocks
- \ref mddox_code_spans
- \ref mddox_lists
- \ref mddox_stars
- \ref mddox_limits
- \ref markdown_debug
[Markdown] support
was introduced in doxygen version 1.8.0. It is a plain text formatting
syntax written by John Gruber, with the following underlying design goal:
> The design goal for Markdown’s formatting syntax is to
> make it as readable as possible. The idea is that a Markdown-formatted
> document should be publishable as-is, as plain text, without
> looking like it’s been marked up with tags or formatting instructions.
> While Markdown’s syntax has been influenced by several existing
> text-to-HTML filters, the single biggest source of inspiration
> for Markdown’s syntax is the format of plain text email.
In the \ref markdown_std "next section" the standard markdown features
are briefly discussed. The reader is referred to the [Markdown site][markdown]
for more details.
Some enhancements were made, for instance [PHP Markdown Extra][mdextra], and
[GitHub flavored Markdown][github]. The section \ref markdown_extra discusses
the extensions that doxygen supports.
Finally section \ref markdown_dox discusses some specifics for doxygen's
implementation of the Markdown standard.
[markdown]: http://daringfireball.net/projects/markdown
[mdextra]: http://michelf.com/projects/php-markdown/extra/
[github]: http://github.github.com/github-flavored-markdown/
\section markdown_std Standard Markdown
\subsection md_para Paragraphs
Even before doxygen had Markdown support it supported the same way
of paragraph handling as Markdown: to make a paragraph you just separate
consecutive lines of text by one or more blank lines.
An example:
Here is text for one paragraph.
We continue with more text in another paragraph.
\subsection md_headers Headers
Just like Markdown, doxygen supports two types of headers
Level 1 or 2 headers can be made as the follows
This is an level 1 header
=========================
This is an level 2 header
-------------------------
A header is followed by a line containing only ='s or -'s.
Note that the exact amount of ='s or -'s is not important.
Alternatively, you can use #'s at the start of a line to make a header.
The number of #'s at the start of the line determines the level (up to 6 levels are supported).
You can end a header by any number of #'s.
Here is an example:
# This is a level 1 header
### This is level 3 header #######
\subsection md_blockquotes Block quotes
Block quotes can be created by starting each line with one or more >'s,
similar to what is used in text-only emails.
> This is a block quote
> spanning multiple lines
Lists and code blocks (see below) can appear inside a quote block.
Quote blocks can also be nested.
Note that doxygen requires that you put a space after the (last) > character
to avoid false positives, i.e. when writing
0 if OK\n
>1 if NOK
the second line will not seen as a block quote.
\subsection md_lists Lists
Simple bullet lists can be made by starting a line with -, +, or *.
- Item 1
More text for this item.
- Item 2
+ nested list item.
+ another nested item.
- Item 3
List items can span multiple paragraphs (if each paragraph starts with
the proper indentation) and lists can be nested.
You can also make a numbered list like so
1. First item.
2. Second item.
\subsection md_codeblock Code Blocks
Preformatted verbatim blocks can be created by indenting
each line in a block of text by at least 4 extra spaces
This a normal paragraph
This is a code block
We continue with a normal paragraph again.
Doxygen will remove the mandatory indentation from the code block.
Note that you cannot start a code block in the middle of a paragraph
(i.e. the line preceding the code block must be empty).
See section \ref mddox_code_blocks for more info how doxygen handles
indentation as this is slightly different than standard Markdown.
\subsection md_rulers Horizontal Rulers
A horizontal ruler will be produced for lines containing at least three or more
hyphens, asterisks, or underscores. The line may also include any amount of whitespace.
Examples:
- - -
______
Note that using asterisks in comment blocks does not work. See
\ref mddox_stars for details.
\subsection md_emphasis Emphasis
To emphasize a text fragment you start and end the fragment with an underscore or star.
Using two stars or underscores will produce strong emphasis.
Examples:
*single asterisks*
_single underscores_
**double asterisks**
__double underscores__
Note that unlike standard Markdown, doxygen will not touch internal underscores or
stars, so the following will appear as-is:
a_nice_identifier
\subsection md_codespan code spans
To indicate a span of code, you should wrap it in backticks (`). Unlike code blocks,
code spans appear inline in a paragraph. An example:
Use the `printf()` function.
To show a literal backtick inside a code span use double backticks, i.e.
To assign the output of command `ls` to `var` use ``var=`ls```.
See section \ref mddox_code_spans for more info how doxygen handles
code spans slightly different than standard Markdown.
\subsection md_links Links
Doxygen supports both styles of make links defined by Markdown: *inline* and *reference*.
For both styles the link definition starts with the link text delimited by [square
brackets].
\subsubsection md_inlinelinks Inline Links
For an inline link the link text is followed by a URL and an optional link title which
together are enclosed in a set of regular parenthesis.
The link title itself is surrounded by quotes.
Examples:
[The link text](http://example.net/)
[The link text](http://example.net/ "Link title")
[The link text](/relative/path/to/index.html "Link title")
[The link text](somefile.html)
In addition doxygen provides a similar way to link a documented entity:
[The link text](@ref MyClass)
\subsubsection md_reflinks Reference Links
Instead of putting the URL inline, you can also define the link separately
and then refer to it from within the text.
The link definition looks as follows:
[link name]: http://www.example.com "Optional title"
Instead of double quotes also single quotes or parenthesis can
be used for the title part.
Once defined, the link looks as follows
[link text][link name]
If the link text and name are the same, also
[link name][]
or even
[link name]
can be used to refer to the link.
Note that the link name matching is not case sensitive
as is shown in the following example:
I get 10 times more traffic from [Google] than from
[Yahoo] or [MSN].
[google]: http://google.com/ "Google"
[yahoo]: http://search.yahoo.com/ "Yahoo Search"
[msn]: http://search.msn.com/ "MSN Search"
Link definitions will not be visible in the output.
Like for inline links doxygen also supports \@ref inside a link definition:
[myclass]: @ref MyClass "My class"
\subsection md_images Images
Markdown syntax for images is similar to that for links.
The only difference is an additional ! before the link text.
Examples:
![Caption text](/path/to/img.jpg)
![Caption text](/path/to/img.jpg "Image title")
![Caption text][img def]
![img def]
[img def]: /path/to/img.jpg "Optional Title"
Also here you can use \@ref to link to an image:
![Caption text](@ref image.png)
![img def]
[img def]: @ref image.png "Caption text"
The caption text is optional.
\subsection md_autolink Automatic Linking
To create a link to an URL or e-mail address Markdown supports the following
syntax:
<http://www.example.com>
<address@example.com>
Note that doxygen will also produce the links without the angle brackets.
\section markdown_extra Markdown Extensions
\subsection md_tables Tables
Of the features defined by "Markdown Extra" is support for
<a href="http://michelf.com/projects/php-markdown/extra/#table">simple tables</a>:
A table consists of a header line, a separator line, and at least one
row line. Table columns are separated by the pipe (!) character.
Here is an example:
First Header | Second Header
------------- | -------------
Content Cell | Content Cell
Content Cell | Content Cell
which will produce the following table:
First Header | Second Header
------------- | -------------
Content Cell | Content Cell
Content Cell | Content Cell
Column alignment can be controlled via one or two colons
at the header separator line:
| Right | Center | Left |
| ----: | :----: | :---- |
| 10 | 10 | 10 |
| 1000 | 1000 | 1000 |
which will look as follows:
| Right | Center | Left |
| ----: | :----: | :---- |
| 10 | 10 | 10 |
| 1000 | 1000 | 1000 |
\subsection md_fenced Fenced Code Blocks
Another feature defined by "Markdown Extra" is support for
<a href="http://michelf.com/projects/php-markdown/extra/#fenced-code-blocks">
fenced code blocks</a>:
A fenced code block does not require indentation, and is
defined by a pair of "fence lines". Such a line consists of 3 or
more tile (~) characters on a line. The end of the block should have the
same number of tildes. Here is an example:
This is a paragraph introducing:
~~~~~~~~~~~~~~~~~~~~~
a one-line code block
~~~~~~~~~~~~~~~~~~~~~
The contents of the code block is syntax highlighted.
The default language is based on the file it was found in
(i.e. a fenced block in a Python file is assumed to be Python code).
In case the language is not clear from the context or you want to
indicate a specific language you can add the language's extension after
the opening fence:
~~~~~~~~~~~~~{.py}
# A class
class Dummy:
pass
~~~~~~~~~~~~~
will produce:
~~~~~~~~~~~~~{.py}
# A class
class Dummy:
pass
~~~~~~~~~~~~~
and
~~~~~~~~~~~~~~~{.c}
int func(int a,int b) { return a*b; }
~~~~~~~~~~~~~~~
will produce:
~~~~~~~~~~~~~~~{.c}
int func(int a,int b) { return a*b; }
~~~~~~~~~~~~~~~
The curly brances and dot are optional by the way.
\subsection md_header_id Header Id Attributes
Standard Markdown has no support for labeling headers, which
is a problem if you want to link to a section.
PHP Markdown Extra allows you to label a header by adding
the following to the header
Header 1 {#labelid}
========
## Header 2 ## {#labelid2}
To link to a section in the same comment block you can use
[Link text](#labelid)
to link to a section in general, doxygen allows you to use \@ref
[Link text](@ref labelid)
Note this only works for the headers of level 1 to 4.
\section markdown_dox Doxygen specifics
Even doxygen tries to following the Markdown standard as closely as
possible, there are couple of deviation and doxygen specifics additions.
\subsection md_page_header Including Markdown files as pages
Doxygen can process files with Markdown formatting.
For this to work the extension for such a file should
be `.md` or `.markdown` (see
\ref cfg_extension_mapping "EXTENSION_MAPPING" if your Markdown files have
a different extension, and use `md` as the name of the parser).
Each file is converted to a page (see the \ref cmdpage "page" command for
details).
By default the name and title of the page are derived from the file name.
If the file starts with a level 1 header however, it is used as the title
of the page. If you specify a label for the
header (as shown \ref md_header_id "here") doxygen will use that as the
page name.
If the label is called `index` or `mainpage` doxygen will put the
documentation on the front page (`index.html`).
Here is an example of a file `README.md` that will appear as the main page
when processed by doxygen:
My Main Page {#mainpage}
============
Documentation that will appear on the main page
\subsection md_html_blocks Treatment of HTML blocks
Markdown is quite strict in the way it processes block-level HTML:
> block-level HTML elements — e.g.
> `<div>`, `<table>`, `<pre>`, `<p>`, etc. —
> must be separated from surrounding content by blank lines,
> and the start and end tags of the block should not be indented
> with tabs or spaces.
Doxygen does not have this requirement, and will also process
Markdown formatting inside such HTML blocks. The only exception is
`<pre>` blocks, which are passed untouched (handy for ASCII art).
Doxygen will not process Markdown formatting inside verbatim or code blocks,
and in other sections that need to be processed without changes
(for instance formulas or inline dot graphs).
\subsection mddox_code_blocks Code Block Indentation
With markdown any block that is indented by 4 spaces (and 8 spaces
inside lists) is treated as a code block. This indentation amount
is absolute, i.e. counting from the start of the line.
Since doxygen comments can appear at any indentation level
that is required by the programming language, it
uses a relative indentation instead. The amount of
indentation is counted relative to the preceding paragraph.
In case there is no preceding paragraph (i.e. you want to start with a
code block), the minimal amount of indentation of the whole comment block
is used as a reference.
In most cases this difference does not result in different output.
Only if you play with the indentation of paragraphs the difference
is noticeable:
text
text
text
code
In this case Markdown will put the word code in a code block,
whereas Doxygen will treat it as normal text, since although the absolute
indentation is 4, the indentation with respect to the previous paragraph
is only 1.
Note that list markers are not counted when determining the
relative indent:
1. Item1
More text for item1
2. Item2
Code block for item2
For Item1 the indentation is 4 (when treating the list marker as whitespace),
so the next paragraph "More text..." starts at the same indentation level
and is therefore not seen as a code block.
\subsection mddox_code_spans Code Spans Limits
Note that unlike standard Markdown, doxygen leaves the following untouched.
A `cool' word in a `nice' sentence.
In other words; a single quote cancels the special treatment of a code span
wrapped in a pair of backtick characters. This extra restriction was
added for backward compatibility reasons.
\subsection mddox_lists Lists Extensions
With Markdown two lists separated by an empty line are joined together into
a single list which can be rather unexpected and many people consider it to
be a bug. Doxygen, however, will make two separate lists as you would expect.
Example:
- Item1 of list 1
- Item2 of list 1
1. Item1 of list 2
2. Item2 of list 2
Historically doxygen has an additional way to create numbered
lists by using `-#` markers:
-# item1
-# item2
\subsection mddox_stars Use of asterisks
Special care has to be taken when using *'s in a comment block
to start a list or make a ruler.
Doxygen will strip off any leading *'s from the comment before doing
Markdown processing. So although the following works fine
@verbatim
/** A list:
* * item1
* * item2
*/
@endverbatim
When you remove the leading *'s doxygen will strip the other stars
as well, making the list disappear!
Rulers created with *'s will not be visible at all. They only work
in Markdown files.
\subsection mddox_limits Limits on markup scope
To avoid that a stray * or _ matches something many paragraphs later,
and shows everything in between with emphasis, doxygen limits the scope
of a * and _ to a single paragraph.
For code span, between the starting and ending backtick only two
new lines are allowed.
Also for links there are limits; the link text, and link title each can
contain only one new line, the URL may not contain any newlines.
\section markdown_debug Debugging problems
When doxygen parses the source code it first extracts the comments blocks,
then passes these through the Markdown preprocessor. The output of the
Markdown preprocessing consists of text with \ref cmd_intro "special commands"
and \ref htmlcmds "HTML commands".
A second pass takes the output of the Markdown preprocessor and
converts it into the various output formats.
During Markdown preprocessing no errors are produced. Anything that
does not fit the Markdown syntax is simply passed on as-is. In the subsequent
parsing phase this could lead to errors, which may not always be obvious
as they are based on the intermediate format.
To see the result after Markdown processing you can run doxygen with the
`-d Markdown` option. It will then print each comment block before and
after Markdown processing.
*/
...@@ -16,8 +16,6 @@ ...@@ -16,8 +16,6 @@
*/ */
/*! \page output Output Formats /*! \page output Output Formats
\section output_sec Output Formats
\addindex output formats \addindex output formats
The following output formats are \e directly supported by doxygen: The following output formats are \e directly supported by doxygen:
...@@ -31,11 +29,9 @@ The following output formats are \e directly supported by doxygen: ...@@ -31,11 +29,9 @@ The following output formats are \e directly supported by doxygen:
<dt><b>RTF</b> <dt><b>RTF</b>
<dd>Generated if \c GENERATE_RTF is set to \c YES in the configuration file.<p> <dd>Generated if \c GENERATE_RTF is set to \c YES in the configuration file.<p>
Note that the RTF output probably only looks nice with Microsoft's Note that the RTF output probably only looks nice with Microsoft's
Word 97. If you have success with other programs, please let me know. Word. If you have success with other programs, please let me know.
<dt><b>XML</b> <dt><b>XML</b>
<dd>Generated if \c GENERATE_XML is set to \c YES in the configuration file.<p> <dd>Generated if \c GENERATE_XML is set to \c YES in the configuration file.<p>
<dt><b>Qt Help Project (.qhp)</b>
<dd>Generated if \c GENERATE_QHP is set to \c YES in the configuration file.
</dl> </dl>
The following output formats are \e indirectly supported by doxygen: The following output formats are \e indirectly supported by doxygen:
...@@ -46,6 +42,12 @@ The following output formats are \e indirectly supported by doxygen: ...@@ -46,6 +42,12 @@ The following output formats are \e indirectly supported by doxygen:
<dt><b>Qt Compressed Help (.qch)</b> <dt><b>Qt Compressed Help (.qch)</b>
<dd>Generated by Qt's qhelpgenerator tool from the HTML output if <dd>Generated by Qt's qhelpgenerator tool from the HTML output if
\c GENERATE_QHP is set to \c YES. \c GENERATE_QHP is set to \c YES.
<dt><b>Eclipse Help</b>
<dd>Generated from HTML with a special index file that is generated when
\c GENERATE_ECLIPSEHELP is set to \c YES.
<dt><b>XCode DocSets</b>
<dd>Compiled from HTML with a special index file that is generated when
\c GENERATE_DOCSET is set to \c YES.
<dt><b>PostScript</b> <dt><b>PostScript</b>
<dd>Generated from the \f$\mbox{\LaTeX}\f$ output by <dd>Generated from the \f$\mbox{\LaTeX}\f$ output by
running <code>make ps</code> in the output directory. running <code>make ps</code> in the output directory.
......
/*! \page perlmod Perl Module output format documentation /*! \page perlmod Perl Module Output
\addindex perlmod \addindex perlmod
...@@ -21,7 +21,7 @@ useful output, as shown by the Perl Module-based LaTeX generator. ...@@ -21,7 +21,7 @@ useful output, as shown by the Perl Module-based LaTeX generator.
backend or the Perl Module-based LaTeX generator to the backend or the Perl Module-based LaTeX generator to the
doxygen-develop mailing list. Suggestions are welcome as well. doxygen-develop mailing list. Suggestions are welcome as well.
\section using_perlmod_fmt Using the Perl Module output format. \section using_perlmod_fmt Usage
<p>When the <b>GENERATE_PERLMOD</b> tag is enabled in the Doxyfile, <p>When the <b>GENERATE_PERLMOD</b> tag is enabled in the Doxyfile,
running Doxygen generates a number of files in the <b>perlmod/</b> running Doxygen generates a number of files in the <b>perlmod/</b>
...@@ -56,7 +56,7 @@ Perl and it's the main purpose of including the Perl Module backend in ...@@ -56,7 +56,7 @@ Perl and it's the main purpose of including the Perl Module backend in
Doxygen. See \ref doxydocs_format "below" for details on how Doxygen. See \ref doxydocs_format "below" for details on how
to do this. to do this.
\section perlmod_latex Using the Perl Module-based LaTeX generator. \section perlmod_latex Using the LaTeX generator.
<p>The Perl Module-based LaTeX generator is pretty experimental and <p>The Perl Module-based LaTeX generator is pretty experimental and
incomplete at the moment, but you could find it useful nevertheless. incomplete at the moment, but you could find it useful nevertheless.
...@@ -98,7 +98,7 @@ rules added to <b>doxyrules.make</b>. ...@@ -98,7 +98,7 @@ rules added to <b>doxyrules.make</b>.
</ul> </ul>
\subsection pm_pdf_gen Simple creation of PDF and DVI output using the Perl Module-based LaTeX generator. \subsection pm_pdf_gen Creation of PDF and DVI output
<p>To try this you need to have installed LaTeX, PDFLaTeX and the <p>To try this you need to have installed LaTeX, PDFLaTeX and the
packages used by <b>doxylatex.tex</b>. packages used by <b>doxylatex.tex</b>.
...@@ -133,7 +133,7 @@ in DVI format. ...@@ -133,7 +133,7 @@ in DVI format.
</ol> </ol>
\section doxydocs_format Perl Module documentation format. \section doxydocs_format Documentation format.
<p>The Perl Module documentation generated by Doxygen is stored in <p>The Perl Module documentation generated by Doxygen is stored in
<b>DoxyDocs.pm</b>. This is a very simple Perl module that contains <b>DoxyDocs.pm</b>. This is a very simple Perl module that contains
...@@ -176,7 +176,7 @@ know the semantics of the nodes of the documentation tree, which we ...@@ -176,7 +176,7 @@ know the semantics of the nodes of the documentation tree, which we
present in \ref perlmod_tree "this page". present in \ref perlmod_tree "this page".
--> -->
\section doxymodel_format Data structure describing the Perl Module documentation tree. \section doxymodel_format Data structure
<p>You might be interested in processing the documentation contained <p>You might be interested in processing the documentation contained
in <b>DoxyDocs.pm</b> without needing to take into account the in <b>DoxyDocs.pm</b> without needing to take into account the
......
/*! \page perlmod_tree Nodes in the documentation tree of the Perl Module output format /*! \page perlmod_tree Perl Module Tree Nodes
<h2>Nodes in the documentation tree of the Perl Module output <h2>Nodes in the documentation tree of the Perl Module output
format.</h2> format.</h2>
......
...@@ -30,7 +30,7 @@ The following figure shows the relation between the tools and the flow ...@@ -30,7 +30,7 @@ The following figure shows the relation between the tools and the flow
of information between them (it looks complex but that's only because it of information between them (it looks complex but that's only because it
tries to be complete): tries to be complete):
\image html infoflow.gif "Doxygen information flow" \image html infoflow.png "Doxygen information flow"
\image latex infoflow.eps "Doxygen information flow" width=14cm \image latex infoflow.eps "Doxygen information flow" width=14cm
\section step0 Step 0: Check if doxygen supports your programming language \section step0 Step 0: Check if doxygen supports your programming language
...@@ -90,26 +90,50 @@ If you have a larger project consisting of a source directory or tree ...@@ -90,26 +90,50 @@ If you have a larger project consisting of a source directory or tree
you should assign the root directory or you should assign the root directory or
directories to the \ref cfg_input "INPUT" tag, and add one or more file directories to the \ref cfg_input "INPUT" tag, and add one or more file
patterns to the \ref cfg_file_patterns "FILE_PATTERNS" tag patterns to the \ref cfg_file_patterns "FILE_PATTERNS" tag
(for instance <code>*.cpp *.h</code>). Only files that match one of the (for instance `*.cpp *.h`). Only files that match one of the
patterns will be parsed (if the patterns are omitted a list of patterns will be parsed (if the patterns are omitted a list of
source extensions is used). typical patterns is used for the types of files doxygen supports).
For recursive parsing of a source tree you must set For recursive parsing of a source tree you must set
the \ref cfg_recursive "RECURSIVE" tag to \c YES. To further fine-tune the the \ref cfg_recursive "RECURSIVE" tag to \c YES. To further fine-tune the
list of files that is parsed the \ref cfg_exclude "EXCLUDE" and list of files that is parsed the \ref cfg_exclude "EXCLUDE" and
\ref cfg_exclude_patterns "EXCLUDE_PATTERNS" tags can be used. \ref cfg_exclude_patterns "EXCLUDE_PATTERNS" tags can be used.
To omit all \c test directories from a source tree for instance, one could use: To omit all \c test directories from a source tree for instance, one could use:
\verbatim EXCLUDE_PATTERNS = */test/* \verbatim EXCLUDE_PATTERNS = */test/*
\endverbatim \endverbatim
Doxygen looks at the file's extension to determine how to parse a file. Doxygen looks at the file's extension to determine how to parse a file,
If a file has an <code>.idl</code> or <code>.odl</code> extension it is using the following table:
treated as an IDL file. If it has a <code>.java</code> extension it is
treated as a file written in Java. Files ending with <code>.cs</code> are Extension | Language
treated as C# files and the <code>.py</code> extension selects the ---------:|---------
Python parser. Finally, files with the extensions <code>.php</code>, <code>.php4</code>, .idl |IDL
<code>.inc</code> or <code>.phtml</code> are treated as PHP sources. .ddl |IDL
Any other extension is parsed as if it is a C/C++ file, where files that .odl |IDL
end with <code>.m</code> are treated as Objective-C source files. .java |Java
.cs |C#
.d |D
.php |PHP
.php4 |PHP
.php5 |PHP
.inc |PHP
.phtml |PHP
.m |Objective-C
.M |Objective-C
.mm |Objective-C
.py |Python
.f |Fortran
.for |Fortran
.f90 |Fortran
.vhd |VHDL
.vhdl |VHDL
.tcl |TCL
.ucf |VHDL
.qsf |VHDL
.md |Markdown
.markdown |Markdown
Any other extension is parsed as if it is a C/C++ file.
\anchor extract_all \anchor extract_all
If you start using doxygen for an existing project (thus without any If you start using doxygen for an existing project (thus without any
...@@ -159,12 +183,12 @@ a whole path recursively, like <code>mkdir -p</code> does). ...@@ -159,12 +183,12 @@ a whole path recursively, like <code>mkdir -p</code> does).
The generated HTML documentation can be viewed by pointing a HTML browser The generated HTML documentation can be viewed by pointing a HTML browser
to the \c index.html file in the \c html directory. For the best results to the \c index.html file in the \c html directory. For the best results
a browser that supports cascading style sheets (CSS) should be used a browser that supports cascading style sheets (CSS) should be used
(I'm using Mozilla, Safari, Konqueror, and sometimes IE6 to test the (I'm using Mozilla Firefox, Google Chrome, Safari, and sometimes
generated output). IE8, IE9, and Opera to test the generated output).
Some of the features the HTML section (such as Some of the features the HTML section (such as
\ref cfg_generate_treeview "GENERATE_TREEVIEW" or the search engine) \ref cfg_generate_treeview "GENERATE_TREEVIEW" or the search engine)
require a browser that supports DHTML and Javascript. require a browser that supports Dynamic HTML and Javascript enabled.
\subsection latex_out LaTeX output \subsection latex_out LaTeX output
\addindex LaTeX \addindex LaTeX
...@@ -176,18 +200,18 @@ documentation, \c doxygen writes a \c Makefile into the \c latex directory. ...@@ -176,18 +200,18 @@ documentation, \c doxygen writes a \c Makefile into the \c latex directory.
The contents and targets in the \c Makefile depend on the setting of The contents and targets in the \c Makefile depend on the setting of
\ref cfg_use_pdflatex "USE_PDFLATEX". If it is disabled (set to \c NO), then \ref cfg_use_pdflatex "USE_PDFLATEX". If it is disabled (set to \c NO), then
typing \c make in the \c latex directory a dvi file called \c refman.dvi typing \c make in the \c latex directory a \c dvi file called \c refman.dvi
will be generated. This file can then be viewed using \c xdvi or will be generated. This file can then be viewed using \c xdvi or
converted into a PostScript file \c refman.ps by converted into a PostScript file \c refman.ps by
typing <code>make ps</code> (this requires <code>dvips</code>). typing `make ps` (this requires `dvips`).
To put 2 pages on one physical page use <code>make ps_2on1</code> instead. To put 2 pages on one physical page use `make ps_2on1` instead.
The resulting PostScript file can be send to a PostScript The resulting PostScript file can be send to a PostScript
printer. If you do not have a PostScript printer, you can try to use printer. If you do not have a PostScript printer, you can try to use
ghostscript to convert PostScript into something your printer understands. ghostscript to convert PostScript into something your printer understands.
Conversion to PDF is also possible if you have installed the ghostscript Conversion to PDF is also possible if you have installed the ghostscript
interpreter; just type <code>make pdf</code> (or <code>make pdf_2on1</code>). interpreter; just type `make pdf` (or `make pdf_2on1`).
To get the best results for PDF output you should set To get the best results for PDF output you should set
the \ref cfg_pdf_hyperlinks "PDF_HYPERLINKS" the \ref cfg_pdf_hyperlinks "PDF_HYPERLINKS"
...@@ -207,21 +231,21 @@ the option from the drop down menu). ...@@ -207,21 +231,21 @@ the option from the drop down menu).
\addindex XML \addindex XML
The XML output consists of a structured "dump" of the information gathered The XML output consists of a structured "dump" of the information gathered
by doxygen. Each compound (class/namespace/file/...) has its own XML file by doxygen. Each compound (class/namespace/file/...) has its own XML file
and there is also an index file called index.xml. and there is also an index file called `index.xml`.
A file called combine.xslt A file called `combine.xslt`
XSLT script is also generated and can be used to combine all XML files XSLT script is also generated and can be used to combine all XML files
into a single file. into a single file.
Doxygen also generates two XML schema files index.xsd Doxygen also generates two XML schema files `index.xsd`
(for the index file) and compound.xsd (for the compound files). (for the index file) and `compound.xsd` (for the compound files).
This schema file describes the possible elements, their attributes and This schema file describes the possible elements, their attributes and
how they are structured, i.e. it the describes the grammar of the XML how they are structured, i.e. it the describes the grammar of the XML
files and can be used for validation or to steer XSLT scripts. files and can be used for validation or to steer XSLT scripts.
In the addon/doxmlparser directory you can find a parser library for reading In the `addon/doxmlparser` directory you can find a parser library for reading
the XML output produced by doxygen in an incremental way the XML output produced by doxygen in an incremental way
(see addon/doxmlparser/include/doxmlintf.h for the interface of the library) (see `addon/doxmlparser/include/doxmlintf.h` for the interface of the library)
\subsection man_out Man page output \subsection man_out Man page output
The generated man pages can be viewed using the \c man program. You do need The generated man pages can be viewed using the \c man program. You do need
...@@ -235,56 +259,63 @@ capabilities of the man page format, so some information ...@@ -235,56 +259,63 @@ capabilities of the man page format, so some information
Although documenting the sources is presented as step 3, in a new project Although documenting the sources is presented as step 3, in a new project
this should of course be step 1. Here I assume this should of course be step 1. Here I assume
you already have some code and you want doxygen to generate a nice document you already have some code and you want doxygen to generate a nice document
describing the API and maybe the internals as well. describing the API and maybe the internals and some related design
documentation as well.
If the \ref cfg_extract_all "EXTRACT_ALL" option is set to \c NO in the If the \ref cfg_extract_all "EXTRACT_ALL" option is set to \c NO in the
configuration file (the default), then doxygen will only generate configuration file (the default), then doxygen will only generate
documentation for \e documented members, files, classes and namespaces. So documentation for \e documented entities. So
how do you document these? For members, classes and namespaces there are how do you document these? For members, classes and namespaces there are
basically two options: basically two options:
<ol> 1. Place a \e special documentation block in front of the declaration or
<li>Place a \e special documentation block in front of the declaration or
definition of the member, class or namespace. For file, class and namespace definition of the member, class or namespace. For file, class and namespace
members it is also allowed to place the documentation directly after the members it is also allowed to place the documentation directly after the
member. See section \ref specialblock to learn more about special member.
See section \ref specialblock to learn more about special
documentation blocks. documentation blocks.
<li>Place a special documentation block somewhere else (another file or 2. Place a special documentation block somewhere else (another file or
another location) \e and put a <em>structural command</em> in the another location) \e and put a <em>structural command</em> in the
documentation block. A structural command links a documentation block documentation block. A structural command links a documentation block
to a certain entity that can be documented (e.g. a member, class, to a certain entity that can be documented (e.g. a member, class,
namespace or file). See section \ref structuralcommands to learn more namespace or file).
See section \ref structuralcommands to learn more
about structural commands. about structural commands.
</ol>
The advantage of the first option is that you do not have to repeat the
name of the entity.
Files can only be documented using the second option, since there is Files can only be documented using the second option, since there is
no way to put a documentation block before a file. Of course, file members no way to put a documentation block before a file. Of course, file members
(functions, variables, typedefs, defines) do not need an explicit (functions, variables, typedefs, defines) do not need an explicit
structural command; just putting a special documentation block in front or structural command; just putting a special documentation block in front or
behind them will do. behind them will work fine.
The text inside a special documentation block is parsed The text inside a special documentation block is parsed
before it is written to the HTML and/or \f$\mbox{\LaTeX}\f$ output files. before it is written to the HTML and/or \f$\mbox{\LaTeX}\f$ output files.
\addindex parsing \addindex parsing
During parsing the following steps take place: During parsing the following steps take place:
<ul> - Markdown formatting is replaced by corresponding HTML or special
<li> The special commands inside the documentation are executed. See commands.
section \ref commands for an overview of all commands. - The special commands inside the documentation are executed. See
<li> If a line starts with some whitespace followed by one or more asterisks section \ref commands for an overview of all commands.
(<tt>*</tt>) and then optionally more whitespace, - If a line starts with some whitespace followed by one or more asterisks
then all whitespace and asterisks are removed. (`*`) and then optionally more whitespace,
<li> All resulting blank lines are treated as a paragraph separators. then all whitespace and asterisks are removed.
This saves you from placing new-paragraph commands yourself - All resulting blank lines are treated as a paragraph separators.
in order to make the generated documentation readable. This saves you from placing new-paragraph commands yourself
<li> Links are created for words corresponding to documented classes in order to make the generated documentation readable.
(unless the word is preceded by a \%; then the word will not be linked and - Links are created for words corresponding to documented classes
the \% sign is removed). (unless the word is preceded by a \%; then the word will not be linked and
<li> Links to members are created when certain patterns are found in the the \% sign is removed).
text. See section \ref autolink - Links to members are created when certain patterns are found in the
for more information on how the automatic link generation works. text. See section \ref autolink
<li> HTML tags that are in the documentation are interpreted and converted for more information on how the automatic link generation works.
to \f$\mbox{\LaTeX}\f$ equivalents for the \f$\mbox{\LaTeX}\f$ output. - HTML tags that are in the documentation are interpreted and converted
See section \ref htmlcmds for an overview of all supported HTML tags. to \f$\mbox{\LaTeX}\f$ equivalents for the \f$\mbox{\LaTeX}\f$ output.
</ul> See section \ref htmlcmds for an overview of all supported HTML tags.
\htmlonly \htmlonly
Go to the <a href="docblocks.html">next</a> section or return to the Go to the <a href="docblocks.html">next</a> section or return to the
......
...@@ -87,10 +87,10 @@ Q_EXPORT void *qmemmove( void *dst, const void *src, uint len ); ...@@ -87,10 +87,10 @@ Q_EXPORT void *qmemmove( void *dst, const void *src, uint len );
Q_EXPORT char *qstrdup( const char * ); Q_EXPORT char *qstrdup( const char * );
Q_EXPORT inline uint cstrlen( const char *str ) Q_EXPORT inline uint cstrlen( const char *str )
{ return strlen(str); } { return (uint)strlen(str); }
Q_EXPORT inline uint qstrlen( const char *str ) Q_EXPORT inline uint qstrlen( const char *str )
{ return str ? strlen(str) : 0; } { return str ? (uint)strlen(str) : 0; }
Q_EXPORT inline char *cstrcpy( char *dst, const char *src ) Q_EXPORT inline char *cstrcpy( char *dst, const char *src )
{ return strcpy(dst,src); } { return strcpy(dst,src); }
......
...@@ -3031,7 +3031,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} ...@@ -3031,7 +3031,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
<FuncCall,MemberCall2>("("{B}*("*"{B}*)+{ID}*{B}*")"{B}*)/("."|"->") { <FuncCall,MemberCall2>("("{B}*("*"{B}*)+{ID}*{B}*")"{B}*)/("."|"->") {
g_code->codify(yytext); g_code->codify(yytext);
int s=0;while (!isId(yytext[s])) s++; int s=0;while (!isId(yytext[s])) s++;
int e=yyleng-1;while (!isId(yytext[e])) e--; int e=(int)yyleng-1;while (!isId(yytext[e])) e--;
g_name=((QCString)yytext).mid(s,e-s+1); g_name=((QCString)yytext).mid(s,e-s+1);
BEGIN( MemberCall2 ); BEGIN( MemberCall2 );
} }
......
...@@ -285,7 +285,7 @@ void replaceComment(int offset); ...@@ -285,7 +285,7 @@ void replaceComment(int offset);
%% %%
<Scan>[^"'!\/\n\\#\\-]* { /* eat anything that is not " / or \n */ <Scan>[^"'!\/\n\\#\\-]* { /* eat anything that is not " / or \n */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
} }
<Scan>"\"\"\""! { /* start of python long comment */ <Scan>"\"\"\""! { /* start of python long comment */
if (g_lang!=SrcLangExt_Python) if (g_lang!=SrcLangExt_Python)
...@@ -295,7 +295,7 @@ void replaceComment(int offset); ...@@ -295,7 +295,7 @@ void replaceComment(int offset);
else else
{ {
g_pythonDocString = TRUE; g_pythonDocString = TRUE;
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
BEGIN(CComment); BEGIN(CComment);
} }
} }
...@@ -306,22 +306,22 @@ void replaceComment(int offset); ...@@ -306,22 +306,22 @@ void replaceComment(int offset);
} }
else else
{ {
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
BEGIN(CComment); BEGIN(CComment);
} }
} }
<Scan>"\"" { /* start of a string */ <Scan>"\"" { /* start of a string */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
g_stringContext = YY_START; g_stringContext = YY_START;
BEGIN(SkipString); BEGIN(SkipString);
} }
<Scan>' { <Scan>' {
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
g_charContext = YY_START; g_charContext = YY_START;
BEGIN(SkipChar); BEGIN(SkipChar);
} }
<Scan>\n { /* new line */ <Scan>\n { /* new line */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
} }
<Scan>("//!"|"///").*/\n[ \t]*"//"[\/!][^\/] { /* start C++ style special comment block */ <Scan>("//!"|"///").*/\n[ \t]*"//"[\/!][^\/] { /* start C++ style special comment block */
if (g_mlBrief) if (g_mlBrief)
...@@ -352,13 +352,13 @@ void replaceComment(int offset); ...@@ -352,13 +352,13 @@ void replaceComment(int offset);
BEGIN(SComment); BEGIN(SComment);
} }
<Scan>"//"/.*\n { /* one line C++ comment */ <Scan>"//"/.*\n { /* one line C++ comment */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
g_readLineCtx=YY_START; g_readLineCtx=YY_START;
BEGIN(ReadLine); BEGIN(ReadLine);
} }
<Scan>"/*"[*!]? { /* start of a C comment */ <Scan>"/*"[*!]? { /* start of a C comment */
g_specialComment=yyleng==3; g_specialComment=(int)yyleng==3;
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
BEGIN(CComment); BEGIN(CComment);
} }
<Scan>"#"("#")? { <Scan>"#"("#")? {
...@@ -368,7 +368,7 @@ void replaceComment(int offset); ...@@ -368,7 +368,7 @@ void replaceComment(int offset);
} }
else else
{ {
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
BEGIN(CComment); BEGIN(CComment);
} }
} }
...@@ -379,7 +379,7 @@ void replaceComment(int offset); ...@@ -379,7 +379,7 @@ void replaceComment(int offset);
} }
else else
{ {
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
BEGIN(CComment); BEGIN(CComment);
} }
} }
...@@ -390,7 +390,7 @@ void replaceComment(int offset); ...@@ -390,7 +390,7 @@ void replaceComment(int offset);
} }
else else
{ {
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
BEGIN(CComment); BEGIN(CComment);
} }
} }
...@@ -402,14 +402,14 @@ void replaceComment(int offset); ...@@ -402,14 +402,14 @@ void replaceComment(int offset);
BEGIN(VerbatimCode); BEGIN(VerbatimCode);
} }
<CComment,ReadLine>[\\@]("dot"|"code"|"msc")/[^a-z_A-Z0-9] { /* start of a verbatim block */ <CComment,ReadLine>[\\@]("dot"|"code"|"msc")/[^a-z_A-Z0-9] { /* start of a verbatim block */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
g_lastCommentContext = YY_START; g_lastCommentContext = YY_START;
g_javaBlock=0; g_javaBlock=0;
g_blockName=&yytext[1]; g_blockName=&yytext[1];
BEGIN(VerbatimCode); BEGIN(VerbatimCode);
} }
<CComment,ReadLine>[\\@]("f$"|"f["|"f{"[a-z]*) { <CComment,ReadLine>[\\@]("f$"|"f["|"f{"[a-z]*) {
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
g_blockName=&yytext[1]; g_blockName=&yytext[1];
if (g_blockName.at(1)=='[') if (g_blockName.at(1)=='[')
{ {
...@@ -423,16 +423,16 @@ void replaceComment(int offset); ...@@ -423,16 +423,16 @@ void replaceComment(int offset);
BEGIN(Verbatim); BEGIN(Verbatim);
} }
<CComment,ReadLine>[\\@]("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"rtfonly"|"manonly")/[^a-z_A-Z0-9] { /* start of a verbatim block */ <CComment,ReadLine>[\\@]("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"rtfonly"|"manonly")/[^a-z_A-Z0-9] { /* start of a verbatim block */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
g_blockName=&yytext[1]; g_blockName=&yytext[1];
g_lastCommentContext = YY_START; g_lastCommentContext = YY_START;
BEGIN(Verbatim); BEGIN(Verbatim);
} }
<Scan>. { /* any other character */ <Scan>. { /* any other character */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
} }
<Verbatim>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"endrtfonly"|"endmanonly"|"f$"|"f]"|"f}") { /* end of verbatim block */ <Verbatim>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"endrtfonly"|"endmanonly"|"f$"|"f]"|"f}") { /* end of verbatim block */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
if (yytext[1]=='f') // end of formula if (yytext[1]=='f') // end of formula
{ {
BEGIN(g_lastCommentContext); BEGIN(g_lastCommentContext);
...@@ -450,7 +450,7 @@ void replaceComment(int offset); ...@@ -450,7 +450,7 @@ void replaceComment(int offset);
else else
{ {
g_javaBlock++; g_javaBlock++;
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
} }
} }
<VerbatimCode>"}" { <VerbatimCode>"}" {
...@@ -468,12 +468,12 @@ void replaceComment(int offset); ...@@ -468,12 +468,12 @@ void replaceComment(int offset);
} }
else else
{ {
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
} }
} }
} }
<VerbatimCode>[\\@]("enddot"|"endcode"|"endmsc") { /* end of verbatim block */ <VerbatimCode>[\\@]("enddot"|"endcode"|"endmsc") { /* end of verbatim block */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
if (&yytext[4]==g_blockName) if (&yytext[4]==g_blockName)
{ {
BEGIN(g_lastCommentContext); BEGIN(g_lastCommentContext);
...@@ -482,14 +482,14 @@ void replaceComment(int offset); ...@@ -482,14 +482,14 @@ void replaceComment(int offset);
<VerbatimCode>^[ \t]*"//"[\!\/]? { /* skip leading comments */ <VerbatimCode>^[ \t]*"//"[\!\/]? { /* skip leading comments */
if (!g_inSpecialComment) if (!g_inSpecialComment)
{ {
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
} }
} }
<Verbatim,VerbatimCode>[^@\/\\\n{}]* { /* any character not a backslash or new line or } */ <Verbatim,VerbatimCode>[^@\/\\\n{}]* { /* any character not a backslash or new line or } */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
} }
<Verbatim,VerbatimCode>\n { /* new line in verbatim block */ <Verbatim,VerbatimCode>\n { /* new line in verbatim block */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
} }
<Verbatim,VerbatimCode>^[ \t]*"///" { <Verbatim,VerbatimCode>^[ \t]*"///" {
if (g_blockName=="dot" || g_blockName=="msc" || g_blockName.at(0)=='f') if (g_blockName=="dot" || g_blockName=="msc" || g_blockName.at(0)=='f')
...@@ -503,40 +503,40 @@ void replaceComment(int offset); ...@@ -503,40 +503,40 @@ void replaceComment(int offset);
} }
} }
<Verbatim,VerbatimCode>. { /* any other character */ <Verbatim,VerbatimCode>. { /* any other character */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
} }
<SkipString>\\. { /* escaped character in string */ <SkipString>\\. { /* escaped character in string */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
} }
<SkipString>"\"" { /* end of string */ <SkipString>"\"" { /* end of string */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
BEGIN(g_stringContext); BEGIN(g_stringContext);
} }
<SkipString>. { /* any other string character */ <SkipString>. { /* any other string character */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
} }
<SkipString>\n { /* new line inside string (illegal for some compilers) */ <SkipString>\n { /* new line inside string (illegal for some compilers) */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
} }
<SkipChar>\\. { /* escaped character */ <SkipChar>\\. { /* escaped character */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
} }
<SkipChar>' { /* end of character literal */ <SkipChar>' { /* end of character literal */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
BEGIN(g_charContext); BEGIN(g_charContext);
} }
<SkipChar>. { /* any other string character */ <SkipChar>. { /* any other string character */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
} }
<SkipChar>\n { /* new line character */ <SkipChar>\n { /* new line character */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
} }
<CComment>[^\\!@*\n{\"]* { /* anything that is not a '*' or command */ <CComment>[^\\!@*\n{\"]* { /* anything that is not a '*' or command */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
} }
<CComment>"*"+[^*/\\@\n{\"]* { /* stars without slashes */ <CComment>"*"+[^*/\\@\n{\"]* { /* stars without slashes */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
} }
<CComment>"\"\"\"" { /* end of Python docstring */ <CComment>"\"\"\"" { /* end of Python docstring */
if (g_lang!=SrcLangExt_Python) if (g_lang!=SrcLangExt_Python)
...@@ -546,12 +546,12 @@ void replaceComment(int offset); ...@@ -546,12 +546,12 @@ void replaceComment(int offset);
else else
{ {
g_pythonDocString = FALSE; g_pythonDocString = FALSE;
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
BEGIN(Scan); BEGIN(Scan);
} }
} }
<CComment>\n { /* new line in comment */ <CComment>\n { /* new line in comment */
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
} }
<CComment>"*"+"/" { /* end of C comment */ <CComment>"*"+"/" { /* end of C comment */
if (g_lang==SrcLangExt_Python) if (g_lang==SrcLangExt_Python)
...@@ -560,7 +560,7 @@ void replaceComment(int offset); ...@@ -560,7 +560,7 @@ void replaceComment(int offset);
} }
else else
{ {
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
BEGIN(Scan); BEGIN(Scan);
} }
} }
...@@ -571,7 +571,7 @@ void replaceComment(int offset); ...@@ -571,7 +571,7 @@ void replaceComment(int offset);
} }
else else
{ {
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
BEGIN(Scan); BEGIN(Scan);
} }
} }
...@@ -582,7 +582,7 @@ void replaceComment(int offset); ...@@ -582,7 +582,7 @@ void replaceComment(int offset);
} }
else else
{ {
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
BEGIN(Scan); BEGIN(Scan);
} }
} }
...@@ -593,22 +593,22 @@ void replaceComment(int offset); ...@@ -593,22 +593,22 @@ void replaceComment(int offset);
} }
else else
{ {
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
BEGIN(Scan); BEGIN(Scan);
} }
} }
<CComment>"'" { <CComment>"'" {
g_charContext = YY_START; g_charContext = YY_START;
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
BEGIN(SkipChar); BEGIN(SkipChar);
} }
<CComment>"\"" { <CComment>"\"" {
g_stringContext = YY_START; g_stringContext = YY_START;
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
BEGIN(SkipString); BEGIN(SkipString);
} }
<CComment>. { <CComment>. {
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
} }
<SComment>^[ \t]*"///"[\/]*/\n { <SComment>^[ \t]*"///"[\/]*/\n {
replaceComment(0); replaceComment(0);
...@@ -666,17 +666,17 @@ void replaceComment(int offset); ...@@ -666,17 +666,17 @@ void replaceComment(int offset);
} }
<SComment>\n { /* end of special comment */ <SComment>\n { /* end of special comment */
copyToOutput(" */",3); copyToOutput(" */",3);
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
g_inSpecialComment=FALSE; g_inSpecialComment=FALSE;
g_inRoseComment=FALSE; g_inRoseComment=FALSE;
BEGIN(Scan); BEGIN(Scan);
} }
<ReadLine>[^\\@\n]*/\n { <ReadLine>[^\\@\n]*/\n {
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
BEGIN(g_readLineCtx); BEGIN(g_readLineCtx);
} }
<CComment,ReadLine>[\\@][\\@][~a-z_A-Z][a-z_A-Z0-9]*[ \t]* { // escaped command <CComment,ReadLine>[\\@][\\@][~a-z_A-Z][a-z_A-Z0-9]*[ \t]* { // escaped command
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
} }
<CComment,ReadLine>[\\@]"cond"[ \t]+ { // conditional section <CComment,ReadLine>[\\@]"cond"[ \t]+ { // conditional section
g_condCtx = YY_START; g_condCtx = YY_START;
...@@ -756,7 +756,7 @@ void replaceComment(int offset); ...@@ -756,7 +756,7 @@ void replaceComment(int offset);
else // abort the alias, restart scanning else // abort the alias, restart scanning
{ {
copyToOutput(g_aliasString,g_aliasString.length()); copyToOutput(g_aliasString,g_aliasString.length());
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
BEGIN(Scan); BEGIN(Scan);
} }
} }
...@@ -794,7 +794,7 @@ void replaceComment(int offset); ...@@ -794,7 +794,7 @@ void replaceComment(int offset);
g_lastEscaped=FALSE; g_lastEscaped=FALSE;
} }
<ReadLine>. { <ReadLine>. {
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
} }
%% %%
...@@ -803,7 +803,7 @@ void replaceComment(int offset) ...@@ -803,7 +803,7 @@ void replaceComment(int offset)
{ {
if (g_mlBrief) if (g_mlBrief)
{ {
copyToOutput(yytext,yyleng); copyToOutput(yytext,(int)yyleng);
} }
else else
{ {
...@@ -811,12 +811,12 @@ void replaceComment(int offset) ...@@ -811,12 +811,12 @@ void replaceComment(int offset)
int i=computeIndent(&yytext[offset]); int i=computeIndent(&yytext[offset]);
if (i==g_blockHeadCol) if (i==g_blockHeadCol)
{ {
replaceCommentMarker(yytext,yyleng); replaceCommentMarker(yytext,(int)yyleng);
} }
else else
{ {
copyToOutput(" */",3); copyToOutput(" */",3);
int i;for (i=yyleng-1;i>=0;i--) unput(yytext[i]); int i;for (i=(int)yyleng-1;i>=0;i--) unput(yytext[i]);
g_inSpecialComment=FALSE; g_inSpecialComment=FALSE;
BEGIN(Scan); BEGIN(Scan);
} }
......
...@@ -387,8 +387,9 @@ static Entry* current = 0 ; // working entry ...@@ -387,8 +387,9 @@ static Entry* current = 0 ; // working entry
//static Entry* previous = 0 ; // TODO: remove need for this //static Entry* previous = 0 ; // TODO: remove need for this
static bool needNewEntry; static bool needNewEntry;
static QCString sectionLabel; static QCString g_sectionLabel;
static QCString sectionTitle; static QCString g_sectionTitle;
static int g_sectionLevel;
static QCString xrefItemKey; static QCString xrefItemKey;
static QCString newXRefItemKey; static QCString newXRefItemKey;
static QCString xrefItemTitle; static QCString xrefItemTitle;
...@@ -401,7 +402,6 @@ static int braceCount; ...@@ -401,7 +402,6 @@ static int braceCount;
static bool insidePre; static bool insidePre;
static bool parseMore; static bool parseMore;
static int g_condCount; static int g_condCount;
static int g_sectionLevel;
static int g_commentCount; static int g_commentCount;
static bool g_spaceBeforeCmd; static bool g_spaceBeforeCmd;
...@@ -421,38 +421,40 @@ static QCString g_compoundName; ...@@ -421,38 +421,40 @@ static QCString g_compoundName;
static void initParser() static void initParser()
{ {
sectionLabel.resize(0); g_sectionLabel.resize(0);
sectionTitle.resize(0); g_sectionTitle.resize(0);
g_memberGroupHeader.resize(0); g_memberGroupHeader.resize(0);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static QCString getDocSectionName(int s) static bool getDocSectionName(int s)
{ {
switch(s) switch(s)
{ {
case Entry::CLASSDOC_SEC: return "\\class"; case Entry::CLASSDOC_SEC:
case Entry::STRUCTDOC_SEC: return "\\struct"; case Entry::STRUCTDOC_SEC:
case Entry::UNIONDOC_SEC: return "\\union"; case Entry::UNIONDOC_SEC:
case Entry::EXCEPTIONDOC_SEC: return "\\exception"; case Entry::EXCEPTIONDOC_SEC:
case Entry::NAMESPACEDOC_SEC: return "\\namespace"; case Entry::NAMESPACEDOC_SEC:
case Entry::PROTOCOLDOC_SEC: return "\\protocol"; case Entry::PROTOCOLDOC_SEC:
case Entry::CATEGORYDOC_SEC: return "\\category"; case Entry::CATEGORYDOC_SEC:
case Entry::ENUMDOC_SEC: return "\\enum"; case Entry::ENUMDOC_SEC:
case Entry::PAGEDOC_SEC: return "\\page"; case Entry::PAGEDOC_SEC:
case Entry::VARIABLEDOC_SEC: return "\\var"; case Entry::VARIABLEDOC_SEC:
case Entry::MEMBERDOC_SEC: return "\\fn"; case Entry::MEMBERDOC_SEC:
case Entry::OVERLOADDOC_SEC: return "\\overload"; case Entry::OVERLOADDOC_SEC:
case Entry::FILEDOC_SEC: return "\\file"; case Entry::FILEDOC_SEC:
case Entry::DEFINEDOC_SEC: return "\\def"; case Entry::DEFINEDOC_SEC:
case Entry::GROUPDOC_SEC: return "\\defgroup"; case Entry::GROUPDOC_SEC:
case Entry::MAINPAGEDOC_SEC: return "\\mainpage"; case Entry::MAINPAGEDOC_SEC:
case Entry::PACKAGEDOC_SEC: return "\\package"; case Entry::PACKAGEDOC_SEC:
case Entry::DIRDOC_SEC: return "\\dir"; case Entry::DIRDOC_SEC:
case Entry::EXAMPLE_SEC: return "\\example"; case Entry::EXAMPLE_SEC:
case Entry::MEMBERGRP_SEC: return "\\name"; case Entry::MEMBERGRP_SEC:
default: return ""; return TRUE;
default:
return FALSE;
} }
} }
...@@ -461,7 +463,7 @@ static QCString getDocSectionName(int s) ...@@ -461,7 +463,7 @@ static QCString getDocSectionName(int s)
static bool makeStructuralIndicator(Entry::Sections s) static bool makeStructuralIndicator(Entry::Sections s)
{ {
//printf("current->section=%x\n",current->section); //printf("current->section=%x\n",current->section);
if (!getDocSectionName(current->section).isEmpty()) if (getDocSectionName(current->section))
{ {
return TRUE; return TRUE;
} }
...@@ -558,8 +560,9 @@ static void addXRefItem(const char *listName,const char *itemTitle, ...@@ -558,8 +560,9 @@ static void addXRefItem(const char *listName,const char *itemTitle,
docEntry->doc += cmdString; docEntry->doc += cmdString;
} }
SectionInfo *si=new SectionInfo(listName,anchorLabel, SectionInfo *si=new SectionInfo(listName,anchorLabel,
sectionTitle,SectionInfo::Anchor); g_sectionTitle,SectionInfo::Anchor,
Doxygen::sectionDict.insert(anchorLabel,si); g_sectionLevel);
Doxygen::sectionDict.append(anchorLabel,si);
docEntry->anchors->append(si); docEntry->anchors->append(si);
} }
outputXRef.resize(0); outputXRef.resize(0);
...@@ -598,14 +601,26 @@ static QCString addFormula() ...@@ -598,14 +601,26 @@ static QCString addFormula()
static void checkFormula(); static void checkFormula();
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static SectionInfo::SectionType sectionLevelToType(int level)
{
if (level>=0 && level<5) return (SectionInfo::SectionType)level;
return SectionInfo::Anchor;
}
static void addSection() static void addSection()
{ {
sectionTitle+=yytext; // create a new section element
sectionTitle=sectionTitle.stripWhiteSpace(); g_sectionTitle+=yytext;
//printf("Adding new section file=%s label=%s title=%s\n",yyFileName,sectionLabel.data(),sectionTitle.data()); g_sectionTitle=g_sectionTitle.stripWhiteSpace();
SectionInfo *si = new SectionInfo(yyFileName,sectionLabel,sectionTitle,SectionInfo::Anchor); SectionInfo *si = new SectionInfo(yyFileName,g_sectionLabel,
g_sectionTitle,sectionLevelToType(g_sectionLevel),g_sectionLevel);
// add section to this entry
current->anchors->append(si); current->anchors->append(si);
Doxygen::sectionDict.insert(yytext,si);
// add section to the global dictionary
Doxygen::sectionDict.append(g_sectionLabel,si);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -1061,7 +1076,22 @@ RCSTAG "$"{ID}":"[^\n$]+"$" ...@@ -1061,7 +1076,22 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
addOutput(yytext); addOutput(yytext);
} }
<Comment>^{B}*[1-9][0-9]*"."{B}+ | <Comment>^{B}*[1-9][0-9]*"."{B}+ |
<Comment>^{B}*[*+-]{B}+ { // start of autolist <Comment>^{B}*[*+]{B}+ { // start of autolist
if (!Doxygen::markdownSupport)
{
REJECT;
}
else
{
if (inContext!=OutputXRef)
{
briefEndsAtDot=FALSE;
setOutput(OutputDoc);
}
addOutput(yytext);
}
}
<Comment>^{B}*"-"{B}+ { // start of autolist
if (inContext!=OutputXRef) if (inContext!=OutputXRef)
{ {
briefEndsAtDot=FALSE; briefEndsAtDot=FALSE;
...@@ -1492,9 +1522,9 @@ RCSTAG "$"{ID}":"[^\n$]+"$" ...@@ -1492,9 +1522,9 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
/* ----- handle arguments of the section/subsection/.. commands ------- */ /* ----- handle arguments of the section/subsection/.. commands ------- */
<SectionLabel>{LABELID} { // first argyment <SectionLabel>{LABELID} { // first argyment
sectionLabel=yytext; g_sectionLabel=yytext;
addOutput(yytext); addOutput(yytext);
sectionTitle.resize(0); g_sectionTitle.resize(0);
BEGIN(SectionTitle); BEGIN(SectionTitle);
} }
<SectionLabel>{DOCNL} { // missing argument <SectionLabel>{DOCNL} { // missing argument
...@@ -1511,8 +1541,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" ...@@ -1511,8 +1541,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
); );
BEGIN(Comment); BEGIN(Comment);
} }
<SectionTitle>[^\n@\\*]*/"\n" { // end of section title
<SectionTitle>[^\n@\\*]*/"\n" { // end of section title
addSection(); addSection();
addOutput(yytext); addOutput(yytext);
BEGIN( Comment ); BEGIN( Comment );
...@@ -1527,19 +1556,19 @@ RCSTAG "$"{ID}":"[^\n$]+"$" ...@@ -1527,19 +1556,19 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
addOutput('\n'); addOutput('\n');
} }
<SectionTitle>[^\n@\\]* { // any character without special meaning <SectionTitle>[^\n@\\]* { // any character without special meaning
sectionTitle+=yytext; g_sectionTitle+=yytext;
addOutput(yytext); addOutput(yytext);
} }
<SectionTitle>("\\\\"|"@@"){ID} { // unescape escaped command <SectionTitle>("\\\\"|"@@"){ID} { // unescape escaped command
sectionTitle+=&yytext[1]; g_sectionTitle+=&yytext[1];
addOutput(yytext); addOutput(yytext);
} }
<SectionTitle>{CMD}[$@\\&~<>#%] { // unescape escaped character <SectionTitle>{CMD}[$@\\&~<>#%] { // unescape escaped character
sectionTitle+=yytext[1]; g_sectionTitle+=yytext[1];
addOutput(yytext); addOutput(yytext);
} }
<SectionTitle>. { // anything else <SectionTitle>. { // anything else
sectionTitle+=yytext; g_sectionTitle+=yytext;
addOutput(*yytext); addOutput(*yytext);
} }
...@@ -1576,8 +1605,8 @@ RCSTAG "$"{ID}":"[^\n$]+"$" ...@@ -1576,8 +1605,8 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
/* ----- handle arguments of the anchor command ------- */ /* ----- handle arguments of the anchor command ------- */
<AnchorLabel>{LABELID} { // found argument <AnchorLabel>{LABELID} { // found argument
SectionInfo *si = new SectionInfo(yyFileName,yytext,0,SectionInfo::Anchor); SectionInfo *si = new SectionInfo(yyFileName,yytext,0,SectionInfo::Anchor,0);
Doxygen::sectionDict.insert(yytext,si); Doxygen::sectionDict.append(yytext,si);
current->anchors->append(si); current->anchors->append(si);
addOutput(yytext); addOutput(yytext);
BEGIN( Comment ); BEGIN( Comment );
...@@ -2646,9 +2675,9 @@ bool parseCommentBlock(/* in */ ParserInterface *parser, ...@@ -2646,9 +2675,9 @@ bool parseCommentBlock(/* in */ ParserInterface *parser,
if (Doxygen::markdownSupport) if (Doxygen::markdownSupport)
{ {
current->brief = processMarkdown(current->brief); current->brief = processMarkdown(fileName,current,current->brief);
current->doc = processMarkdown(current->doc); current->doc = processMarkdown(fileName,current,current->doc);
current->inbodyDocs = processMarkdown(current->inbodyDocs); current->inbodyDocs = processMarkdown(fileName,current,current->inbodyDocs);
} }
Debug::print(Debug::CommentScan,0, Debug::print(Debug::CommentScan,0,
......
...@@ -320,10 +320,11 @@ void Definition::addSectionsToDefinition(QList<SectionInfo> *anchorList) ...@@ -320,10 +320,11 @@ void Definition::addSectionsToDefinition(QList<SectionInfo> *anchorList)
//printf("Add section `%s' to definition `%s'\n", //printf("Add section `%s' to definition `%s'\n",
// si->label.data(),name().data()); // si->label.data(),name().data());
SectionInfo *gsi=Doxygen::sectionDict.find(si->label); SectionInfo *gsi=Doxygen::sectionDict.find(si->label);
//printf("===== label=%s gsi=%p\n",si->label.data(),gsi);
if (gsi==0) if (gsi==0)
{ {
gsi = new SectionInfo(*si); gsi = new SectionInfo(*si);
Doxygen::sectionDict.insert(si->label,gsi); Doxygen::sectionDict.append(si->label,gsi);
} }
if (m_impl->sectionDict==0) if (m_impl->sectionDict==0)
{ {
...@@ -331,20 +332,82 @@ void Definition::addSectionsToDefinition(QList<SectionInfo> *anchorList) ...@@ -331,20 +332,82 @@ void Definition::addSectionsToDefinition(QList<SectionInfo> *anchorList)
} }
if (m_impl->sectionDict->find(gsi->label)==0) if (m_impl->sectionDict->find(gsi->label)==0)
{ {
m_impl->sectionDict->insert(gsi->label,gsi); m_impl->sectionDict->append(gsi->label,gsi);
gsi->definition = this; gsi->definition = this;
} }
si=anchorList->next(); si=anchorList->next();
} }
} }
bool Definition::hasSections() const
{
makeResident();
//printf("Definition::hasSections(%s) #sections=%d\n",name().data(),
// m_impl->sectionDict ? m_impl->sectionDict->count() : 0);
if (m_impl->sectionDict==0) return FALSE;
SDict<SectionInfo>::Iterator li(*m_impl->sectionDict);
SectionInfo *si;
for (li.toFirst();(si=li.current());++li)
{
if (si->type==SectionInfo::Section ||
si->type==SectionInfo::Subsection ||
si->type==SectionInfo::Subsubsection ||
si->type==SectionInfo::Paragraph)
{
return TRUE;
}
}
return FALSE;
}
void Definition::addSectionsToIndex()
{
makeResident();
if (m_impl->sectionDict==0) return;
//printf("Definition::addSectionsToIndex()\n");
SDict<SectionInfo>::Iterator li(*m_impl->sectionDict);
SectionInfo *si;
int level=0;
for (li.toFirst();(si=li.current());++li)
{
if (si->type==SectionInfo::Section ||
si->type==SectionInfo::Subsection ||
si->type==SectionInfo::Subsubsection ||
si->type==SectionInfo::Paragraph)
{
//printf(" level=%d title=%s\n",level,si->title.data());
int nextLevel = (int)si->type;
if (nextLevel>level)
{
Doxygen::indexList.incContentsDepth();
}
else if (nextLevel<level)
{
Doxygen::indexList.decContentsDepth();
}
Doxygen::indexList.addContentsItem(TRUE,si->title,
getReference(),
getOutputFileBase(),
si->label,
FALSE,
TRUE);
level = nextLevel;
}
}
while (level>0)
{
Doxygen::indexList.decContentsDepth();
level--;
}
}
void Definition::writeDocAnchorsToTagFile() void Definition::writeDocAnchorsToTagFile()
{ {
makeResident(); makeResident();
if (!Config_getString("GENERATE_TAGFILE").isEmpty() && m_impl->sectionDict) if (!Config_getString("GENERATE_TAGFILE").isEmpty() && m_impl->sectionDict)
{ {
//printf("%s: writeDocAnchorsToTagFile(%d)\n",name().data(),m_sectionDict->count()); //printf("%s: writeDocAnchorsToTagFile(%d)\n",name().data(),m_sectionDict->count());
QDictIterator<SectionInfo> sdi(*m_impl->sectionDict); SDict<SectionInfo>::Iterator sdi(*m_impl->sectionDict);
SectionInfo *si; SectionInfo *si;
for (;(si=sdi.current());++sdi) for (;(si=sdi.current());++sdi)
{ {
......
...@@ -260,6 +260,7 @@ class Definition : public DefinitionIntf, public LockableObj ...@@ -260,6 +260,7 @@ class Definition : public DefinitionIntf, public LockableObj
LockingPtr<MemberSDict> getReferencesMembers() const; LockingPtr<MemberSDict> getReferencesMembers() const;
LockingPtr<MemberSDict> getReferencedByMembers() const; LockingPtr<MemberSDict> getReferencedByMembers() const;
bool hasSections() const;
//----------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------
// ---- setters ----- // ---- setters -----
...@@ -328,6 +329,8 @@ class Definition : public DefinitionIntf, public LockableObj ...@@ -328,6 +329,8 @@ class Definition : public DefinitionIntf, public LockableObj
void writeDocAnchorsToTagFile(); void writeDocAnchorsToTagFile();
void setLocalName(const QCString name); void setLocalName(const QCString name);
void addSectionsToIndex();
protected: protected:
virtual void flushToDisk() const; virtual void flushToDisk() const;
......
...@@ -1720,7 +1720,7 @@ DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor) ...@@ -1720,7 +1720,7 @@ DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor)
if (g_sectionDict && g_sectionDict->find(id)==0) if (g_sectionDict && g_sectionDict->find(id)==0)
{ {
//printf("Inserting in dictionary!\n"); //printf("Inserting in dictionary!\n");
g_sectionDict->insert(id,sec); g_sectionDict->append(id,sec);
} }
} }
else else
...@@ -1736,9 +1736,10 @@ DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor) ...@@ -1736,9 +1736,10 @@ DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor)
DocVerbatim::DocVerbatim(DocNode *parent,const QCString &context, DocVerbatim::DocVerbatim(DocNode *parent,const QCString &context,
const QCString &text, Type t,bool isExample, const QCString &text, Type t,bool isExample,
const QCString &exampleFile) const QCString &exampleFile,const QCString &lang)
: m_context(context), m_text(text), m_type(t), : m_context(context), m_text(text), m_type(t),
m_isExample(isExample), m_exampleFile(exampleFile), m_relPath(g_relPath) m_isExample(isExample), m_exampleFile(exampleFile),
m_relPath(g_relPath), m_lang(lang)
{ {
m_parent = parent; m_parent = parent;
} }
...@@ -2134,7 +2135,7 @@ void DocSecRefItem::parse() ...@@ -2134,7 +2135,7 @@ void DocSecRefItem::parse()
m_anchor = sec->label; m_anchor = sec->label;
if (g_sectionDict && g_sectionDict->find(m_target)==0) if (g_sectionDict && g_sectionDict->find(m_target)==0)
{ {
g_sectionDict->insert(m_target,sec); g_sectionDict->append(m_target,sec);
} }
} }
else else
...@@ -2278,7 +2279,7 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) : ...@@ -2278,7 +2279,7 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) :
m_parent = parent; m_parent = parent;
Definition *compound = 0; Definition *compound = 0;
QCString anchor; QCString anchor;
//printf("DocRef::DocRef(target=%s,context=%s\n",target.data(),context.data()); //printf("DocRef::DocRef(target=%s,context=%s)\n",target.data(),context.data());
ASSERT(!target.isEmpty()); ASSERT(!target.isEmpty());
m_relPath = g_relPath; m_relPath = g_relPath;
SectionInfo *sec = Doxygen::sectionDict[target]; SectionInfo *sec = Doxygen::sectionDict[target];
...@@ -2299,7 +2300,8 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) : ...@@ -2299,7 +2300,8 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) :
else if (resolveLink(context,target,TRUE,&compound,anchor)) else if (resolveLink(context,target,TRUE,&compound,anchor))
{ {
bool isFile = compound ? bool isFile = compound ?
(compound->definitionType()==Definition::TypeFile ? TRUE : FALSE) : (compound->definitionType()==Definition::TypeFile ||
compound->definitionType()==Definition::TypePage ? TRUE : FALSE) :
FALSE; FALSE;
m_text = linkToText(compound?compound->getLanguage():SrcLangExt_Unknown,target,isFile); m_text = linkToText(compound?compound->getLanguage():SrcLangExt_Unknown,target,isFile);
m_anchor = anchor; m_anchor = anchor;
...@@ -2323,6 +2325,8 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) : ...@@ -2323,6 +2325,8 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) :
m_file = compound->getOutputFileBase(); m_file = compound->getOutputFileBase();
m_ref = compound->getReference(); m_ref = compound->getReference();
//printf("isFile=%d compound=%s (%d)\n",isFile,compound->name().data(),
// compound->definitionType());
return; return;
} }
else if (compound->definitionType()==Definition::TypeFile && else if (compound->definitionType()==Definition::TypeFile &&
...@@ -2334,7 +2338,7 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) : ...@@ -2334,7 +2338,7 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) :
return; return;
} }
} }
m_text = linkToText(SrcLangExt_Unknown,target,FALSE); m_text = target;
warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unable to resolve reference to `%s' for \\ref command", warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unable to resolve reference to `%s' for \\ref command",
qPrint(target)); qPrint(target));
} }
...@@ -4902,6 +4906,11 @@ bool DocPara::injectToken(int tok,const QCString &tokText) ...@@ -4902,6 +4906,11 @@ bool DocPara::injectToken(int tok,const QCString &tokText)
int DocPara::handleStartCode() int DocPara::handleStartCode()
{ {
int retval = doctokenizerYYlex(); int retval = doctokenizerYYlex();
QCString lang = g_token->name;
if (!lang.isEmpty() && lang.at(0)!='.')
{
lang="."+lang;
}
// search for the first non-whitespace line, index is stored in li // search for the first non-whitespace line, index is stored in li
int i=0,li=0,l=g_token->verb.length(); int i=0,li=0,l=g_token->verb.length();
while (i<l && (g_token->verb.at(i)==' ' || g_token->verb.at(i)=='\n')) while (i<l && (g_token->verb.at(i)==' ' || g_token->verb.at(i)=='\n'))
...@@ -4909,7 +4918,7 @@ int DocPara::handleStartCode() ...@@ -4909,7 +4918,7 @@ int DocPara::handleStartCode()
if (g_token->verb.at(i)=='\n') li=i+1; if (g_token->verb.at(i)=='\n') li=i+1;
i++; i++;
} }
m_children.append(new DocVerbatim(this,g_context,g_token->verb.mid(li),DocVerbatim::Code,g_isExample,g_exampleName)); m_children.append(new DocVerbatim(this,g_context,g_token->verb.mid(li),DocVerbatim::Code,g_isExample,g_exampleName,lang));
if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: code section ended without end marker"); if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: code section ended without end marker");
doctokenizerYYsetStatePara(); doctokenizerYYsetStatePara();
return retval; return retval;
...@@ -6264,7 +6273,7 @@ int DocSection::parse() ...@@ -6264,7 +6273,7 @@ int DocSection::parse()
if (m_title.isEmpty()) m_title = sec->label; if (m_title.isEmpty()) m_title = sec->label;
if (g_sectionDict && g_sectionDict->find(m_id)==0) if (g_sectionDict && g_sectionDict->find(m_id)==0)
{ {
g_sectionDict->insert(m_id,sec); g_sectionDict->append(m_id,sec);
} }
} }
} }
......
...@@ -375,7 +375,7 @@ class DocVerbatim : public DocNode ...@@ -375,7 +375,7 @@ class DocVerbatim : public DocNode
enum Type { Code, HtmlOnly, ManOnly, LatexOnly, XmlOnly, Verbatim, Dot, Msc }; enum Type { Code, HtmlOnly, ManOnly, LatexOnly, XmlOnly, Verbatim, Dot, Msc };
DocVerbatim(DocNode *parent,const QCString &context, DocVerbatim(DocNode *parent,const QCString &context,
const QCString &text, Type t,bool isExample, const QCString &text, Type t,bool isExample,
const QCString &exampleFile); const QCString &exampleFile,const QCString &lang=QCString());
Kind kind() const { return Kind_Verbatim; } Kind kind() const { return Kind_Verbatim; }
Type type() const { return m_type; } Type type() const { return m_type; }
QCString text() const { return m_text; } QCString text() const { return m_text; }
...@@ -384,14 +384,16 @@ class DocVerbatim : public DocNode ...@@ -384,14 +384,16 @@ class DocVerbatim : public DocNode
bool isExample() const { return m_isExample; } bool isExample() const { return m_isExample; }
QCString exampleFile() const { return m_exampleFile; } QCString exampleFile() const { return m_exampleFile; }
QCString relPath() const { return m_relPath; } QCString relPath() const { return m_relPath; }
QCString language() const { return m_lang; }
private: private:
QCString m_context; QCString m_context;
QCString m_text; QCString m_text;
Type m_type; Type m_type;
bool m_isExample; bool m_isExample;
QCString m_exampleFile; QCString m_exampleFile;
QCString m_relPath; QCString m_relPath;
QCString m_lang;
}; };
...@@ -1190,6 +1192,9 @@ class DocHtmlRow : public CompAccept<DocHtmlRow>, public DocNode ...@@ -1190,6 +1192,9 @@ class DocHtmlRow : public CompAccept<DocHtmlRow>, public DocNode
const HtmlAttribList &attribs() const { return m_attribs; } const HtmlAttribList &attribs() const { return m_attribs; }
int parse(); int parse();
int parseXml(bool header); int parseXml(bool header);
bool isHeading() const { return m_children.count()>0 &&
((DocHtmlCell*)m_children.getFirst())->isHeading();
}
private: private:
HtmlAttribList m_attribs; HtmlAttribList m_attribs;
......
...@@ -290,7 +290,8 @@ void DocSets::addIndexItem(Definition *context,MemberDef *md,const char *) ...@@ -290,7 +290,8 @@ void DocSets::addIndexItem(Definition *context,MemberDef *md,const char *)
case SrcLangExt_VHDL: lang="vhdl"; break; // VHDL case SrcLangExt_VHDL: lang="vhdl"; break; // VHDL
case SrcLangExt_XML: lang="xml"; break; // DBUS XML case SrcLangExt_XML: lang="xml"; break; // DBUS XML
case SrcLangExt_Tcl: lang="tcl"; break; // Tcl case SrcLangExt_Tcl: lang="tcl"; break; // Tcl
case SrcLangExt_Unknown: lang="unknown"; break; // should not happen! case SrcLangExt_Markdown:lang="markdown"; break; // Markdown
case SrcLangExt_Unknown: lang="unknown"; break; // should not happen!
} }
if (md) if (md)
......
...@@ -389,6 +389,7 @@ REFWORD {LABELID}|{REFWORD2}|{REFWORD3} ...@@ -389,6 +389,7 @@ REFWORD {LABELID}|{REFWORD2}|{REFWORD3}
%x St_TitleA %x St_TitleA
%x St_TitleV %x St_TitleV
%x St_Code %x St_Code
%x St_CodeOpt
%x St_XmlCode %x St_XmlCode
%x St_HtmlOnly %x St_HtmlOnly
%x St_ManOnly %x St_ManOnly
...@@ -696,6 +697,16 @@ REFWORD {LABELID}|{REFWORD2}|{REFWORD3} ...@@ -696,6 +697,16 @@ REFWORD {LABELID}|{REFWORD2}|{REFWORD3}
return TK_NEWPARA; return TK_NEWPARA;
} }
} }
<St_CodeOpt>"{"{LABELID}"}" {
g_token->name = yytext;
g_token->name = g_token->name.mid(1,g_token->name.length()-2);
BEGIN(St_Code);
}
<St_CodeOpt>\n |
<St_CodeOpt>. {
unput(*yytext);
BEGIN(St_Code);
}
<St_Code>{WS}*{CMD}"endcode" { <St_Code>{WS}*{CMD}"endcode" {
return RetVal_OK; return RetVal_OK;
} }
...@@ -1154,12 +1165,14 @@ void doctokenizerYYsetStateTitleAttrValue() ...@@ -1154,12 +1165,14 @@ void doctokenizerYYsetStateTitleAttrValue()
void doctokenizerYYsetStateCode() void doctokenizerYYsetStateCode()
{ {
g_token->verb=""; g_token->verb="";
BEGIN(St_Code); g_token->name="";
BEGIN(St_CodeOpt);
} }
void doctokenizerYYsetStateXmlCode() void doctokenizerYYsetStateXmlCode()
{ {
g_token->verb=""; g_token->verb="";
g_token->name="";
BEGIN(St_XmlCode); BEGIN(St_XmlCode);
} }
......
...@@ -163,8 +163,6 @@ static bool g_successfulRun = FALSE; ...@@ -163,8 +163,6 @@ static bool g_successfulRun = FALSE;
static bool g_dumpSymbolMap = FALSE; static bool g_dumpSymbolMap = FALSE;
static bool g_dumpConfigAsXML = FALSE; static bool g_dumpConfigAsXML = FALSE;
void clearAll() void clearAll()
{ {
g_inputFiles.clear(); g_inputFiles.clear();
...@@ -8233,8 +8231,9 @@ static void findMainPage(EntryNav *rootNav) ...@@ -8233,8 +8231,9 @@ static void findMainPage(EntryNav *rootNav)
indexName, indexName,
Doxygen::mainPage->name(), Doxygen::mainPage->name(),
Doxygen::mainPage->title(), Doxygen::mainPage->title(),
SectionInfo::Page); SectionInfo::Page,
Doxygen::sectionDict.insert(indexName,si); 0); // level 0
Doxygen::sectionDict.append(indexName,si);
Doxygen::mainPage->addSectionsToDefinition(root->anchors); Doxygen::mainPage->addSectionsToDefinition(root->anchors);
} }
else else
...@@ -8310,7 +8309,7 @@ static void checkPageRelations() ...@@ -8310,7 +8309,7 @@ static void checkPageRelations()
static void resolveUserReferences() static void resolveUserReferences()
{ {
QDictIterator<SectionInfo> sdi(Doxygen::sectionDict); SDict<SectionInfo>::Iterator sdi(Doxygen::sectionDict);
SectionInfo *si; SectionInfo *si;
for (;(si=sdi.current());++sdi) for (;(si=sdi.current());++sdi)
{ {
...@@ -9380,7 +9379,7 @@ void initDoxygen() ...@@ -9380,7 +9379,7 @@ void initDoxygen()
Doxygen::memGrpInfoDict.setAutoDelete(TRUE); Doxygen::memGrpInfoDict.setAutoDelete(TRUE);
Doxygen::tagDestinationDict.setAutoDelete(TRUE); Doxygen::tagDestinationDict.setAutoDelete(TRUE);
Doxygen::dirRelations.setAutoDelete(TRUE); Doxygen::dirRelations.setAutoDelete(TRUE);
Doxygen::citeDict = new CiteDict(256); Doxygen::citeDict = new CiteDict(257);
} }
void cleanUpDoxygen() void cleanUpDoxygen()
......
...@@ -638,7 +638,6 @@ table.doxtable th { ...@@ -638,7 +638,6 @@ table.doxtable th {
font-size: 110%; font-size: 110%;
padding-bottom: 4px; padding-bottom: 4px;
padding-top: 5px; padding-top: 5px;
text-align:left;
} }
table.fieldtable { table.fieldtable {
......
...@@ -638,7 +638,6 @@ ...@@ -638,7 +638,6 @@
" font-size: 110%;\n" " font-size: 110%;\n"
" padding-bottom: 4px;\n" " padding-bottom: 4px;\n"
" padding-top: 5px;\n" " padding-top: 5px;\n"
" text-align:left;\n"
"}\n" "}\n"
"\n" "\n"
"table.fieldtable {\n" "table.fieldtable {\n"
......
...@@ -661,7 +661,7 @@ ATTR_SPEC (ALLOCATABLE|DIMENSION{ARGS}|EXTERNAL|{INTENT_SPEC}|INTRINSIC|OPTIONAL ...@@ -661,7 +661,7 @@ ATTR_SPEC (ALLOCATABLE|DIMENSION{ARGS}|EXTERNAL|{INTENT_SPEC}|INTRINSIC|OPTIONAL
ACCESS_SPEC (PRIVATE|PUBLIC) ACCESS_SPEC (PRIVATE|PUBLIC)
/* Assume that attribute statements are almost the same as attributes. */ /* Assume that attribute statements are almost the same as attributes. */
ATTR_STMT {ATTR_SPEC}|DIMENSION ATTR_STMT {ATTR_SPEC}|DIMENSION
COMMANDS (BLOCK{BS}DATA|DO|SELECT|CASE|WHERE|IF|THEN|ELSE|MODULE{BS_}PROCEDURE|CONTAINS|IMPLICIT{BS}NONE|CONTAINS|WRITE|READ|ALLOCATE|ALLOCATED|ASSOCIATED|DEALLOCATE|SIZE|END{BS}IF|END{BS}DO|WHILE|INQUIRE|OPEN|CLOSE|DATA) COMMANDS (DO|SELECT|CASE|WHERE|IF|THEN|ELSE|MODULE{BS_}PROCEDURE|CONTAINS|IMPLICIT{BS}NONE|CONTAINS|WRITE|READ|ALLOCATE|ALLOCATED|ASSOCIATED|DEALLOCATE|SIZE|END{BS}IF|END{BS}DO|WHILE|INQUIRE|OPEN|CLOSE|DATA)
IGNORE (CALL) IGNORE (CALL)
/* | */ /* | */
...@@ -741,7 +741,7 @@ IGNORE (CALL) ...@@ -741,7 +741,7 @@ IGNORE (CALL)
} }
/*-------- fortran module -----------------------------------------*/ /*-------- fortran module -----------------------------------------*/
<Start>("program"|"module"|"type"|"interface")/{BS_}|({COMMA}{ACCESS_SPEC})|\n { // <Start>("block"{BS}"data"|"program"|"module"|"type"|"interface")/{BS_}|({COMMA}{ACCESS_SPEC})|\n { //
startScope(); startScope();
startFontClass("keyword"); startFontClass("keyword");
codifyLines(yytext); codifyLines(yytext);
......
...@@ -230,6 +230,7 @@ IDSYM [a-z_A-Z0-9] ...@@ -230,6 +230,7 @@ IDSYM [a-z_A-Z0-9]
NOTIDSYM [^a-z_A-Z0-9] NOTIDSYM [^a-z_A-Z0-9]
SEPARATE [:, \t] SEPARATE [:, \t]
ID [a-z_A-Z%]+{IDSYM}* ID [a-z_A-Z%]+{IDSYM}*
ID_ [a-z_A-Z%]*{IDSYM}*
PP_ID {ID} PP_ID {ID}
LABELID [a-z_A-Z]+[a-z_A-Z0-9\-]* LABELID [a-z_A-Z]+[a-z_A-Z0-9\-]*
SUBPROG (subroutine|function) SUBPROG (subroutine|function)
...@@ -299,6 +300,7 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA ...@@ -299,6 +300,7 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA
%x DocBackLine %x DocBackLine
%x EndDoc %x EndDoc
%x BlockData
%% %%
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
...@@ -505,6 +507,11 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA ...@@ -505,6 +507,11 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA
<TypedefBody>^{BS}{CONTAINS}/({BS}|\n|!) { BEGIN(TypedefBodyContains); } <TypedefBody>^{BS}{CONTAINS}/({BS}|\n|!) { BEGIN(TypedefBodyContains); }
/*------ module handling ------------------------------------------------------------*/ /*------ module handling ------------------------------------------------------------*/
<Start>block{BS}data{BS}{ID_} { //
v_type = V_IGNORE;
yy_push_state(BlockData);
defaultProtection = Public;
}
<Start>module|program{BS_} { // <Start>module|program{BS_} { //
v_type = V_IGNORE; v_type = V_IGNORE;
if(yytext[0]=='m' || yytext[0]=='M') if(yytext[0]=='m' || yytext[0]=='M')
...@@ -513,6 +520,12 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA ...@@ -513,6 +520,12 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA
yy_push_state(Program); yy_push_state(Program);
defaultProtection = Public; defaultProtection = Public;
} }
<BlockData>^{BS}"end"({BS}(block{BS}data)({BS_}{ID})?)?{BS}/(\n|!) { // end block data
//if (!endScope(current_root))
// yyterminate();
defaultProtection = Public;
yy_pop_state();
}
<Start,ModuleBody,ModuleBodyContains>^{BS}"end"({BS}(module|program)({BS_}{ID})?)?{BS}/(\n|!) { // end module <Start,ModuleBody,ModuleBodyContains>^{BS}"end"({BS}(module|program)({BS_}{ID})?)?{BS}/(\n|!) { // end module
resolveModuleProcedures(moduleProcedures, current_root); resolveModuleProcedures(moduleProcedures, current_root);
if (!endScope(current_root)) if (!endScope(current_root))
...@@ -660,6 +673,10 @@ private { ...@@ -660,6 +673,10 @@ private {
subrCurrent.remove(0u); subrCurrent.remove(0u);
yy_pop_state() ; yy_pop_state() ;
} }
<BlockData>{
{ID} {
}
}
<Start,ModuleBody,TypedefBody,SubprogBody>{ <Start,ModuleBody,TypedefBody,SubprogBody>{
^{BS}{TYPE_SPEC}/{SEPARATE} { ^{BS}{TYPE_SPEC}/{SEPARATE} {
/* variable declaration starts */ /* variable declaration starts */
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "language.h" #include "language.h"
#include "htmlgen.h" #include "htmlgen.h"
#include "layout.h" #include "layout.h"
#include "pagedef.h"
#define MAX_INDENT 1024 #define MAX_INDENT 1024
...@@ -849,10 +850,17 @@ void FTVHelp::generateTreeViewScripts() ...@@ -849,10 +850,17 @@ void FTVHelp::generateTreeViewScripts()
QCString &projName = Config_getString("PROJECT_NAME"); QCString &projName = Config_getString("PROJECT_NAME");
if (projName.isEmpty()) if (projName.isEmpty())
{ {
LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::MainPage); if (Doxygen::mainPage && !Doxygen::mainPage->title().isEmpty()) // Use title of main page as root
t << "\"" << convertToJSString(lne->title()) << "\", "; {
t << "\"" << convertToJSString(Doxygen::mainPage->title()) << "\", ";
}
else // Use default section title as root
{
LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::MainPage);
t << "\"" << convertToJSString(lne->title()) << "\", ";
}
} }
else else // use PROJECT_NAME as root tree element
{ {
t << "\"" << convertToJSString(projName) << "\", "; t << "\"" << convertToJSString(projName) << "\", ";
} }
......
...@@ -330,12 +330,17 @@ void HtmlDocVisitor::visit(DocStyleChange *s) ...@@ -330,12 +330,17 @@ void HtmlDocVisitor::visit(DocStyleChange *s)
void HtmlDocVisitor::visit(DocVerbatim *s) void HtmlDocVisitor::visit(DocVerbatim *s)
{ {
if (m_hide) return; if (m_hide) return;
QCString lang = m_langExt;
if (!s->language().isEmpty()) // explicit language setting
{
lang = s->language();
}
switch(s->type()) switch(s->type())
{ {
case DocVerbatim::Code: case DocVerbatim::Code:
forceEndParagraph(s); forceEndParagraph(s);
m_t << PREFRAG_START; m_t << PREFRAG_START;
Doxygen::parserManager->getParser(m_langExt) Doxygen::parserManager->getParser(lang)
->parseCode(m_ci,s->context(),s->text(), ->parseCode(m_ci,s->context(),s->text(),
s->isExample(),s->exampleFile()); s->isExample(),s->exampleFile());
m_t << PREFRAG_END; m_t << PREFRAG_END;
......
...@@ -2765,7 +2765,7 @@ static void writePageIndex(OutputList &ol) ...@@ -2765,7 +2765,7 @@ static void writePageIndex(OutputList &ol)
ol.startContents(); ol.startContents();
ol.startTextBlock(); ol.startTextBlock();
bool addToIndex = lne==0 || lne->visible(); bool addToIndex = lne==0 || lne->visible();
if (addToIndex) if (0 /*addToIndex*/) // skip Related Pages section in navigation index
{ {
Doxygen::indexList.addContentsItem(TRUE,title,0,"pages",0,TRUE,TRUE); Doxygen::indexList.addContentsItem(TRUE,title,0,"pages",0,TRUE,TRUE);
Doxygen::indexList.incContentsDepth(); Doxygen::indexList.incContentsDepth();
...@@ -2777,7 +2777,7 @@ static void writePageIndex(OutputList &ol) ...@@ -2777,7 +2777,7 @@ static void writePageIndex(OutputList &ol)
PageDef *pd=0; PageDef *pd=0;
for (pdi.toFirst();(pd=pdi.current());++pdi) for (pdi.toFirst();(pd=pdi.current());++pdi)
{ {
if ( pd->visibleInIndex()) if (pd->visibleInIndex())
{ {
QCString pageTitle; QCString pageTitle;
...@@ -2787,6 +2787,7 @@ static void writePageIndex(OutputList &ol) ...@@ -2787,6 +2787,7 @@ static void writePageIndex(OutputList &ol)
pageTitle=pd->title(); pageTitle=pd->title();
bool hasSubPages = pd->hasSubPages(); bool hasSubPages = pd->hasSubPages();
bool hasSections = pd->hasSections();
ol.startIndexListItem(); ol.startIndexListItem();
ol.startIndexItem(pd->getReference(),pd->getOutputFileBase()); ol.startIndexItem(pd->getReference(),pd->getOutputFileBase());
...@@ -2801,14 +2802,25 @@ static void writePageIndex(OutputList &ol) ...@@ -2801,14 +2802,25 @@ static void writePageIndex(OutputList &ol)
ol.writeString("\n"); ol.writeString("\n");
if (addToIndex) if (addToIndex)
{ {
Doxygen::indexList.addContentsItem(hasSubPages,filterTitle(pageTitle),pd->getReference(),pd->getOutputFileBase(),0,hasSubPages,TRUE); Doxygen::indexList.addContentsItem(
hasSubPages || hasSections, // isDir
filterTitle(pageTitle), // name
pd->getReference(), // ref
pd->getOutputFileBase(), // file
0, // anchor
hasSubPages || hasSections, // separateIndex
TRUE); // addToNavIndex
if (hasSections)
{
pd->addSectionsToIndex();
}
} }
writeSubPages(pd); writeSubPages(pd);
ol.endIndexListItem(); ol.endIndexListItem();
} }
} }
endIndexHierarchy(ol,0); endIndexHierarchy(ol,0);
if (addToIndex) if (0 /*addToIndex*/) // skip Related Pages section in navigation index
{ {
Doxygen::indexList.decContentsDepth(); Doxygen::indexList.decContentsDepth();
} }
...@@ -3445,8 +3457,12 @@ static void writeIndex(OutputList &ol) ...@@ -3445,8 +3457,12 @@ static void writeIndex(OutputList &ol)
if (Doxygen::mainPage) if (Doxygen::mainPage)
{ {
Doxygen::indexList.addContentsItem(Doxygen::mainPage->hasSubPages(),title,0,indexName,0,Doxygen::mainPage->hasSubPages(),TRUE); if (Doxygen::mainPage->hasSubPages() ||
(!Config_getString("PROJECT_NAME").isEmpty() && mainPageHasTitle())
) // to avoid duplicate entries in the treeview
{
Doxygen::indexList.addContentsItem(Doxygen::mainPage->hasSubPages(),title,0,indexName,0,Doxygen::mainPage->hasSubPages(),TRUE);
}
if (Doxygen::mainPage->hasSubPages()) if (Doxygen::mainPage->hasSubPages())
{ {
writeSubPages(Doxygen::mainPage); writeSubPages(Doxygen::mainPage);
......
...@@ -53,8 +53,9 @@ static const char *secLabels[maxLevels] = ...@@ -53,8 +53,9 @@ static const char *secLabels[maxLevels] =
static const char *getSectionName(int level) static const char *getSectionName(int level)
{ {
static bool compactLatex = Config_getBool("COMPACT_LATEX");
int l = level; int l = level;
if (Config_getBool("COMPACT_LATEX")) l++; if (compactLatex) l++;
if (Doxygen::insideMainPage) l--; if (Doxygen::insideMainPage) l--;
return secLabels[QMIN(maxLevels-1,l)]; return secLabels[QMIN(maxLevels-1,l)];
} }
...@@ -62,10 +63,11 @@ static const char *getSectionName(int level) ...@@ -62,10 +63,11 @@ static const char *getSectionName(int level)
static int rowspan(DocHtmlCell *cell) static int rowspan(DocHtmlCell *cell)
{ {
int retval = 0; int retval = 0;
HtmlAttribList attrs = cell->attribs (); HtmlAttribList attrs = cell->attribs();
for (unsigned int i = 0; i < attrs.count(); ++i) uint i;
for (i=0; i<attrs.count(); ++i)
{ {
if ("rowspan" == attrs.at(i)->name.lower()) if (attrs.at(i)->name.lower()=="rowspan")
{ {
retval = attrs.at(i)->value.toInt(); retval = attrs.at(i)->value.toInt();
break; break;
...@@ -74,6 +76,24 @@ static int rowspan(DocHtmlCell *cell) ...@@ -74,6 +76,24 @@ static int rowspan(DocHtmlCell *cell)
return retval; return retval;
} }
static int align(DocHtmlCell *cell)
{
HtmlAttribList attrs = cell->attribs();
uint i;
for (i=0; i<attrs.count(); ++i)
{
if (attrs.at(i)->name.lower()=="align")
{
if (attrs.at(i)->value.lower()=="center")
return 1;
else if (attrs.at(i)->value.lower()=="right")
return 2;
else return 0;
}
}
return 0;
}
QCString LatexDocVisitor::escapeMakeIndexChars(const char *s) QCString LatexDocVisitor::escapeMakeIndexChars(const char *s)
{ {
QCString result; QCString result;
...@@ -277,26 +297,19 @@ void LatexDocVisitor::visit(DocVerbatim *s) ...@@ -277,26 +297,19 @@ void LatexDocVisitor::visit(DocVerbatim *s)
{ {
//static bool latexSourceCode = Config_getBool("LATEX_SOURCE_CODE"); //static bool latexSourceCode = Config_getBool("LATEX_SOURCE_CODE");
if (m_hide) return; if (m_hide) return;
QCString lang = m_langExt;
if (!s->language().isEmpty()) // explicit language setting
{
lang = s->language();
}
switch(s->type()) switch(s->type())
{ {
case DocVerbatim::Code: case DocVerbatim::Code:
//if (latexSourceCode)
//{
// m_t << "\n\n\\begin{footnotesize}\\begin{alltt}" << endl;
//}
//else
{ {
m_t << "\n\\begin{DoxyCode}\n"; m_t << "\n\\begin{DoxyCode}\n";
} Doxygen::parserManager->getParser(lang)
Doxygen::parserManager->getParser(m_langExt) ->parseCode(m_ci,s->context(),s->text(),
->parseCode(m_ci,s->context(),s->text(), s->isExample(),s->exampleFile());
s->isExample(),s->exampleFile());
//if (latexSourceCode)
//{
// m_t << "\\end{alltt}\\end{footnotesize}" << endl;
//}
//else
{
m_t << "\\end{DoxyCode}\n"; m_t << "\\end{DoxyCode}\n";
} }
break; break;
...@@ -883,9 +896,10 @@ void LatexDocVisitor::visitPost(DocHtmlCaption *) ...@@ -883,9 +896,10 @@ void LatexDocVisitor::visitPost(DocHtmlCaption *)
m_t << "}\n"; m_t << "}\n";
} }
void LatexDocVisitor::visitPre(DocHtmlRow *) void LatexDocVisitor::visitPre(DocHtmlRow *r)
{ {
m_currentColumn = 0; m_currentColumn = 0;
if (r->isHeading()) m_t << "\\rowcolor{lightgray}";
} }
void LatexDocVisitor::visitPost(DocHtmlRow *) void LatexDocVisitor::visitPost(DocHtmlRow *)
...@@ -896,24 +910,30 @@ void LatexDocVisitor::visitPost(DocHtmlRow *) ...@@ -896,24 +910,30 @@ void LatexDocVisitor::visitPost(DocHtmlRow *)
QMap<int, int>::Iterator it; QMap<int, int>::Iterator it;
int col = 1; int col = 1;
for (it = m_rowspanIndices.begin(); it != m_rowspanIndices.end(); ++it) for (it = m_rowspanIndices.begin(); it != m_rowspanIndices.end(); ++it)
{ {
it.data()--; it.data()--;
if (it.data () <= 0) if (it.data () <= 0)
{
m_rowspanIndices.remove (it); m_rowspanIndices.remove (it);
}
else if (0 < it.data() - col) else if (0 < it.data() - col)
{
m_t << "\\cline{" << col << "-" << it.data() - col << "}"; m_t << "\\cline{" << col << "-" << it.data() - col << "}";
col = 1 + it.data ();
} }
col = 1 + it.data();
}
if (col <= m_currentColumn) if (col <= m_currentColumn)
{
m_t << "\\cline{" << col << "-" << m_currentColumn << "}"; m_t << "\\cline{" << col << "-" << m_currentColumn << "}";
}
m_t << "\n"; m_t << "\n";
} }
void LatexDocVisitor::visitPre(DocHtmlCell *cell) void LatexDocVisitor::visitPre(DocHtmlCell *c)
{ {
if (m_hide) return; if (m_hide) return;
...@@ -927,18 +947,35 @@ void LatexDocVisitor::visitPre(DocHtmlCell *cell) ...@@ -927,18 +947,35 @@ void LatexDocVisitor::visitPre(DocHtmlCell *cell)
it++; it++;
} }
int rs = rowspan(cell); int rs = rowspan(c);
if (0 < rs) if (rs>0)
{ {
m_inRowspan = TRUE; m_inRowspan = TRUE;
m_rowspanIndices[m_currentColumn] = rs; m_rowspanIndices[m_currentColumn] = rs;
m_t << "\\multirow{" << rs << "}{\\linewidth}{"; m_t << "\\multirow{" << rs << "}{\\linewidth}{";
} }
int a = align(c);
if (a==1)
{
m_t << "\\PBS\\centering ";
}
else if (a==2)
{
m_t << "\\PBS\\raggedleft ";
}
if (c->isHeading())
{
m_t << "{\\bf ";
}
} }
void LatexDocVisitor::visitPost(DocHtmlCell *c) void LatexDocVisitor::visitPost(DocHtmlCell *c)
{ {
if (m_hide) return; if (m_hide) return;
if (c->isHeading())
{
m_t << "}";
}
if (m_inRowspan) if (m_inRowspan)
{ {
m_inRowspan = FALSE; m_inRowspan = FALSE;
......
...@@ -72,18 +72,10 @@ LatexGenerator::~LatexGenerator() ...@@ -72,18 +72,10 @@ LatexGenerator::~LatexGenerator()
{ {
} }
void LatexGenerator::init() static void writeLatexMakefile()
{ {
bool generateBib = !Doxygen::citeDict->isEmpty(); bool generateBib = !Doxygen::citeDict->isEmpty();
QCString dir=Config_getString("LATEX_OUTPUT"); QCString dir=Config_getString("LATEX_OUTPUT");
QDir d(dir);
if (!d.exists() && !d.mkdir(dir))
{
err("Could not create output directory %s\n",dir.data());
exit(1);
}
QCString fileName=dir+"/Makefile"; QCString fileName=dir+"/Makefile";
QFile file(fileName); QFile file(fileName);
if (!file.open(IO_WriteOnly)) if (!file.open(IO_WriteOnly))
...@@ -182,6 +174,66 @@ void LatexGenerator::init() ...@@ -182,6 +174,66 @@ void LatexGenerator::init()
<< "\trm -f " << "\trm -f "
#endif #endif
<< "*.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf" << endl; << "*.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf" << endl;
}
static void writeMakePdfBat()
{
#if defined(_MSC_VER)
if (Config_getBool("USE_PDFLATEX")) // use plain old latex
{
bool generateBib = !Doxygen::citeDict->isEmpty();
QCString mkidx_command = Config_getString("MAKEINDEX_CMD_NAME");
QCString dir=Config_getString("LATEX_OUTPUT");
QCString fileName=dir+"/makepdf.bat";
QFile file(fileName);
if (!file.open(IO_WriteOnly))
{
err("Could not open file %s for writing\n",fileName.data());
exit(1);
}
FTextStream t(&file);
t << "del /s /f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf\n\n";
t << "pdflatex refman\n";
t << "echo ----\n";
t << mkidx_command << " refman.idx\n";
if (generateBib)
{
t << "\tbibtex refman" << endl;
t << "\tpdflatex refman" << endl;
}
t << "echo ----\n";
t << "pdflatex refman\n\n";
t << "setlocal enabledelayedexpansion\n";
t << "set count=5\n";
t << ":repeat\n";
t << "set content=X\n";
t << "for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun LaTeX\" refman.log' ) do set content=\"%%~T\"\n";
t << "if !content! == X for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun to get cross-references right\" refman.log' ) do set content=\"%%~T\"\n";
t << "if !content! == X goto :skip\n";
t << "set /a count-=1\n";
t << "if !count! EQU 0 goto :skip\n\n";
t << "echo ----\n";
t << "pdflatex refman\n";
t << "goto :repeat\n";
t << ":skip\n";
t << "endlocal\n";
}
#endif
}
void LatexGenerator::init()
{
QCString dir=Config_getString("LATEX_OUTPUT");
QDir d(dir);
if (!d.exists() && !d.mkdir(dir))
{
err("Could not create output directory %s\n",dir.data());
exit(1);
}
writeLatexMakefile();
writeMakePdfBat();
createSubDirs(d); createSubDirs(d);
} }
...@@ -345,6 +397,7 @@ static void writeDefaultStyleSheetPart1(FTextStream &t) ...@@ -345,6 +397,7 @@ static void writeDefaultStyleSheetPart1(FTextStream &t)
"\\RequirePackage{longtable}\n" "\\RequirePackage{longtable}\n"
"\\RequirePackage{verbatim}\n" "\\RequirePackage{verbatim}\n"
"\\RequirePackage{ifthen}\n" "\\RequirePackage{ifthen}\n"
"\\RequirePackage{xtab}\n"
"\\RequirePackage[table]{xcolor}\n\n"; "\\RequirePackage[table]{xcolor}\n\n";
t << "% Use helvetica font instead of times roman\n" t << "% Use helvetica font instead of times roman\n"
...@@ -788,10 +841,10 @@ static void writeDefaultStyleSheetPart3(FTextStream &t) ...@@ -788,10 +841,10 @@ static void writeDefaultStyleSheetPart3(FTextStream &t)
t << "{\n"; t << "{\n";
t << "\\setlength{\\tmplength}\n"; t << "\\setlength{\\tmplength}\n";
t << " {\\linewidth/(#1)-\\tabcolsep*2-\\arrayrulewidth*(#1+1)/(#1)}\n"; t << " {\\linewidth/(#1)-\\tabcolsep*2-\\arrayrulewidth*(#1+1)/(#1)}\n";
t << " \\par\\begin{tabular*}{\\linewidth}\n"; t << " \\par\\begin{xtabular*}{\\linewidth}\n";
t << " {*{#1}{|>{\\PBS\\raggedright\\hspace{0pt}}p{\\the\\tmplength}}|}\n"; t << " {*{#1}{|>{\\PBS\\raggedright\\hspace{0pt}}p{\\the\\tmplength}}|}\n";
t << "}\n"; t << "}\n";
t << "{\\end{tabular*}\\par}\n"; t << "{\\end{xtabular*}\\par}\n";
t << "\\newcommand{\\entrylabel}[1]{\n"; t << "\\newcommand{\\entrylabel}[1]{\n";
t << " {\\parbox[b]{\\labelwidth-4pt}{\\makebox[0pt][l]{%\n"; t << " {\\parbox[b]{\\labelwidth-4pt}{\\makebox[0pt][l]{%\n";
t << " \\usefont{OT1}{phv}{bc}{n}\\color{darkgray}#1}\\vspace{1.5\\baselineskip}}}}\n"; t << " \\usefont{OT1}{phv}{bc}{n}\\color{darkgray}#1}\\vspace{1.5\\baselineskip}}}}\n";
......
...@@ -43,6 +43,14 @@ ...@@ -43,6 +43,14 @@
#include "util.h" #include "util.h"
#include "doxygen.h" #include "doxygen.h"
#include "commentscan.h" #include "commentscan.h"
#include "entry.h"
//-----------
#define isIdChar(i) \
((data[(i)]>='a' && data[(i)]<='z') || \
(data[(i)]>='A' && data[(i)]<='Z') || \
(data[(i)]>='0' && data[(i)]<='9')) \
//---------- //----------
...@@ -62,6 +70,8 @@ enum Alignment { AlignNone, AlignLeft, AlignCenter, AlignRight }; ...@@ -62,6 +70,8 @@ enum Alignment { AlignNone, AlignLeft, AlignCenter, AlignRight };
static QDict<LinkRef> g_linkRefs(257); static QDict<LinkRef> g_linkRefs(257);
static action_t g_actions[256]; static action_t g_actions[256];
static Entry *g_current;
static QCString g_fileName;
//static QDict<void> g_htmlBlockTags(17); //static QDict<void> g_htmlBlockTags(17);
//---------- //----------
...@@ -206,11 +216,7 @@ static int findEmphasisChar(const char *data, int size, char c) ...@@ -206,11 +216,7 @@ static int findEmphasisChar(const char *data, int size, char c)
if (data[i] == c) if (data[i] == c)
{ {
if (i<size-1 && ((data[i+1]>='a' && data[i+1]<='z') || if (i<size-1 && isIdChar(i+1)) // to prevent touching some_underscore_identifier
(data[i+1]>='A' && data[i+1]<='Z') ||
(data[i+1]>='0' && data[i+1]<='9')
)
) // to prevent touching some_underscore_identifier
{ {
i++; i++;
continue; continue;
...@@ -397,11 +403,110 @@ static int processEmphasis3(GrowBuf &out, const char *data, int size, char c) ...@@ -397,11 +403,110 @@ static int processEmphasis3(GrowBuf &out, const char *data, int size, char c)
return 0; return 0;
} }
static int processEmphasis(GrowBuf &out,const char *data,int,int size) static int processHtmlTag(GrowBuf &out,const char *data,int offset,int size)
{ {
if (offset>0 && data[-1]=='\\') return 0; // escaped <
// find the end of the html tag
int i=1;
int l=0;
// compute length of the tag name
while (i<size && isIdChar(i)) i++,l++;
QCString tagName;
convertStringFragment(tagName,data+1,i-1);
if (tagName.lower()=="pre") // found <pre> tag
{
bool insideStr=FALSE;
while (i<size-6)
{
char c=data[i];
if (!insideStr && c=='<') // potential start of html tag
{
if (data[i+1]=='/' &&
tolower(data[i+2])=='p' && tolower(data[i+3])=='r' &&
tolower(data[i+4])=='e' && tolower(data[i+5])=='>')
{ // found </pre> tag, copy from start to end of tag
out.addStr(data,i+6);
//printf("found <pre>..</pre> [%d..%d]\n",0,i+6);
return i+6;
}
}
else if (insideStr && c=='"')
{
if (data[i-1]!='\\') insideStr=FALSE;
}
else if (c=='"')
{
insideStr=TRUE;
}
i++;
}
}
else // some other html tag
{
if (l>0 && i<size)
{
if (data[i]=='/' && i<size-1 && data[i+1]=='>') // <bla/>
{
//printf("Found htmlTag={%s}\n",QCString(data).left(i+2).data());
out.addStr(data,i+2);
return i+2;
}
else if (data[i]=='>') // <bla>
{
//printf("Found htmlTag={%s}\n",QCString(data).left(i+1).data());
out.addStr(data,i+1);
return i+1;
}
else if (data[i]==' ') // <bla attr=...
{
i++;
bool insideAttr=FALSE;
while (i<size)
{
if (!insideAttr && data[i]=='"')
{
insideAttr=TRUE;
}
else if (data[i]=='"' && data[i-1]!='\\')
{
insideAttr=FALSE;
}
else if (!insideAttr && data[i]=='>') // found end of tag
{
//printf("Found htmlTag={%s}\n",QCString(data).left(i+1).data());
out.addStr(data,i+1);
return i+1;
}
i++;
}
}
}
}
//printf("Not a valid html tag\n");
return 0;
}
static int processEmphasis(GrowBuf &out,const char *data,int offset,int size)
{
if (offset>0 && size>1 && (isIdChar(-1) || data[-1]==data[0]))
{
if (isIdChar(1) || data[-1]==data[0])
{
// avoid processing interal * and _ as cmd_id, or 4*10 as emphasis,
// also x**2,y*2 should not be processed
return 0;
}
else if (size>2 && data[0]==data[1] && isIdChar(2))
{
// avoid processing interal ** and __ such as cmd__id__bla,
// or 4**10,5**10 as emphasis
return 0;
}
}
char c = data[0]; char c = data[0];
size_t ret; int ret;
if (size>2 && data[1]!=c) if (size>2 && data[1]!=c) // _bla or *bla
{ {
// whitespace cannot follow an opening emphasis // whitespace cannot follow an opening emphasis
if (data[1]==' ' || data[1]=='\n' || if (data[1]==' ' || data[1]=='\n' ||
...@@ -411,7 +516,7 @@ static int processEmphasis(GrowBuf &out,const char *data,int,int size) ...@@ -411,7 +516,7 @@ static int processEmphasis(GrowBuf &out,const char *data,int,int size)
} }
return ret+1; return ret+1;
} }
if (size>3 && data[1]==c && data[2]!=c) if (size>3 && data[1]==c && data[2]!=c) // __bla or **bla
{ {
if (data[2]==' ' || data[2]=='\n' || if (data[2]==' ' || data[2]=='\n' ||
(ret = processEmphasis2(out, data+2, size-2, c)) == 0) (ret = processEmphasis2(out, data+2, size-2, c)) == 0)
...@@ -420,7 +525,7 @@ static int processEmphasis(GrowBuf &out,const char *data,int,int size) ...@@ -420,7 +525,7 @@ static int processEmphasis(GrowBuf &out,const char *data,int,int size)
} }
return ret+2; return ret+2;
} }
if (size>4 && data[1]==c && data[2]==c && data[3]!=c) if (size>4 && data[1]==c && data[2]==c && data[3]!=c) // ___bla or ***bla
{ {
if (data[3]==' ' || data[3]=='\n' || if (data[3]==' ' || data[3]=='\n' ||
(ret = processEmphasis3(out, data+3, size-3, c)) == 0) (ret = processEmphasis3(out, data+3, size-3, c)) == 0)
...@@ -478,7 +583,7 @@ static int processLink(GrowBuf &out,const char *data,int,int size) ...@@ -478,7 +583,7 @@ static int processLink(GrowBuf &out,const char *data,int,int size)
contentEnd=i; contentEnd=i;
convertStringFragment(content,data+contentStart,contentEnd-contentStart); convertStringFragment(content,data+contentStart,contentEnd-contentStart);
//printf("processLink: content={%s}\n",content.data()); //printf("processLink: content={%s}\n",content.data());
if (content.isEmpty()) return 0; // no link text if (!isImageLink && content.isEmpty()) return 0; // no link text
i++; // skip over ] i++; // skip over ]
// skip whitespace // skip whitespace
...@@ -588,7 +693,7 @@ static int processLink(GrowBuf &out,const char *data,int,int size) ...@@ -588,7 +693,7 @@ static int processLink(GrowBuf &out,const char *data,int,int size)
} }
i++; i++;
} }
else if (i<size && data[i]!=':') // minimal link ref notation [some id] else if (i<size && data[i]!=':' && !content.isEmpty()) // minimal link ref notation [some id]
{ {
LinkRef *lr = g_linkRefs.find(content.lower()); LinkRef *lr = g_linkRefs.find(content.lower());
//printf("processLink: minimal link {%s} lr=%p",content.data(),lr); //printf("processLink: minimal link {%s} lr=%p",content.data(),lr);
...@@ -609,28 +714,33 @@ static int processLink(GrowBuf &out,const char *data,int,int size) ...@@ -609,28 +714,33 @@ static int processLink(GrowBuf &out,const char *data,int,int size)
{ {
return 0; return 0;
} }
if (isImageLink) // TODO: use @image? static QRegExp re("^[@\\]ref ");
if (isImageLink)
{ {
out.addStr("<img src=\""); if (link.find("@ref ")!=-1 || link.find("\\ref ")!=-1)
out.addStr(link); // assume doxygen symbol link
out.addStr("\" alt=\"");
out.addStr(content);
out.addStr("\"");
if (!title.isEmpty())
{ {
out.addStr(" title=\""); out.addStr("@image html ");
out.addStr(substitute(title.simplifyWhiteSpace(),"\"","&quot;")); out.addStr(link.mid(5));
out.addStr("\""); if (!explicitTitle && !content.isEmpty())
{
out.addStr(" \"");
out.addStr(content);
out.addStr("\"");
}
else if ((content.isEmpty() || explicitTitle) && !title.isEmpty())
{
out.addStr(" \"");
out.addStr(title);
out.addStr("\"");
}
} }
out.addStr("/>"); else
}
else
{
static QRegExp re("^[@\\]ref ");
if (link.find('/')!=-1) // file/url link
{ {
out.addStr("<a href=\""); out.addStr("<img src=\"");
out.addStr(link); out.addStr(link);
out.addStr("\" alt=\"");
out.addStr(content);
out.addStr("\""); out.addStr("\"");
if (!title.isEmpty()) if (!title.isEmpty())
{ {
...@@ -638,11 +748,12 @@ static int processLink(GrowBuf &out,const char *data,int,int size) ...@@ -638,11 +748,12 @@ static int processLink(GrowBuf &out,const char *data,int,int size)
out.addStr(substitute(title.simplifyWhiteSpace(),"\"","&quot;")); out.addStr(substitute(title.simplifyWhiteSpace(),"\"","&quot;"));
out.addStr("\""); out.addStr("\"");
} }
out.addStr(">"); out.addStr("/>");
out.addStr(content.simplifyWhiteSpace());
out.addStr("</a>");
} }
else if (link.find("@ref ")!=-1 || link.find("\\ref ")!=-1) }
else
{
if (link.find("@ref ")!=-1 || link.find("\\ref ")!=-1)
// assume doxygen symbol link // assume doxygen symbol link
{ {
out.addStr(link); out.addStr(link);
...@@ -657,7 +768,22 @@ static int processLink(GrowBuf &out,const char *data,int,int size) ...@@ -657,7 +768,22 @@ static int processLink(GrowBuf &out,const char *data,int,int size)
} }
out.addStr("\""); out.addStr("\"");
} }
else // avoid link to F[x](y) else if (link.find('/')!=-1 || link.find('.')!=-1 || link.find('#')!=-1)
{ // file/url link
out.addStr("<a href=\"");
out.addStr(link);
out.addStr("\"");
if (!title.isEmpty())
{
out.addStr(" title=\"");
out.addStr(substitute(title.simplifyWhiteSpace(),"\"","&quot;"));
out.addStr("\"");
}
out.addStr(">");
out.addStr(content.simplifyWhiteSpace());
out.addStr("</a>");
}
else // avoid link to e.g. F[x](y)
{ {
//printf("no link for '%s'\n",link.data()); //printf("no link for '%s'\n",link.data());
return 0; return 0;
...@@ -722,17 +848,14 @@ static int processCodeSpan(GrowBuf &out, const char *data, int /*offset*/, int s ...@@ -722,17 +848,14 @@ static int processCodeSpan(GrowBuf &out, const char *data, int /*offset*/, int s
i=f_begin; i=f_begin;
while (i<f_end-1) while (i<f_end-1)
{ {
if (data[i]=='\'' && !((data[i+1]>='a' && data[i+1]<='z') || if (data[i]=='\'' && !isIdChar(i+1)) // reject `some word' and not `it's cool`
(data[i+1]>='A' && data[i+1]<='Z') ||
(data[i+1]>='0' && data[i+1]<='9')
)) // reject `some word' and not `it's cool`
{ {
return 0; return 0;
} }
i++; i++;
} }
} }
printf("found code span '%s'\n",QCString(data+f_begin).left(f_end-f_begin).data()); //printf("found code span '%s'\n",QCString(data+f_begin).left(f_end-f_begin).data());
/* real code span */ /* real code span */
if (f_begin < f_end) if (f_begin < f_end)
...@@ -783,28 +906,6 @@ static int processSpecialCommand(GrowBuf &out, const char *data, int offset, int ...@@ -783,28 +906,6 @@ static int processSpecialCommand(GrowBuf &out, const char *data, int offset, int
return 0; return 0;
} }
#if 0
static int processHtmlBlock(GrowBuf &out, const char *data, int offset, int size)
{
if (size<2 || data[0]!='<') return 0;
int i=1;
while (i<size && ((data[i]>='0' && data[i]<='9') ||
(data[i]>='A' && data[i]<='Z') ||
(data[i]>='a' && data[i]<='z'))) i++;
if (i<=1 || i>=size) return 0;
QCString tagName;
convertStringFragment(tagName,data+1,i-1);
printf("found html tag '%s'\n",tagName.data());
if (g_htmlBlockTags.find(tagName)!=0)
{
printf("found block tag\n");
// search for end of the block...
}
return 0;
}
#endif
static void processInline(GrowBuf &out,const char *data,int size) static void processInline(GrowBuf &out,const char *data,int size)
{ {
int i=0, end=0; int i=0, end=0;
...@@ -856,7 +957,24 @@ static bool isBlockQuote(const char *data,int size,int indent) ...@@ -856,7 +957,24 @@ static bool isBlockQuote(const char *data,int size,int indent)
{ {
int i = 0; int i = 0;
while (i<size && data[i]==' ') i++; while (i<size && data[i]==' ') i++;
return i<size && data[i]=='>' && i<indent+codeBlockIndent; if (i<indent+codeBlockIndent) // could be a quotation
{
// count >'s and skip spaces
int level=0;
while (i<size && (data[i]=='>' || data[i]==' '))
{
if (data[i]=='>') level++;
i++;
}
// last characters should be a space or newline,
// so a line starting with >= does not match
return level>0 && i<size && ((data[i-1]==' ') || data[i]=='\n');
}
else // too much indentation -> code block
{
return FALSE;
}
//return i<size && data[i]=='>' && i<indent+codeBlockIndent;
} }
/** returns end of the link ref if this is indeed a link reference. */ /** returns end of the link ref if this is indeed a link reference. */
...@@ -979,7 +1097,7 @@ static int isHRuler(const char *data,int size) ...@@ -979,7 +1097,7 @@ static int isHRuler(const char *data,int size)
static QCString extractTitleId(QCString &title) static QCString extractTitleId(QCString &title)
{ {
static QRegExp r1("^[a-z_A-Z][a-z_A-Z0-9\\-]*:"); //static QRegExp r1("^[a-z_A-Z][a-z_A-Z0-9\\-]*:");
static QRegExp r2("\\{#[a-z_A-Z][a-z_A-Z0-9\\-]*\\}$"); static QRegExp r2("\\{#[a-z_A-Z][a-z_A-Z0-9\\-]*\\}$");
int l=0; int l=0;
int i = r2.match(title,0,&l); int i = r2.match(title,0,&l);
...@@ -990,20 +1108,21 @@ static QCString extractTitleId(QCString &title) ...@@ -990,20 +1108,21 @@ static QCString extractTitleId(QCString &title)
//printf("found id='%s' title='%s'\n",id.data(),title.data()); //printf("found id='%s' title='%s'\n",id.data(),title.data());
return id; return id;
} }
i = r1.match(title,0,&l); //i = r1.match(title,0,&l);
if (i!=-1) // found id: style id //if (i!=-1) // found id: style id
{ //{
QCString id = title.mid(i,l-1); // QCString id = title.mid(i,l-1);
title = title.left(i)+title.mid(i+l); // title = title.left(i)+title.mid(i+l);
//printf("found id='%s' title='%s'\n",id.data(),title.data()); // //printf("found id='%s' title='%s'\n",id.data(),title.data());
return id; // return id;
} //}
//printf("no id found in title '%s'\n",title.data()); //printf("no id found in title '%s'\n",title.data());
return ""; return "";
} }
static int isAtxHeader(const char *data,int size,QCString &header) static int isAtxHeader(const char *data,int size,
QCString &header,QCString &id)
{ {
int i = 0, end; int i = 0, end;
int level = 0; int level = 0;
...@@ -1021,6 +1140,13 @@ static int isAtxHeader(const char *data,int size,QCString &header) ...@@ -1021,6 +1140,13 @@ static int isAtxHeader(const char *data,int size,QCString &header)
// store result // store result
convertStringFragment(header,data+i,end-i); convertStringFragment(header,data+i,end-i);
id = extractTitleId(header);
if (!id.isEmpty()) // strip #'s between title and id
{
i=header.length()-1;
while (i>=0 && header.at(i)=='#' || header.at(i)==' ') i--;
header=header.left(i+1);
}
return level; return level;
} }
...@@ -1037,19 +1163,29 @@ static int isEmptyLine(const char *data,int size) ...@@ -1037,19 +1163,29 @@ static int isEmptyLine(const char *data,int size)
return TRUE; return TRUE;
} }
#define isLiTag(i) \
(data[(i)]=='<' && \
(data[(i)+1]=='l' || data[(i)+1]=='L') && \
(data[(i)+2]=='i' || data[(i)+2]=='I') && \
(data[(i)+3]=='>'))
// compute the indent from the start of the input, excluding list markers // compute the indent from the start of the input, excluding list markers
// such as -, *, +, and 1. // such as -, -#, *, +, 1., and <li>
static int computeIndentExcludingListMarkers(const char *data,int size) static int computeIndentExcludingListMarkers(const char *data,int size)
{ {
int i=0; int i=0;
int indent=0; int indent=0;
bool isDigit=FALSE; bool isDigit=FALSE;
bool isLi=FALSE;
bool listMarkerSkipped=FALSE; bool listMarkerSkipped=FALSE;
while (i<size && while (i<size &&
(data[i]==' ' || // space (data[i]==' ' || // space
(!listMarkerSkipped && // first list marker (!listMarkerSkipped && // first list marker
(data[i]=='+' || data[i]=='-' || data[i]=='*' || // unordered list char (data[i]=='+' || data[i]=='-' || data[i]=='*' || // unordered list char
(isDigit=(data[i]>='1' && data[i]<='9'))) // ordered list marker? (data[i]=='#' && i>0 && data[i-1]=='-') || // -# item
(isDigit=(data[i]>='1' && data[i]<='9')) || // ordered list marker?
(isLi=(i<size-3 && isLiTag(i))) // <li> tag
)
) )
) )
) )
...@@ -1076,12 +1212,24 @@ static int computeIndentExcludingListMarkers(const char *data,int size) ...@@ -1076,12 +1212,24 @@ static int computeIndentExcludingListMarkers(const char *data,int size)
j++; j++;
} }
} }
else if (data[i]!=' ' && i<size-1 && data[i+1]==' ') else if (isLi)
{ {
i+=3; // skip over <li>
indent+=3;
listMarkerSkipped=TRUE;
}
else if (data[i]=='-' && i<size-2 && data[i+1]=='#' && data[i+2]==' ')
{ // case "-# "
listMarkerSkipped=TRUE; // only a single list marker is accepted
i++; // skip over #
indent++;
}
else if (data[i]!=' ' && i<size-1 && data[i+1]==' ')
{ // case "- " or "+ " or "* "
listMarkerSkipped=TRUE; // only a single list marker is accepted listMarkerSkipped=TRUE; // only a single list marker is accepted
} }
if (data[i]!=' ' && !listMarkerSkipped) if (data[i]!=' ' && !listMarkerSkipped)
{ { // end of indent
break; break;
} }
indent++,i++; indent++,i++;
...@@ -1090,6 +1238,44 @@ static int computeIndentExcludingListMarkers(const char *data,int size) ...@@ -1090,6 +1238,44 @@ static int computeIndentExcludingListMarkers(const char *data,int size)
return indent; return indent;
} }
static bool isFencedCodeBlock(const char *data,int size,int refIndent,
QCString &lang,int &start,int &end,int &offset)
{
// TODO: implement me...
// rules: at least 3 ~~~, end of the block same amount of ~~~'s, otherwise
// return FALSE
int i=0;
int indent=0;
int startTildes=0;
while (i<size && data[i]==' ') indent++,i++;
if (indent>=refIndent+4) return FALSE; // part of code block
while (i<size && data[i]=='~') startTildes++,i++;
if (startTildes<3) return FALSE; // not enough tildes
if (i<size && data[i]=='{') i++; // skip over optional {
int startLang=i;
while (i<size && (data[i]!='\n' && data[i]!='}' && data[i]!=' ')) i++;
convertStringFragment(lang,data+startLang,i-startLang);
while (i<size && data[i]!='\n') i++; // proceed to the end of the line
start=i;
while (i<size)
{
if (data[i]=='~')
{
end=i-1;
int endTildes=0;
while (i<size && data[i]=='~') endTildes++,i++;
while (i<size && data[i]==' ') i++;
if (i==size || data[i]=='\n')
{
offset=i;
return endTildes==startTildes;
}
}
i++;
}
return FALSE;
}
static bool isCodeBlock(const char *data,int offset,int size,int &indent) static bool isCodeBlock(const char *data,int offset,int size,int &indent)
{ {
//printf("<isCodeBlock(offset=%d,size=%d,indent=%d)\n",offset,size,indent); //printf("<isCodeBlock(offset=%d,size=%d,indent=%d)\n",offset,size,indent);
...@@ -1244,16 +1430,9 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size) ...@@ -1244,16 +1430,9 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size)
// write table header, in range [start..end] // write table header, in range [start..end]
out.addStr("<tr>"); out.addStr("<tr>");
j=start;
for (k=0;k<columns;k++) int headerStart = start;
{ int headerEnd = end;
out.addStr("<th>");
while (j<=end && (data[j]!='|' || (j>0 && data[j-1]=='\\')))
{
out.addChar(data[j++]);
}
j++;
}
// read cell alignments // read cell alignments
int ret = findTableColumns(data+i,size-i,start,end,cc); int ret = findTableColumns(data+i,size-i,start,end,cc);
...@@ -1295,6 +1474,25 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size) ...@@ -1295,6 +1474,25 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size)
// proceed to next line // proceed to next line
i+=ret; i+=ret;
int m=headerStart;
for (k=0;k<columns;k++)
{
out.addStr("<th");
switch (columnAlignment[k])
{
case AlignLeft: out.addStr(" align=left"); break;
case AlignRight: out.addStr(" align=right"); break;
case AlignCenter: out.addStr(" align=center"); break;
case AlignNone: break;
}
out.addStr(">");
while (m<=headerEnd && (data[m]!='|' || (m>0 && data[m-1]=='\\')))
{
out.addChar(data[m++]);
}
m++;
}
// write table cells // write table cells
while (i<size) while (i<size)
{ {
...@@ -1348,17 +1546,44 @@ void writeOneLineHeaderOrRuler(GrowBuf &out,const char *data,int size) ...@@ -1348,17 +1546,44 @@ void writeOneLineHeaderOrRuler(GrowBuf &out,const char *data,int size)
{ {
int level; int level;
QCString header; QCString header;
QCString id;
if (isHRuler(data,size)) if (isHRuler(data,size))
{ {
out.addStr("<hr>\n"); out.addStr("<hr>\n");
} }
else if ((level=isAtxHeader(data,size,header))) else if ((level=isAtxHeader(data,size,header,id)))
{ {
QCString hTag; QCString hTag;
hTag.sprintf("h%d",level); if (level<5 && !id.isEmpty())
out.addStr("<"+hTag+">"); {
out.addStr(header); switch(level)
out.addStr("</"+hTag+">\n"); {
case 1: out.addStr("@section "); break;
case 2: out.addStr("@subsection "); break;
case 3: out.addStr("@subsubsection "); break;
default: out.addStr("@paragraph "); break;
}
out.addStr(id);
out.addStr(" ");
out.addStr(header);
SectionInfo *si = new SectionInfo(g_fileName,id,header,SectionInfo::Anchor,level);
if (g_current)
{
g_current->anchors->append(si);
}
Doxygen::sectionDict.append(header,si);
}
else
{
if (!id.isEmpty())
{
out.addStr("\\anchor "+id+"\n");
}
hTag.sprintf("h%d",level);
out.addStr("<"+hTag+">");
out.addStr(header);
out.addStr("</"+hTag+">\n");
}
} }
else // nothing interesting -> just output the line else // nothing interesting -> just output the line
{ {
...@@ -1387,6 +1612,11 @@ static int writeBlockQuote(GrowBuf &out,const char *data,int size) ...@@ -1387,6 +1612,11 @@ static int writeBlockQuote(GrowBuf &out,const char *data,int size)
else if (j>0 && data[j-1]=='>') indent=j+1; else if (j>0 && data[j-1]=='>') indent=j+1;
j++; j++;
} }
if (j>0 && data[j-1]=='>') // disqualify last > if not followed by space
{
indent--;
j--;
}
if (level>curLevel) // quote level increased => add start markers if (level>curLevel) // quote level increased => add start markers
{ {
for (l=curLevel;l<level;l++) for (l=curLevel;l<level;l++)
...@@ -1458,11 +1688,12 @@ static void findEndOfLine(GrowBuf &out,const char *data,int size, ...@@ -1458,11 +1688,12 @@ static void findEndOfLine(GrowBuf &out,const char *data,int size,
int &pi,int&i,int &end) int &pi,int&i,int &end)
{ {
// find end of the line // find end of the line
int nb=0;
for (end=i+1; end<size && data[end-1]!='\n'; end++) for (end=i+1; end<size && data[end-1]!='\n'; end++)
{ {
// while looking for the end of the line we might encounter a block // while looking for the end of the line we might encounter a block
// that needs to be passed unprocessed. // that needs to be passed unprocessed.
if ((data[end-1]=='\\' || data[end-1]=='@') && // command if ((data[end-1]=='\\' || data[end-1]=='@') && // command
(end<=1 || (data[end-2]!='\\' && data[end-2]!='@')) // not escaped (end<=1 || (data[end-2]!='\\' && data[end-2]!='@')) // not escaped
) )
{ {
...@@ -1493,6 +1724,36 @@ static void findEndOfLine(GrowBuf &out,const char *data,int size, ...@@ -1493,6 +1724,36 @@ static void findEndOfLine(GrowBuf &out,const char *data,int size,
} }
} }
} }
else if (nb==0 && data[end-1]=='<' && end<size-6 &&
(end<=1 || (data[end-2]!='\\' && data[end-2]!='@'))
)
{
if (tolower(data[end])=='p' && tolower(data[end+1])=='r' &&
tolower(data[end+2])=='e' && data[end+3]=='>') // <pre> tag
{
if (pi!=-1) // output previous line if available
{
out.addStr(data+pi,i-pi);
}
// output part until <pre>
out.addStr(data+i,end-1-i);
// output part until </pre>
i = end-1 + processHtmlTag(out,data+end-1,end-1,size-end+1);
pi=-1;
end = i+1;
break;
}
}
else if (nb==0 && data[end-1]=='`')
{
while (end<size && data[end-1]=='`') end++,nb++;
}
else if (nb>0 && data[end-1]=='`')
{
int enb=0;
while (end<size && data[end-1]=='`') end++,enb++;
if (enb==nb) nb=0;
}
} }
} }
...@@ -1578,17 +1839,38 @@ static QCString processBlocks(const QCString &s,int indent) ...@@ -1578,17 +1839,38 @@ static QCString processBlocks(const QCString &s,int indent)
if (pi!=-1) if (pi!=-1)
{ {
int blockStart,blockEnd,blockOffset;
QCString lang;
blockIndent = indent; blockIndent = indent;
//printf("isHeaderLine(%s)=%d\n",QCString(data+i).left(size-i).data(),level); //printf("isHeaderLine(%s)=%d\n",QCString(data+i).left(size-i).data(),level);
if ((level=isHeaderline(data+i,size-i))>0) if ((level=isHeaderline(data+i,size-i))>0)
{ {
//printf("Found header at %d-%d\n",i,end); //printf("Found header at %d-%d\n",i,end);
while (pi<size && data[pi]==' ') pi++; while (pi<size && data[pi]==' ') pi++;
if (i-pi>1) QCString header,id;
convertStringFragment(header,data+pi,i-pi-1);
id = extractTitleId(header);
if (!header.isEmpty())
{ {
out.addStr(level==1?"<h1>":"<h2>"); if (!id.isEmpty())
out.addStr(data+pi,i-pi-1); {
out.addStr(level==1?"</h1>\n":"</h2>\n"); out.addStr(level==1?"@section ":"@subsection ");
out.addStr(id);
out.addStr(" ");
out.addStr(header);
SectionInfo *si = new SectionInfo(g_fileName,id,header,SectionInfo::Anchor,level);
if (g_current)
{
g_current->anchors->append(si);
}
Doxygen::sectionDict.append(header,si);
}
else
{
out.addStr(level==1?"<h1>":"<h2>");
out.addStr(header);
out.addStr(level==1?"</h1>\n":"</h2>\n");
}
} }
else else
{ {
...@@ -1608,6 +1890,23 @@ static QCString processBlocks(const QCString &s,int indent) ...@@ -1608,6 +1890,23 @@ static QCString processBlocks(const QCString &s,int indent)
pi=-1; pi=-1;
end=i+1; end=i+1;
} }
else if (isFencedCodeBlock(data+pi,size-pi,indent,lang,blockStart,blockEnd,blockOffset))
{
//printf("Found FencedCodeBlock lang='%s' start=%d end=%d code={%s}\n",
// lang.data(),blockStart,blockEnd,QCString(data+pi+blockStart).left(blockEnd-blockStart).data());
out.addStr("@code");
if (!lang.isEmpty() && lang.at(0)=='.') lang=lang.mid(1);
if (!lang.isEmpty())
{
out.addStr("{"+lang+"}");
}
out.addStr(data+pi+blockStart,blockEnd-blockStart);
out.addStr("\n@endcode");
i=pi+blockOffset;
pi=-1;
end=i+1;
continue;
}
else if (isCodeBlock(data+i,i,end-i,blockIndent)) else if (isCodeBlock(data+i,i,end-i,blockIndent))
//if (isCodeBlock(data+pi,pi,end-pi,blockIndent)) //if (isCodeBlock(data+pi,pi,end-pi,blockIndent))
{ {
...@@ -1651,7 +1950,7 @@ static QCString processBlocks(const QCString &s,int indent) ...@@ -1651,7 +1950,7 @@ static QCString processBlocks(const QCString &s,int indent)
return out.get(); return out.get();
} }
static QCString extractPageTitle(QCString &docs) static QCString extractPageTitle(QCString &docs,QCString &id)
{ {
// first first non-empty line // first first non-empty line
QCString title; QCString title;
...@@ -1671,16 +1970,19 @@ static QCString extractPageTitle(QCString &docs) ...@@ -1671,16 +1970,19 @@ static QCString extractPageTitle(QCString &docs)
while (end2<size && data[end2-1]!='\n') end2++; while (end2<size && data[end2-1]!='\n') end2++;
if (isHeaderline(data+end1,size-end1)) if (isHeaderline(data+end1,size-end1))
{ {
convertStringFragment(title,data+i,end1-i); convertStringFragment(title,data+i,end1-i-1);
docs=docs.mid(end2); docs=docs.mid(end2);
id = extractTitleId(title);
//printf("extractPageTitle(title='%s' docs='%s' id='%s')\n",title.data(),docs.data(),id.data());
return title; return title;
} }
} }
if (i<end1 && isAtxHeader(data+i,end1-i,title)>0) if (i<end1 && isAtxHeader(data+i,end1-i,title,id)>0)
{ {
docs=docs.mid(end1); docs=docs.mid(end1);
} }
//printf("extractPageTitle(title='%s' docs='%s')\n",title.data(),docs.data()); id = extractTitleId(title);
//printf("extractPageTitle(title='%s' docs='%s' id='%s')\n",title.data(),docs.data(),id.data());
return title; return title;
} }
...@@ -1727,36 +2029,12 @@ static QCString detab(const QCString &s,int &refIndent) ...@@ -1727,36 +2029,12 @@ static QCString detab(const QCString &s,int &refIndent)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
QCString processMarkdown(const QCString &input) QCString processMarkdown(const QCString &fileName,Entry *e,const QCString &input)
{ {
#if 0
static bool g_init = FALSE;
if (!g_init)
{
g_htmlBlockTags.insert("p",(void*)0x8);
g_htmlBlockTags.insert("dl",(void*)0x8);
g_htmlBlockTags.insert("h1",(void*)0x8);
g_htmlBlockTags.insert("h2",(void*)0x8);
g_htmlBlockTags.insert("h3",(void*)0x8);
g_htmlBlockTags.insert("h4",(void*)0x8);
g_htmlBlockTags.insert("h5",(void*)0x8);
g_htmlBlockTags.insert("h6",(void*)0x8);
g_htmlBlockTags.insert("ol",(void*)0x8);
g_htmlBlockTags.insert("ul",(void*)0x8);
g_htmlBlockTags.insert("div",(void*)0x8);
g_htmlBlockTags.insert("pre",(void*)0x8);
g_htmlBlockTags.insert("form",(void*)0x8);
g_htmlBlockTags.insert("math",(void*)0x8);
g_htmlBlockTags.insert("table",(void*)0x8);
g_htmlBlockTags.insert("iframe",(void*)0x8);
g_htmlBlockTags.insert("script",(void*)0x8);
g_htmlBlockTags.insert("fieldset",(void*)0x8);
g_htmlBlockTags.insert("noscript",(void*)0x8);
g_init=TRUE;
}
#endif
g_linkRefs.setAutoDelete(TRUE); g_linkRefs.setAutoDelete(TRUE);
g_linkRefs.clear(); g_linkRefs.clear();
g_current = e;
g_fileName = fileName;
static GrowBuf out; static GrowBuf out;
if (input.isEmpty()) return input; if (input.isEmpty()) return input;
out.clear(); out.clear();
...@@ -1777,7 +2055,7 @@ QCString processMarkdown(const QCString &input) ...@@ -1777,7 +2055,7 @@ QCString processMarkdown(const QCString &input)
g_actions['@']=processSpecialCommand; g_actions['@']=processSpecialCommand;
g_actions['[']=processLink; g_actions['[']=processLink;
g_actions['!']=processLink; g_actions['!']=processLink;
//g_actions['<']=processHtmlBlock; g_actions['<']=processHtmlTag;
// finally process the inline markup (links, emphasis and code spans) // finally process the inline markup (links, emphasis and code spans)
processInline(out,s,size); processInline(out,s,size);
out.addChar(0); out.addChar(0);
...@@ -1794,10 +2072,11 @@ void MarkdownFileParser::parseInput(const char *fileName, ...@@ -1794,10 +2072,11 @@ void MarkdownFileParser::parseInput(const char *fileName,
Entry *current = new Entry; Entry *current = new Entry;
current->lang = SrcLangExt_Markdown; current->lang = SrcLangExt_Markdown;
QCString docs = fileBuf; QCString docs = fileBuf;
QCString title=extractPageTitle(docs).stripWhiteSpace(); QCString id;
QCString id=extractTitleId(title); QCString title=extractPageTitle(docs,id).stripWhiteSpace();
QCString baseName = substitute(QFileInfo(fileName).baseName().utf8()," ","_"); QCString baseName = substitute(QFileInfo(fileName).baseName().utf8()," ","_");
if (id.isEmpty()) id = "md_"+baseName; if (id.isEmpty()) id = "md_"+baseName;
if (title.isEmpty()) title = baseName;
if (id=="mainpage" || id=="index") if (id=="mainpage" || id=="index")
{ {
docs.prepend("@mainpage "+title+"\n"); docs.prepend("@mainpage "+title+"\n");
......
...@@ -19,8 +19,10 @@ ...@@ -19,8 +19,10 @@
#include <qcstring.h> #include <qcstring.h>
#include "parserintf.h" #include "parserintf.h"
class Entry;
/** processes string \a s and converts markdown into doxygen/html commands. */ /** processes string \a s and converts markdown into doxygen/html commands. */
QCString processMarkdown(const QCString &s); QCString processMarkdown(const QCString &fileName,Entry *e,const QCString &s);
class MarkdownFileParser : public ParserInterface class MarkdownFileParser : public ParserInterface
{ {
......
...@@ -157,6 +157,7 @@ void marshalSectionInfoList(StorageIntf *s, QList<SectionInfo> *anchors) ...@@ -157,6 +157,7 @@ void marshalSectionInfoList(StorageIntf *s, QList<SectionInfo> *anchors)
marshalQCString(s,si->ref); marshalQCString(s,si->ref);
marshalInt(s,(int)si->type); marshalInt(s,(int)si->type);
marshalQCString(s,si->fileName); marshalQCString(s,si->fileName);
marshalInt(s,si->level);
} }
} }
} }
...@@ -195,7 +196,7 @@ void marshalSectionDict(StorageIntf *s,SectionDict *sections) ...@@ -195,7 +196,7 @@ void marshalSectionDict(StorageIntf *s,SectionDict *sections)
else else
{ {
marshalUInt(s,sections->count()); marshalUInt(s,sections->count());
QDictIterator<SectionInfo> sli(*sections); SDict<SectionInfo>::IteratorDict sli(*sections);
SectionInfo *si; SectionInfo *si;
for (sli.toFirst();(si=sli.current());++sli) for (sli.toFirst();(si=sli.current());++sli)
{ {
...@@ -576,7 +577,8 @@ QList<SectionInfo> *unmarshalSectionInfoList(StorageIntf *s) ...@@ -576,7 +577,8 @@ QList<SectionInfo> *unmarshalSectionInfoList(StorageIntf *s)
QCString ref = unmarshalQCString(s); QCString ref = unmarshalQCString(s);
SectionInfo::SectionType type = (SectionInfo::SectionType)unmarshalInt(s); SectionInfo::SectionType type = (SectionInfo::SectionType)unmarshalInt(s);
QCString fileName = unmarshalQCString(s); QCString fileName = unmarshalQCString(s);
result->append(new SectionInfo(fileName,label,title,type,ref)); int level = unmarshalInt(s);
result->append(new SectionInfo(fileName,label,title,type,level,ref));
} }
return result; return result;
} }
...@@ -619,7 +621,7 @@ SectionDict *unmarshalSectionDict(StorageIntf *s) ...@@ -619,7 +621,7 @@ SectionDict *unmarshalSectionDict(StorageIntf *s)
QCString key = unmarshalQCString(s); QCString key = unmarshalQCString(s);
SectionInfo *si = (SectionInfo *)unmarshalObjPointer(s); SectionInfo *si = (SectionInfo *)unmarshalObjPointer(s);
//printf(" unmarshalSectionDict i=%d key=%s si=%s\n",count,key.data(),si->label.data()); //printf(" unmarshalSectionDict i=%d key=%s si=%s\n",count,key.data(),si->label.data());
result->insert(key,si); result->append(key,si);
} }
return result; return result;
} }
......
...@@ -210,6 +210,21 @@ function expandNode(o, node, imm, showRoot) ...@@ -210,6 +210,21 @@ function expandNode(o, node, imm, showRoot)
} }
} }
function highlightAnchor()
{
var anchor = $($(location).attr('hash'));
if (anchor.parent().attr('class')=='memItemLeft'){
var rows = $('.memberdecls tr[class$=\""'+
window.location.hash.substring(1)+'"\"]').children();
rows.effect('highlight',{},1500);
} else if (anchor.parent().is(":header")) {
anchor.parent().effect('highlight',{},1500);
} else {
var targetDiv = anchor.next();
$(targetDiv).children('.memproto,.memdoc').effect("highlight",{},1500);
}
}
function showNode(o, node, index) function showNode(o, node, index)
{ {
if (node.childrenData && !node.expanded) { if (node.childrenData && !node.expanded) {
...@@ -249,15 +264,12 @@ function showNode(o, node, index) ...@@ -249,15 +264,12 @@ function showNode(o, node, index)
if ($(location).attr('hash')) { if ($(location).attr('hash')) {
var link=stripPath($(location).attr('pathname'))+':'+ var link=stripPath($(location).attr('pathname'))+':'+
$(location).attr('hash').substring(1); $(location).attr('hash').substring(1);
a=$('.item a[class*=\""'+link+'"\"]'); a=$('.item a[class$=\""'+link+'"\"]');
} }
if (a && a.length) { if (a && a.length) {
a.parent().parent().addClass('selected'); a.parent().parent().addClass('selected');
a.parent().parent().attr('id','selected'); a.parent().parent().attr('id','selected');
var anchor = $($(location).attr('hash')); highlightAnchor();
var targetDiv = anchor.next();
$(targetDiv).children('.memproto,.memdoc').
effect("highlight", {}, 1500);
} else { } else {
$(n.itemDiv).addClass('selected'); $(n.itemDiv).addClass('selected');
$(n.itemDiv).attr('id','selected'); $(n.itemDiv).attr('id','selected');
...@@ -302,7 +314,8 @@ function initNavTree(toroot,relpath) ...@@ -302,7 +314,8 @@ function initNavTree(toroot,relpath)
getScript(relpath+"navtreeindex",function(){ getScript(relpath+"navtreeindex",function(){
var navTreeIndex = eval('NAVTREEINDEX'); var navTreeIndex = eval('NAVTREEINDEX');
if (navTreeIndex) { if (navTreeIndex) {
o.breadcrumbs = navTreeIndex[toroot]; var nti = navTreeIndex[toroot+window.location.hash];
o.breadcrumbs = nti ? nti : navTreeIndex[toroot];
if (o.breadcrumbs==null) o.breadcrumbs = navTreeIndex["index.html"]; if (o.breadcrumbs==null) o.breadcrumbs = navTreeIndex["index.html"];
o.breadcrumbs.unshift(0); o.breadcrumbs.unshift(0);
showNode(o, o.node, 0); showNode(o, o.node, 0);
...@@ -311,20 +324,12 @@ function initNavTree(toroot,relpath) ...@@ -311,20 +324,12 @@ function initNavTree(toroot,relpath)
$(window).bind('hashchange', function(){ $(window).bind('hashchange', function(){
if (window.location.hash && window.location.hash.length>1){ if (window.location.hash && window.location.hash.length>1){
var anchor = $(window.location.hash); highlightAnchor();
if (anchor.parent().attr('class')=='memItemLeft'){
var rows = $('.memberdecls tr[class$=\""'+
window.location.hash.substring(1)+'"\"]').children();
rows.effect('highlight',{},1500);
} else {
var targetDiv = anchor.next();
$(targetDiv).children('.memproto,.memdoc').effect("highlight",{},1500);
}
var a; var a;
if ($(location).attr('hash')){ if ($(location).attr('hash')){
var link=stripPath($(location).attr('pathname'))+':'+ var link=stripPath($(location).attr('pathname'))+':'+
$(location).attr('hash').substring(1); $(location).attr('hash').substring(1);
a=$('.item a[class*=\""'+link+'"\"]'); a=$('.item a[class$=\""'+link+'"\"]');
} }
if (a && a.length){ if (a && a.length){
$('.item').removeClass('selected'); $('.item').removeClass('selected');
......
...@@ -210,6 +210,21 @@ ...@@ -210,6 +210,21 @@
" }\n" " }\n"
"}\n" "}\n"
"\n" "\n"
"function highlightAnchor()\n"
"{\n"
" var anchor = $($(location).attr('hash'));\n"
" if (anchor.parent().attr('class')=='memItemLeft'){\n"
" var rows = $('.memberdecls tr[class$=\\\"\"'+\n"
" window.location.hash.substring(1)+'\"\\\"]').children();\n"
" rows.effect('highlight',{},1500);\n"
" } else if (anchor.parent().is(\":header\")) {\n"
" anchor.parent().effect('highlight',{},1500);\n"
" } else {\n"
" var targetDiv = anchor.next();\n"
" $(targetDiv).children('.memproto,.memdoc').effect(\"highlight\",{},1500);\n"
" }\n"
"}\n"
"\n"
"function showNode(o, node, index)\n" "function showNode(o, node, index)\n"
"{\n" "{\n"
" if (node.childrenData && !node.expanded) {\n" " if (node.childrenData && !node.expanded) {\n"
...@@ -249,15 +264,12 @@ ...@@ -249,15 +264,12 @@
" if ($(location).attr('hash')) {\n" " if ($(location).attr('hash')) {\n"
" var link=stripPath($(location).attr('pathname'))+':'+\n" " var link=stripPath($(location).attr('pathname'))+':'+\n"
" $(location).attr('hash').substring(1);\n" " $(location).attr('hash').substring(1);\n"
" a=$('.item a[class*=\\\"\"'+link+'\"\\\"]');\n" " a=$('.item a[class$=\\\"\"'+link+'\"\\\"]');\n"
" }\n" " }\n"
" if (a && a.length) {\n" " if (a && a.length) {\n"
" a.parent().parent().addClass('selected');\n" " a.parent().parent().addClass('selected');\n"
" a.parent().parent().attr('id','selected');\n" " a.parent().parent().attr('id','selected');\n"
" var anchor = $($(location).attr('hash'));\n" " highlightAnchor();\n"
" var targetDiv = anchor.next();\n"
" $(targetDiv).children('.memproto,.memdoc').\n"
" effect(\"highlight\", {}, 1500);\n"
" } else {\n" " } else {\n"
" $(n.itemDiv).addClass('selected');\n" " $(n.itemDiv).addClass('selected');\n"
" $(n.itemDiv).attr('id','selected');\n" " $(n.itemDiv).attr('id','selected');\n"
...@@ -302,7 +314,8 @@ ...@@ -302,7 +314,8 @@
" getScript(relpath+\"navtreeindex\",function(){\n" " getScript(relpath+\"navtreeindex\",function(){\n"
" var navTreeIndex = eval('NAVTREEINDEX');\n" " var navTreeIndex = eval('NAVTREEINDEX');\n"
" if (navTreeIndex) {\n" " if (navTreeIndex) {\n"
" o.breadcrumbs = navTreeIndex[toroot];\n" " var nti = navTreeIndex[toroot+window.location.hash];\n"
" o.breadcrumbs = nti ? nti : navTreeIndex[toroot];\n"
" if (o.breadcrumbs==null) o.breadcrumbs = navTreeIndex[\"index.html\"];\n" " if (o.breadcrumbs==null) o.breadcrumbs = navTreeIndex[\"index.html\"];\n"
" o.breadcrumbs.unshift(0);\n" " o.breadcrumbs.unshift(0);\n"
" showNode(o, o.node, 0);\n" " showNode(o, o.node, 0);\n"
...@@ -311,20 +324,12 @@ ...@@ -311,20 +324,12 @@
"\n" "\n"
" $(window).bind('hashchange', function(){\n" " $(window).bind('hashchange', function(){\n"
" if (window.location.hash && window.location.hash.length>1){\n" " if (window.location.hash && window.location.hash.length>1){\n"
" var anchor = $(window.location.hash);\n" " highlightAnchor();\n"
" if (anchor.parent().attr('class')=='memItemLeft'){\n"
" var rows = $('.memberdecls tr[class$=\\\"\"'+\n"
" window.location.hash.substring(1)+'\"\\\"]').children();\n"
" rows.effect('highlight',{},1500);\n"
" } else {\n"
" var targetDiv = anchor.next();\n"
" $(targetDiv).children('.memproto,.memdoc').effect(\"highlight\",{},1500);\n"
" }\n"
" var a;\n" " var a;\n"
" if ($(location).attr('hash')){\n" " if ($(location).attr('hash')){\n"
" var link=stripPath($(location).attr('pathname'))+':'+\n" " var link=stripPath($(location).attr('pathname'))+':'+\n"
" $(location).attr('hash').substring(1);\n" " $(location).attr('hash').substring(1);\n"
" a=$('.item a[class*=\\\"\"'+link+'\"\\\"]');\n" " a=$('.item a[class$=\\\"\"'+link+'\"\\\"]');\n"
" }\n" " }\n"
" if (a && a.length){\n" " if (a && a.length){\n"
" $('.item').removeClass('selected');\n" " $('.item').removeClass('selected');\n"
......
...@@ -120,8 +120,8 @@ class ParserManager ...@@ -120,8 +120,8 @@ class ParserManager
* @param[in] name A symbolic name of the parser, i.e. "c", * @param[in] name A symbolic name of the parser, i.e. "c",
* "python", "fortran", "vhdl", ... * "python", "fortran", "vhdl", ...
* @param[in] parser The parser that is to be used for the * @param[in] parser The parser that is to be used for the
* given extension. * given name.
* @param[in] defParser Use this parser as the default parser, using * @param[in] defParser Use this parser as the default parser, used
* for unregistered file extensions. * for unregistered file extensions.
*/ */
void registerParser(const char *name,ParserInterface *parser,bool defParser=FALSE) void registerParser(const char *name,ParserInterface *parser,bool defParser=FALSE)
......
...@@ -328,13 +328,18 @@ void RTFDocVisitor::visit(DocVerbatim *s) ...@@ -328,13 +328,18 @@ void RTFDocVisitor::visit(DocVerbatim *s)
{ {
if (m_hide) return; if (m_hide) return;
DBG_RTF("{\\comment RTFDocVisitor::visit(DocVerbatim)}\n"); DBG_RTF("{\\comment RTFDocVisitor::visit(DocVerbatim)}\n");
QCString lang = m_langExt;
if (!s->language().isEmpty()) // explicit language setting
{
lang = s->language();
}
switch(s->type()) switch(s->type())
{ {
case DocVerbatim::Code: // fall though case DocVerbatim::Code: // fall though
m_t << "{" << endl; m_t << "{" << endl;
m_t << "\\par" << endl; m_t << "\\par" << endl;
m_t << rtf_Style_Reset << getStyle("CodeExample"); m_t << rtf_Style_Reset << getStyle("CodeExample");
Doxygen::parserManager->getParser(m_langExt) Doxygen::parserManager->getParser(lang)
->parseCode(m_ci,s->context(),s->text(), ->parseCode(m_ci,s->context(),s->text(),
s->isExample(),s->exampleFile()); s->isExample(),s->exampleFile());
//m_t << "\\par" << endl; //m_t << "\\par" << endl;
......
...@@ -69,6 +69,7 @@ static int lastPreLineCtrlContext; ...@@ -69,6 +69,7 @@ static int lastPreLineCtrlContext;
static int lastSkipVerbStringContext; static int lastSkipVerbStringContext;
static int lastCommentInArgContext; static int lastCommentInArgContext;
static int lastCSConstraint; static int lastCSConstraint;
static int lastHereDocContext;
static Protection protection; static Protection protection;
static Protection baseProt; static Protection baseProt;
static int sharpCount = 0 ; static int sharpCount = 0 ;
...@@ -138,6 +139,7 @@ static QCString *pCopyCurlyString; ...@@ -138,6 +139,7 @@ static QCString *pCopyCurlyString;
static QGString *pCopyCurlyGString; static QGString *pCopyCurlyGString;
static QGString *pCopyRoundGString; static QGString *pCopyRoundGString;
static QGString *pCopyQuotedGString; static QGString *pCopyQuotedGString;
static QGString *pCopyHereDocGString;
static QGString *pSkipVerbString; static QGString *pSkipVerbString;
static QStack<Grouping> autoGroupStack; static QStack<Grouping> autoGroupStack;
...@@ -698,6 +700,8 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -698,6 +700,8 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
%x CopyArgVerbatim %x CopyArgVerbatim
%x HereDoc %x HereDoc
%x HereDocEnd %x HereDocEnd
%x CopyHereDoc
%x CopyHereDocEnd
%x IDLAttribute %x IDLAttribute
%x IDLProp %x IDLProp
...@@ -1833,13 +1837,14 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -1833,13 +1837,14 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
else else
BEGIN( EndTemplate ); BEGIN( EndTemplate );
} }
<EndTemplate>"<<<" { <EndTemplate>"<<<" {
if (!insidePHP) if (!insidePHP)
{ {
REJECT; REJECT;
} }
else else
{ {
lastHereDocContext = YY_START;
BEGIN(HereDoc); BEGIN(HereDoc);
} }
} }
...@@ -1922,20 +1927,44 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -1922,20 +1927,44 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
else else
REJECT; REJECT;
} }
<CopyHereDoc>{ID} { // PHP heredoc
g_hereDocId = yytext;
*pCopyHereDocGString += yytext;
BEGIN(CopyHereDocEnd);
}
<CopyHereDoc>"'"{ID}/"'" { // PHP nowdoc
g_hereDocId = &yytext[1];
*pCopyHereDocGString += yytext;
BEGIN(CopyHereDocEnd);
}
<HereDoc>{ID} { // PHP heredoc <HereDoc>{ID} { // PHP heredoc
g_hereDocId = yytext; g_hereDocId = yytext;
BEGIN(HereDocEnd); BEGIN(HereDocEnd);
} }
<HereDoc>"'"{ID}/"'" { // PHP nowdoc <HereDoc>"'"{ID}/"'" { // PHP nowdoc
g_hereDocId = &yytext[1]; g_hereDocId = &yytext[1];
BEGIN(HereDocEnd);
} }
<HereDocEnd>^{ID} { // id at start of the line could mark the end of the block <HereDocEnd>^{ID} { // id at start of the line could mark the end of the block
if (g_hereDocId==yytext) // it is the end marker if (g_hereDocId==yytext) // it is the end marker
{ {
BEGIN(FindMembers); BEGIN(lastHereDocContext);
} }
} }
<HereDocEnd>. { } <HereDocEnd>. { }
<CopyHereDocEnd>^{ID} { // id at start of the line could mark the end of the block
*pCopyHereDocGString += yytext;
if (g_hereDocId==yytext) // it is the end marker
{
BEGIN(lastHereDocContext);
}
}
<CopyHereDocEnd>\n {
*pCopyHereDocGString += yytext;
}
<CopyHereDocEnd>. {
*pCopyHereDocGString += yytext;
}
<FindMembers>"Q_OBJECT" { // Qt object macro <FindMembers>"Q_OBJECT" { // Qt object macro
} }
<FindMembers>"Q_PROPERTY" { // Qt property declaration <FindMembers>"Q_PROPERTY" { // Qt property declaration
...@@ -3130,7 +3159,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -3130,7 +3159,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
/* /*
<FindFieldArg>"," { unput(*yytext); BEGIN(FindFields); } <FindFieldArg>"," { unput(*yytext); BEGIN(FindFields); }
*/ */
<ReadBody,ReadNSBody,ReadBodyIntf>[^\r\n\#{}"@'/]* { current->program += yytext ; } <ReadBody,ReadNSBody,ReadBodyIntf>[^\r\n\#{}"@'/<]* { current->program += yytext ; }
<ReadBody,ReadNSBody,ReadBodyIntf>"//".* { current->program += yytext ; } <ReadBody,ReadNSBody,ReadBodyIntf>"//".* { current->program += yytext ; }
<ReadBody,ReadNSBody,ReadBodyIntf>"#".* { if (!insidePHP) <ReadBody,ReadNSBody,ReadBodyIntf>"#".* { if (!insidePHP)
REJECT; REJECT;
...@@ -3142,6 +3171,18 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -3142,6 +3171,18 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
lastSkipVerbStringContext=YY_START; lastSkipVerbStringContext=YY_START;
BEGIN( SkipVerbString ); BEGIN( SkipVerbString );
} }
<ReadBody,ReadNSBody,ReadBodyIntf>"<<<" { if (insidePHP)
{
current->program += yytext ;
pCopyHereDocGString = &current->program;
lastHereDocContext=YY_START;
BEGIN( CopyHereDoc );
}
else
{
REJECT;
}
}
<ReadBody,ReadNSBody,ReadBodyIntf>\" { current->program += yytext ; <ReadBody,ReadNSBody,ReadBodyIntf>\" { current->program += yytext ;
pCopyQuotedGString = &current->program; pCopyQuotedGString = &current->program;
lastStringContext=YY_START; lastStringContext=YY_START;
...@@ -4470,7 +4511,18 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -4470,7 +4511,18 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
yyLineNr++; yyLineNr++;
//addToBody(yytext); //addToBody(yytext);
} }
<SkipCurly,SkipCurlyCpp>[^\n#"'@\\/{}]+ { <SkipCurly,SkipCurlyCpp>"<<<" {
if (!insidePHP)
{
REJECT;
}
else
{
lastHereDocContext = YY_START;
BEGIN(HereDoc);
}
}
<SkipCurly,SkipCurlyCpp>[^\n#"'@\\/{}<]+ {
//addToBody(yytext); //addToBody(yytext);
} }
<SkipCurlyCpp>\n { <SkipCurlyCpp>\n {
......
...@@ -28,13 +28,17 @@ class Definition; ...@@ -28,13 +28,17 @@ class Definition;
struct SectionInfo struct SectionInfo
{ {
enum SectionType { Page, Section, Subsection, enum SectionType { Page = 0,
Subsubsection, Paragraph, Anchor Section = 1,
Subsection = 2,
Subsubsection = 3,
Paragraph = 4,
Anchor = 5
}; };
SectionInfo(const char *f,const char *l,const char *t, SectionInfo(const char *f,const char *l,const char *t,
SectionType st,const char *r=0) : SectionType st,int lev,const char *r=0) :
label(l), title(t), type(st), ref(r), definition(0), label(l), title(t), type(st), ref(r), definition(0),
fileName(f), generated(FALSE) fileName(f), generated(FALSE), level(lev)
{ {
} }
SectionInfo(const SectionInfo &s) SectionInfo(const SectionInfo &s)
...@@ -51,12 +55,13 @@ struct SectionInfo ...@@ -51,12 +55,13 @@ struct SectionInfo
Definition *definition; Definition *definition;
QCString fileName; QCString fileName;
bool generated; bool generated;
int level;
}; };
class SectionDict : public QDict<SectionInfo> class SectionDict : public SDict<SectionInfo>
{ {
public: public:
SectionDict(int size) : QDict<SectionInfo>(size) {} SectionDict(int size) : SDict<SectionInfo>(size) {}
~SectionDict() {} ~SectionDict() {}
}; };
......
...@@ -1035,8 +1035,8 @@ void TagFileParser::addDocAnchors(Entry *e,const TagAnchorInfoList &l) ...@@ -1035,8 +1035,8 @@ void TagFileParser::addDocAnchors(Entry *e,const TagAnchorInfoList &l)
//printf("New sectionInfo file=%s anchor=%s\n", //printf("New sectionInfo file=%s anchor=%s\n",
// ta->fileName.data(),ta->label.data()); // ta->fileName.data(),ta->label.data());
SectionInfo *si=new SectionInfo(ta->fileName,ta->label,ta->label, SectionInfo *si=new SectionInfo(ta->fileName,ta->label,ta->label,
SectionInfo::Anchor,m_tagName); SectionInfo::Anchor,0,m_tagName);
Doxygen::sectionDict.insert(ta->label,si); Doxygen::sectionDict.append(ta->label,si);
e->anchors->append(si); e->anchors->append(si);
} }
else else
......
...@@ -5908,13 +5908,13 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle, ...@@ -5908,13 +5908,13 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle,
file=pd->getOutputFileBase(); file=pd->getOutputFileBase();
} }
SectionInfo *si=new SectionInfo( SectionInfo *si=new SectionInfo(
file,pd->name(),pd->title(),SectionInfo::Page,pd->getReference()); file,pd->name(),pd->title(),SectionInfo::Page,0,pd->getReference());
//printf("si->label=`%s' si->definition=%s si->fileName=`%s'\n", //printf("si->label=`%s' si->definition=%s si->fileName=`%s'\n",
// si->label.data(),si->definition?si->definition->name().data():"<none>", // si->label.data(),si->definition?si->definition->name().data():"<none>",
// si->fileName.data()); // si->fileName.data());
//printf(" SectionInfo: sec=%p sec->fileName=%s\n",si,si->fileName.data()); //printf(" SectionInfo: sec=%p sec->fileName=%s\n",si,si->fileName.data());
//printf("Adding section key=%s si->fileName=%s\n",pageName.data(),si->fileName.data()); //printf("Adding section key=%s si->fileName=%s\n",pageName.data(),si->fileName.data());
Doxygen::sectionDict.insert(pd->name(),si); Doxygen::sectionDict.append(pd->name(),si);
} }
} }
return pd; return pd;
...@@ -6303,6 +6303,7 @@ bool updateLanguageMapping(const QCString &extension,const QCString &language) ...@@ -6303,6 +6303,7 @@ bool updateLanguageMapping(const QCString &extension,const QCString &language)
void initDefaultExtensionMapping() void initDefaultExtensionMapping()
{ {
g_extLookup.setAutoDelete(TRUE); g_extLookup.setAutoDelete(TRUE);
// extension parser id
updateLanguageMapping(".idl", "idl"); updateLanguageMapping(".idl", "idl");
updateLanguageMapping(".ddl", "idl"); updateLanguageMapping(".ddl", "idl");
updateLanguageMapping(".odl", "idl"); updateLanguageMapping(".odl", "idl");
...@@ -7166,20 +7167,21 @@ QCString langToString(SrcLangExt lang) ...@@ -7166,20 +7167,21 @@ QCString langToString(SrcLangExt lang)
{ {
switch(lang) switch(lang)
{ {
case SrcLangExt_Unknown: return "Unknown"; case SrcLangExt_Unknown: return "Unknown";
case SrcLangExt_IDL: return "IDL"; case SrcLangExt_IDL: return "IDL";
case SrcLangExt_Java: return "Java"; case SrcLangExt_Java: return "Java";
case SrcLangExt_CSharp: return "C#"; case SrcLangExt_CSharp: return "C#";
case SrcLangExt_D: return "D"; case SrcLangExt_D: return "D";
case SrcLangExt_PHP: return "PHP"; case SrcLangExt_PHP: return "PHP";
case SrcLangExt_ObjC: return "Objective-C"; case SrcLangExt_ObjC: return "Objective-C";
case SrcLangExt_Cpp: return "C++"; case SrcLangExt_Cpp: return "C++";
case SrcLangExt_JS: return "Javascript"; case SrcLangExt_JS: return "Javascript";
case SrcLangExt_Python: return "Python"; case SrcLangExt_Python: return "Python";
case SrcLangExt_Fortran: return "Fortran"; case SrcLangExt_Fortran: return "Fortran";
case SrcLangExt_VHDL: return "VHDL"; case SrcLangExt_VHDL: return "VHDL";
case SrcLangExt_XML: return "XML"; case SrcLangExt_XML: return "XML";
case SrcLangExt_Tcl: return "Tcl"; case SrcLangExt_Tcl: return "Tcl";
case SrcLangExt_Markdown: return "Markdown";
} }
return "Unknown"; return "Unknown";
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment