diff options
52 files changed, 2880 insertions, 604 deletions
@@ -1,7 +1,7 @@ -DOXYGEN Version 1.7.6.1-20120110 +DOXYGEN Version 1.7.6.1-20120122 Please read the installation section of the manual (http://www.doxygen.org/install.html) for instructions. -------- -Dimitri van Heesch (10 January 2012) +Dimitri van Heesch (22 January 2012) @@ -1,4 +1,4 @@ -DOXYGEN Version 1.7.6.1_20120110 +DOXYGEN Version 1.7.6.1_20120122 Please read INSTALL for compilation instructions. @@ -26,4 +26,4 @@ forum. 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 doxygen_version_revision=6.1 #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"` diff --git a/doc/Doxyfile b/doc/Doxyfile index 74ed73d..0d1381e 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -19,19 +19,21 @@ HTML_FOOTER = QUIET = NO WARNINGS = YES DISABLE_INDEX = YES +GENERATE_TREEVIEW = YES EXTRACT_ALL = NO EXTRACT_PRIVATE = NO GENERATE_MAN = NO GENERATE_LATEX = YES GENERATE_HTML = YES -GENERATE_HTMLHELP = YES +GENERATE_HTMLHELP = NO GENERATE_RTF = NO GENERATE_XML = NO +HTML_COLORSTYLE_SAT = 0 ENABLED_SECTIONS = logo_on ENABLE_PREPROCESSING = NO CASE_SENSE_NAMES = NO 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 \ autolink.doc output.doc searching.doc customize.doc custcmd.doc \ external.doc faq.doc trouble.doc features.doc \ @@ -48,3 +50,4 @@ SEARCHENGINE = NO PDF_HYPERLINKS = YES USE_PDFLATEX = YES STRIP_CODE_COMMENTS = NO +HTML_STYLESHEET = doxygen_manual.css diff --git a/doc/autolink.doc b/doc/autolink.doc index 4eb4989..1f4b617 100644 --- a/doc/autolink.doc +++ b/doc/autolink.doc @@ -38,7 +38,7 @@ \verbatim <a href="linkURL">link text</a> \endverbatim 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 contain at least one non-lower case character will automatically be @@ -48,14 +48,14 @@ should put a \% in front of the word. 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 in the word are considered to be file names. If the word is indeed the name of a documented input file, a link will 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 encountered: @@ -101,7 +101,7 @@ that matches the pattern. </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 previous section. For sake of clarity it is advised to only use diff --git a/doc/commands.doc b/doc/commands.doc index 0b1db8c..ad6b2ba 100644 --- a/doc/commands.doc +++ b/doc/commands.doc @@ -2140,13 +2140,35 @@ Commands for visual enhancements To have multiple words in typewriter font use \<tt\>multiple words\</tt\>. <hr> -\section cmdcode \\code +\section cmdcode \\code [ '{'<word>'}'] \addindex \\code 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 - classes and members that are documented are automatically replaced by - links to the documentation. + from ordinary text. It is interpreted as source code. The names of + classes and members and other documented entities are automatically + 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". diff --git a/doc/docblocks.doc b/doc/docblocks.doc index bf0466a..093122b 100644 --- a/doc/docblocks.doc +++ b/doc/docblocks.doc @@ -16,19 +16,30 @@ */ /*! \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 -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. +\section specialblock Special comment blocks -For each code item there are two (or in some cases three) types of descriptions, -which together form the documentation: a \e brief description and \e detailed +A special comment block is a C or C++ style comment block with some +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 -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. 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, more detailed documentation. An "in body" description can also act as a detailed description or can describe a collection of implementation details. 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: <ol> @@ -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 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 the documentation of members (including global functions) in front of @@ -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 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, -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 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 @@ -275,7 +242,7 @@ or int var; ///< Brief description after the member \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> to document the direction. For inline documentation this is also possible by starting with the direction attribute, e.g. @@ -302,11 +269,54 @@ Here is an example of the use of these comment blocks: (like <code>\\class</code>) are not allowed 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 -\e front of the declaration or definition of a file, class or namespace or in -front or after one of its members. +In the examples in the previous section the comment blocks were always located *in +front* of the declaration or definition of a file, class or namespace or *in +front* or *after* one of its members. Although this is often comfortable, there may sometimes be reasons to put the documentation somewhere else. For documenting a file this is even 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 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 (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, followed by a command name and one or more parameters. For instance, if you want to document the class \c Test in the example @@ -384,7 +394,7 @@ using structural commands: 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. -\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 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 <a href="index.html">index</a>. \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 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 were not already set correctly doxygen will produce a warning telling which settings where overruled. -\section fortranblocks Special documentation blocks in Fortran +\subsection fortranblocks Comment blocks in Fortran When using doxygen for Fortran code you should set \ref cfg_optimize_for_fortran "OPTIMIZE_FOR_FORTRAN" to \c YES. @@ -481,7 +491,7 @@ C> input parameter end function A \endverbatim -\section tclblocks Documentation blocks in Tcl +\subsection tclblocks Comment blocks in Tcl 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 <a href="index.html">index</a>. \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. + */ diff --git a/doc/doxygen.sty b/doc/doxygen.sty index 44becf8..c64fb09 100644 --- a/doc/doxygen.sty +++ b/doc/doxygen.sty @@ -39,8 +39,8 @@ \fancyhead[RO]{\fancyplain{}{\bfseries\thepage}} \fancyfoot[LE]{\fancyplain{}{}} \fancyfoot[CE]{\fancyplain{}{}} -\fancyfoot[RE]{\fancyplain{}{\bfseries\scriptsize Generated on Fri Dec 16 2011 21\-:40\-:27 for My Project by Doxygen }} -\fancyfoot[LO]{\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 by Doxygen }} \fancyfoot[CO]{\fancyplain{}{}} \fancyfoot[RO]{\fancyplain{}{}} %---------- Internal commands used in this style file ---------------- diff --git a/doc/doxygen_manual.css b/doc/doxygen_manual.css new file mode 100644 index 0000000..8dfe6dd --- /dev/null +++ b/doc/doxygen_manual.css @@ -0,0 +1,977 @@ +/* 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+ */ + } +} + diff --git a/doc/doxygen_manual.tex b/doc/doxygen_manual.tex index 010ba4c..54898e8 100644 --- a/doc/doxygen_manual.tex +++ b/doc/doxygen_manual.tex @@ -18,6 +18,7 @@ \usepackage{graphicx} \usepackage{multicol} \usepackage{float} +\usepackage{geometry} \usepackage{listings} \usepackage{color} \usepackage{ifthen} @@ -79,7 +80,7 @@ Written by Dimitri van Heesch\\[2ex] \chapter{Installation}\label{install}\hypertarget{install}{}\input{install} \chapter{Getting Started}\label{starting}\hypertarget{starting}{}\input{starting} \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{Including Formulas}\label{formulas}\hypertarget{formulas}{}\input{formulas} \chapter{Graphs and diagrams}\label{diagrams}\hypertarget{diagrams}{}\input{diagrams} diff --git a/doc/features.doc b/doc/features.doc index 12de7b9..688a1b1 100644 --- a/doc/features.doc +++ b/doc/features.doc @@ -19,25 +19,26 @@ \addindex features <UL> <li>Requires very little overhead from the writer of the documentation. - Plain text will do, but for more fancy or structured output HTML tags - and/or some of doxygen's special commands can be used. -<li>Cross platform: works on Windows and many Unices (including Linux and + Plain text will do, Markdown is support, and for more fancy or + structured output HTML tags and/or some of doxygen's special commands + can be used. +<li>Cross platform: works on Windows and many Unix flavors (including Linux and MacOSX). <li>Indexes, organizes and generates browsable and cross-referenced output even from undocumented code. <li>Generates structured XML output for parsed sources, which can be used by external tools. <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, structs, unions, templates, variables, functions, typedefs, enums and defines. <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. - The GUI is available on Windows, Linux, and MacOSX. +<li>Comes with a GUI frontend (Doxywizard) to ease editing the options and + run doxygen. The GUI is available on Windows, Linux, and MacOSX. <li>Automatically generates class and collaboration diagrams in HTML (as clickable 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 graphs, and graphical class hierarchy graphs. <li>Allows grouping of entities in modules and creating a hierarchy of modules. diff --git a/doc/index.doc b/doc/index.doc index 9d10829..48f01e6 100644 --- a/doc/index.doc +++ b/doc/index.doc @@ -14,7 +14,7 @@ * input used in their production; they are not affected by this license. * */ -/*! \mainpage +/*! \mainpage Doxygen Manual \if logo_on <center> \htmlonly @@ -44,7 +44,7 @@ It can help you in three ways: You can also visualize the relations between the various elements by means of include dependency graphs, inheritance diagrams, 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). </ol> @@ -65,7 +65,7 @@ The first part forms a user manual: documentation quickly. <li>Section \ref docblocks demonstrates the various ways that code can 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 formulas shows how to insert formulas in the documentation. <li>Section \ref diagrams describes the diagrams and graphs that doxygen can generate. diff --git a/doc/infoflow.gif b/doc/infoflow.gif Binary files differdeleted file mode 100644 index 82fc46e..0000000 --- a/doc/infoflow.gif +++ /dev/null diff --git a/doc/infoflow.png b/doc/infoflow.png Binary files differnew file mode 100644 index 0000000..d975be1 --- /dev/null +++ b/doc/infoflow.png diff --git a/doc/install.doc b/doc/install.doc index 6524750..6a18784 100644 --- a/doc/install.doc +++ b/doc/install.doc @@ -19,7 +19,6 @@ \addindex installation First go to the <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. This section is divided into the following sections: @@ -45,7 +44,6 @@ following to build the executable: \addindex strip <li>In order to generate a Makefile for your platform, you need <a href="http://www.perl.com/">perl</a> - \latexonly(see {\tt http://www.perl.com/})\endlatexonly. \addindex perl <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. @@ -57,17 +55,14 @@ tools should be installed. <ul> <li>Qt Software's GUI toolkit <a href="http://qt.nokia.com/">Qt</A> - \latexonly(see {\tt http://qt.nokia.com/})\endlatexonly \addindex Qt version 4.3 or higher. This is needed to build the GUI front-end doxywizard. <li>A \f$\mbox{\LaTeX}\f$ distribution: for instance <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. <li><a href="http://www.graphviz.org/"> 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, the graphical inheritance graphs, and the collaboration graphs. If you compile graphviz yourself, make sure you do include @@ -83,18 +78,14 @@ tools should be installed. Compilation is now done by performing the following steps: <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 - tar xf doxygen-$VERSION.src.tar # unpack it -\endverbatim + gunzip doxygen-$VERSION.src.tar.gz # uncompress the archive + tar xf doxygen-$VERSION.src.tar # unpack it <li>Run the configure script: -\verbatim - sh ./configure -\endverbatim + sh ./configure The script tries to determine the platform you use, the make tool (which \e must be GNU make) and the perl @@ -103,9 +94,7 @@ Compilation is now done by performing the following steps: To override the auto detected platform and compiler you can run configure as follows: -\verbatim - configure --platform platform-type -\endverbatim + configure --platform platform-type See the <code>PLATFORMS</code> file for a list of possible platform options. @@ -114,21 +103,15 @@ Compilation is now done by performing the following steps: front-end, you should run the configure script with the <code>--with-doxywizard</code> option: -\verbatim - configure --with-doxywizard -\endverbatim + configure --with-doxywizard For an overview of other configuration options use -\verbatim - configure --help -\endverbatim + configure --help <li>Compile the program by running make: -\verbatim - make -\endverbatim + make The program should compile without problems and the binaries (<code>doxygen</code> and optionally <code>doxywizard</code>) @@ -136,9 +119,7 @@ Compilation is now done by performing the following steps: <li>Optional: Generate the user manual. -\verbatim - make docs -\endverbatim + make docs To let doxygen generate the HTML documentation. @@ -152,9 +133,7 @@ Compilation is now done by performing the following steps: (you will need <code>pdflatex</code>, <code>makeindex</code>, and <code>egrep</code> for this). -\verbatim - make pdf -\endverbatim + make pdf The PDF manual <code>doxygen_manual.pdf</code> will be located in the latex directory of the distribution. Just @@ -168,10 +147,8 @@ Compilation is now done by performing the following steps: to install doxygen. If you downloaded the binary distribution for UNIX, type: -\verbatim - ./configure - make install -\endverbatim + ./configure + make install Binaries are installed into the directory <code>\<prefix\>/bin</code>. Use <code>make install_docs</code> to install the @@ -204,14 +181,13 @@ directory pointed to by QTDIR on some systems libs are in /usr/lib). The solution: go to the root of the doxygen distribution and do: -\verbatim - mkdir qt - cd qt - ln -s your-qt-include-dir-here include - ln -s your-qt-lib-dir-here lib - ln -s your-qt-bin-dir-here bin - export QTDIR=$PWD -\endverbatim + + mkdir qt + cd qt + ln -s your-qt-include-dir-here include + ln -s your-qt-lib-dir-here lib + ln -s your-qt-bin-dir-here bin + export QTDIR=$PWD If you have a csh-like shell you should use <code>setenv QTDIR \$PWD</code> instead of the <code>export</code> command above. @@ -239,24 +215,23 @@ config file). <b>HP-UX \& Digital UNIX problems</b> If you are compiling for HP-UX with aCC and you get this error: -\verbatim + /opt/aCC/lbin/ld: Unsatisfied symbols: alloca (code) -\endverbatim - then you should (according to Anke Selig) edit <code>ce_parse.cpp</code> - and replace -\verbatim + +then you should (according to Anke Selig) edit <code>ce_parse.cpp</code> +and replace + extern "C" { void *alloca (unsigned int); }; -\endverbatim - with -\verbatim + +with + #include <alloca.h> -\endverbatim - If that does not help, try removing <code>ce_parse.cpp</code> and let - bison rebuild it (this worked for me). +If that does not help, try removing <code>ce_parse.cpp</code> and let +bison rebuild it (this worked for me). If you are compiling for Digital UNIX, the same problem can be solved (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 it does work and installing Sun patch 111679-13 has also been reported as a way to fix the problem. -when configuring with <code>--static</code> I got: +when configuring with `--static` I got: \verbatim Undefined first referenced @@ -318,13 +293,11 @@ dlsym /usr/lib/libc.a(nss_deffinder.o) dlopen /usr/lib/libc.a(nss_deffinder.o) \endverbatim -Manually adding <code>-Bdynamic</code> after the target rule in -<code>Makefile.doxygen</code> will fix this: +Manually adding `-Bdynamic` after the target rule in +`Makefile.doxygen` will fix this: -\verbatim -$(TARGET): $(OBJECTS) $(OBJMOC) - $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) -Bdynamic -\endverbatim + $(TARGET): $(OBJECTS) $(OBJMOC) + $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) -Bdynamic <b>GCC compiler problems</b> @@ -456,11 +429,9 @@ Here is what is required: <li>The GNU tools flex, bison, and sed. To get these working on Windows you should install the <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 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. As a third alternative one could use the GNUWin32 tools that can be @@ -648,7 +619,6 @@ features: <li><a href="http://www.graphviz.org/"> 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, and the collaboration graphs. </ul> diff --git a/doc/lists.doc b/doc/lists.doc index f72957e..89b21e8 100644 --- a/doc/lists.doc +++ b/doc/lists.doc @@ -4,15 +4,16 @@ Doxygen provides a number of ways to create lists of items. <b>Using dashes</b> - 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 - sign also plus (+) or asterix (\*) can be used. +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 +sign also plus (+) or asterix (\*) can be used. - Numbered lists can also be generated by using a minus followed by a hash - or by using a number followed by a dot. +Numbered lists can also be generated by using a minus followed by a hash +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 /*! * A list of events: diff --git a/doc/markdown.doc b/doc/markdown.doc new file mode 100644 index 0000000..ea6776e --- /dev/null +++ b/doc/markdown.doc @@ -0,0 +1,607 @@ +/****************************************************************************** + * + * + * + * 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. + +*/ diff --git a/doc/output.doc b/doc/output.doc index 0661670..f2c742c 100644 --- a/doc/output.doc +++ b/doc/output.doc @@ -16,8 +16,6 @@ */ /*! \page output Output Formats -\section output_sec Output Formats - \addindex output formats 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> <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 - 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> <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> 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> <dd>Generated by Qt's qhelpgenerator tool from the HTML output if \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> <dd>Generated from the \f$\mbox{\LaTeX}\f$ output by running <code>make ps</code> in the output directory. diff --git a/doc/perlmod.doc b/doc/perlmod.doc index 9c0d79f..b375e15 100644 --- a/doc/perlmod.doc +++ b/doc/perlmod.doc @@ -1,4 +1,4 @@ -/*! \page perlmod Perl Module output format documentation +/*! \page perlmod Perl Module Output \addindex perlmod @@ -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 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, 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 Doxygen. See \ref doxydocs_format "below" for details on how 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 incomplete at the moment, but you could find it useful nevertheless. @@ -98,7 +98,7 @@ rules added to <b>doxyrules.make</b>. </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 packages used by <b>doxylatex.tex</b>. @@ -133,7 +133,7 @@ in DVI format. </ol> -\section doxydocs_format Perl Module documentation format. +\section doxydocs_format Documentation format. <p>The Perl Module documentation generated by Doxygen is stored in <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 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 in <b>DoxyDocs.pm</b> without needing to take into account the diff --git a/doc/perlmod_tree.doc b/doc/perlmod_tree.doc index e2b1366..be71315 100644 --- a/doc/perlmod_tree.doc +++ b/doc/perlmod_tree.doc @@ -1,4 +1,4 @@ -/*! \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 format.</h2> diff --git a/doc/starting.doc b/doc/starting.doc index 4e60d3a..a60093f 100644 --- a/doc/starting.doc +++ b/doc/starting.doc @@ -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 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 \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 you should assign the root directory or directories to the \ref cfg_input "INPUT" tag, and add one or more file 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 -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 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 \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: + \verbatim EXCLUDE_PATTERNS = */test/* \endverbatim -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 -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 -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>, -<code>.inc</code> or <code>.phtml</code> are treated as PHP sources. -Any other extension is parsed as if it is a C/C++ file, where files that -end with <code>.m</code> are treated as Objective-C source files. +Doxygen looks at the file's extension to determine how to parse a file, +using the following table: + +Extension | Language +---------:|--------- +.idl |IDL +.ddl |IDL +.odl |IDL +.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 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). 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 a browser that supports cascading style sheets (CSS) should be used -(I'm using Mozilla, Safari, Konqueror, and sometimes IE6 to test the -generated output). +(I'm using Mozilla Firefox, Google Chrome, Safari, and sometimes +IE8, IE9, and Opera to test the generated output). Some of the features the HTML section (such as \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 \addindex LaTeX @@ -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 \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 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 printer. If you do not have a PostScript printer, you can try to use ghostscript to convert PostScript into something your printer understands. 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 the \ref cfg_pdf_hyperlinks "PDF_HYPERLINKS" @@ -207,21 +231,21 @@ the option from the drop down menu). \addindex XML The XML output consists of a structured "dump" of the information gathered 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 into a single file. -Doxygen also generates two XML schema files index.xsd -(for the index file) and compound.xsd (for the compound files). +Doxygen also generates two XML schema files `index.xsd` +(for the index file) and `compound.xsd` (for the compound files). This schema file describes the possible elements, their attributes and 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. -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 -(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 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 Although documenting the sources is presented as step 3, in a new project this should of course be step 1. Here I assume 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 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 basically two options: -<ol> -<li>Place a \e special documentation block in front of the declaration or +1. Place a \e special documentation block in front of the declaration or definition of the member, class or namespace. For file, class and namespace 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. -<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 documentation block. A structural command links a documentation block 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. -</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 no way to put a documentation block before a file. Of course, file members (functions, variables, typedefs, defines) do not need an explicit 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 before it is written to the HTML and/or \f$\mbox{\LaTeX}\f$ output files. \addindex parsing During parsing the following steps take place: -<ul> -<li> The special commands inside the documentation are executed. See - section \ref commands for an overview of all commands. -<li> If a line starts with some whitespace followed by one or more asterisks - (<tt>*</tt>) and then optionally more whitespace, - then all whitespace and asterisks are removed. -<li> All resulting blank lines are treated as a paragraph separators. - This saves you from placing new-paragraph commands yourself - in order to make the generated documentation readable. -<li> Links are created for words corresponding to documented classes - (unless the word is preceded by a \%; then the word will not be linked and - the \% sign is removed). -<li> Links to members are created when certain patterns are found in the - text. See section \ref autolink - for more information on how the automatic link generation works. -<li> HTML tags that are in the documentation are interpreted and converted - to \f$\mbox{\LaTeX}\f$ equivalents for the \f$\mbox{\LaTeX}\f$ output. - See section \ref htmlcmds for an overview of all supported HTML tags. -</ul> +- Markdown formatting is replaced by corresponding HTML or special + commands. +- The special commands inside the documentation are executed. See + section \ref commands for an overview of all commands. +- If a line starts with some whitespace followed by one or more asterisks + (`*`) and then optionally more whitespace, + then all whitespace and asterisks are removed. +- All resulting blank lines are treated as a paragraph separators. + This saves you from placing new-paragraph commands yourself + in order to make the generated documentation readable. +- Links are created for words corresponding to documented classes + (unless the word is preceded by a \%; then the word will not be linked and + the \% sign is removed). +- Links to members are created when certain patterns are found in the + text. See section \ref autolink + for more information on how the automatic link generation works. +- HTML tags that are in the documentation are interpreted and converted + to \f$\mbox{\LaTeX}\f$ equivalents for the \f$\mbox{\LaTeX}\f$ output. + See section \ref htmlcmds for an overview of all supported HTML tags. \htmlonly Go to the <a href="docblocks.html">next</a> section or return to the diff --git a/qtools/qcstring.h b/qtools/qcstring.h index 1e5f6f8..bbe8700 100644 --- a/qtools/qcstring.h +++ b/qtools/qcstring.h @@ -87,10 +87,10 @@ Q_EXPORT void *qmemmove( void *dst, const void *src, uint len ); Q_EXPORT char *qstrdup( const char * ); Q_EXPORT inline uint cstrlen( const char *str ) -{ return strlen(str); } +{ return (uint)strlen(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 ) { return strcpy(dst,src); } @@ -3031,7 +3031,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} <FuncCall,MemberCall2>("("{B}*("*"{B}*)+{ID}*{B}*")"{B}*)/("."|"->") { g_code->codify(yytext); 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); BEGIN( MemberCall2 ); } diff --git a/src/commentcnv.l b/src/commentcnv.l index 5408f68..fa392bf 100644 --- a/src/commentcnv.l +++ b/src/commentcnv.l @@ -285,7 +285,7 @@ void replaceComment(int offset); %% <Scan>[^"'!\/\n\\#\\-]* { /* eat anything that is not " / or \n */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <Scan>"\"\"\""! { /* start of python long comment */ if (g_lang!=SrcLangExt_Python) @@ -295,7 +295,7 @@ void replaceComment(int offset); else { g_pythonDocString = TRUE; - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(CComment); } } @@ -306,22 +306,22 @@ void replaceComment(int offset); } else { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(CComment); } } <Scan>"\"" { /* start of a string */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); g_stringContext = YY_START; BEGIN(SkipString); } <Scan>' { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); g_charContext = YY_START; BEGIN(SkipChar); } <Scan>\n { /* new line */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <Scan>("//!"|"///").*/\n[ \t]*"//"[\/!][^\/] { /* start C++ style special comment block */ if (g_mlBrief) @@ -352,13 +352,13 @@ void replaceComment(int offset); BEGIN(SComment); } <Scan>"//"/.*\n { /* one line C++ comment */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); g_readLineCtx=YY_START; BEGIN(ReadLine); } <Scan>"/*"[*!]? { /* start of a C comment */ - g_specialComment=yyleng==3; - copyToOutput(yytext,yyleng); + g_specialComment=(int)yyleng==3; + copyToOutput(yytext,(int)yyleng); BEGIN(CComment); } <Scan>"#"("#")? { @@ -368,7 +368,7 @@ void replaceComment(int offset); } else { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(CComment); } } @@ -379,7 +379,7 @@ void replaceComment(int offset); } else { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(CComment); } } @@ -390,7 +390,7 @@ void replaceComment(int offset); } else { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(CComment); } } @@ -402,14 +402,14 @@ void replaceComment(int offset); BEGIN(VerbatimCode); } <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_javaBlock=0; g_blockName=&yytext[1]; BEGIN(VerbatimCode); } <CComment,ReadLine>[\\@]("f$"|"f["|"f{"[a-z]*) { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); g_blockName=&yytext[1]; if (g_blockName.at(1)=='[') { @@ -423,16 +423,16 @@ void replaceComment(int offset); BEGIN(Verbatim); } <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_lastCommentContext = YY_START; BEGIN(Verbatim); } <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 */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); if (yytext[1]=='f') // end of formula { BEGIN(g_lastCommentContext); @@ -450,7 +450,7 @@ void replaceComment(int offset); else { g_javaBlock++; - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } } <VerbatimCode>"}" { @@ -468,12 +468,12 @@ void replaceComment(int offset); } else { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } } } <VerbatimCode>[\\@]("enddot"|"endcode"|"endmsc") { /* end of verbatim block */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); if (&yytext[4]==g_blockName) { BEGIN(g_lastCommentContext); @@ -482,14 +482,14 @@ void replaceComment(int offset); <VerbatimCode>^[ \t]*"//"[\!\/]? { /* skip leading comments */ if (!g_inSpecialComment) { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } } <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 */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <Verbatim,VerbatimCode>^[ \t]*"///" { if (g_blockName=="dot" || g_blockName=="msc" || g_blockName.at(0)=='f') @@ -503,40 +503,40 @@ void replaceComment(int offset); } } <Verbatim,VerbatimCode>. { /* any other character */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <SkipString>\\. { /* escaped character in string */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <SkipString>"\"" { /* end of string */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(g_stringContext); } <SkipString>. { /* any other string character */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <SkipString>\n { /* new line inside string (illegal for some compilers) */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <SkipChar>\\. { /* escaped character */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <SkipChar>' { /* end of character literal */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(g_charContext); } <SkipChar>. { /* any other string character */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <SkipChar>\n { /* new line character */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <CComment>[^\\!@*\n{\"]* { /* anything that is not a '*' or command */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <CComment>"*"+[^*/\\@\n{\"]* { /* stars without slashes */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <CComment>"\"\"\"" { /* end of Python docstring */ if (g_lang!=SrcLangExt_Python) @@ -546,12 +546,12 @@ void replaceComment(int offset); else { g_pythonDocString = FALSE; - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(Scan); } } <CComment>\n { /* new line in comment */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <CComment>"*"+"/" { /* end of C comment */ if (g_lang==SrcLangExt_Python) @@ -560,7 +560,7 @@ void replaceComment(int offset); } else { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(Scan); } } @@ -571,7 +571,7 @@ void replaceComment(int offset); } else { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(Scan); } } @@ -582,7 +582,7 @@ void replaceComment(int offset); } else { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(Scan); } } @@ -593,22 +593,22 @@ void replaceComment(int offset); } else { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(Scan); } } <CComment>"'" { g_charContext = YY_START; - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(SkipChar); } <CComment>"\"" { g_stringContext = YY_START; - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(SkipString); } <CComment>. { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <SComment>^[ \t]*"///"[\/]*/\n { replaceComment(0); @@ -666,17 +666,17 @@ void replaceComment(int offset); } <SComment>\n { /* end of special comment */ copyToOutput(" */",3); - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); g_inSpecialComment=FALSE; g_inRoseComment=FALSE; BEGIN(Scan); } <ReadLine>[^\\@\n]*/\n { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(g_readLineCtx); } <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 g_condCtx = YY_START; @@ -756,7 +756,7 @@ void replaceComment(int offset); else // abort the alias, restart scanning { copyToOutput(g_aliasString,g_aliasString.length()); - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(Scan); } } @@ -794,7 +794,7 @@ void replaceComment(int offset); g_lastEscaped=FALSE; } <ReadLine>. { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } %% @@ -803,7 +803,7 @@ void replaceComment(int offset) { if (g_mlBrief) { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } else { @@ -811,12 +811,12 @@ void replaceComment(int offset) int i=computeIndent(&yytext[offset]); if (i==g_blockHeadCol) { - replaceCommentMarker(yytext,yyleng); + replaceCommentMarker(yytext,(int)yyleng); } else { 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; BEGIN(Scan); } diff --git a/src/commentscan.l b/src/commentscan.l index 4f4408f..85b378a 100644 --- a/src/commentscan.l +++ b/src/commentscan.l @@ -387,8 +387,9 @@ static Entry* current = 0 ; // working entry //static Entry* previous = 0 ; // TODO: remove need for this static bool needNewEntry; -static QCString sectionLabel; -static QCString sectionTitle; +static QCString g_sectionLabel; +static QCString g_sectionTitle; +static int g_sectionLevel; static QCString xrefItemKey; static QCString newXRefItemKey; static QCString xrefItemTitle; @@ -401,7 +402,6 @@ static int braceCount; static bool insidePre; static bool parseMore; static int g_condCount; -static int g_sectionLevel; static int g_commentCount; static bool g_spaceBeforeCmd; @@ -421,38 +421,40 @@ static QCString g_compoundName; static void initParser() { - sectionLabel.resize(0); - sectionTitle.resize(0); + g_sectionLabel.resize(0); + g_sectionTitle.resize(0); g_memberGroupHeader.resize(0); } //----------------------------------------------------------------------------- -static QCString getDocSectionName(int s) +static bool getDocSectionName(int s) { switch(s) { - case Entry::CLASSDOC_SEC: return "\\class"; - case Entry::STRUCTDOC_SEC: return "\\struct"; - case Entry::UNIONDOC_SEC: return "\\union"; - case Entry::EXCEPTIONDOC_SEC: return "\\exception"; - case Entry::NAMESPACEDOC_SEC: return "\\namespace"; - case Entry::PROTOCOLDOC_SEC: return "\\protocol"; - case Entry::CATEGORYDOC_SEC: return "\\category"; - case Entry::ENUMDOC_SEC: return "\\enum"; - case Entry::PAGEDOC_SEC: return "\\page"; - case Entry::VARIABLEDOC_SEC: return "\\var"; - case Entry::MEMBERDOC_SEC: return "\\fn"; - case Entry::OVERLOADDOC_SEC: return "\\overload"; - case Entry::FILEDOC_SEC: return "\\file"; - case Entry::DEFINEDOC_SEC: return "\\def"; - case Entry::GROUPDOC_SEC: return "\\defgroup"; - case Entry::MAINPAGEDOC_SEC: return "\\mainpage"; - case Entry::PACKAGEDOC_SEC: return "\\package"; - case Entry::DIRDOC_SEC: return "\\dir"; - case Entry::EXAMPLE_SEC: return "\\example"; - case Entry::MEMBERGRP_SEC: return "\\name"; - default: return ""; + case Entry::CLASSDOC_SEC: + case Entry::STRUCTDOC_SEC: + case Entry::UNIONDOC_SEC: + case Entry::EXCEPTIONDOC_SEC: + case Entry::NAMESPACEDOC_SEC: + case Entry::PROTOCOLDOC_SEC: + case Entry::CATEGORYDOC_SEC: + case Entry::ENUMDOC_SEC: + case Entry::PAGEDOC_SEC: + case Entry::VARIABLEDOC_SEC: + case Entry::MEMBERDOC_SEC: + case Entry::OVERLOADDOC_SEC: + case Entry::FILEDOC_SEC: + case Entry::DEFINEDOC_SEC: + case Entry::GROUPDOC_SEC: + case Entry::MAINPAGEDOC_SEC: + case Entry::PACKAGEDOC_SEC: + case Entry::DIRDOC_SEC: + case Entry::EXAMPLE_SEC: + case Entry::MEMBERGRP_SEC: + return TRUE; + default: + return FALSE; } } @@ -461,7 +463,7 @@ static QCString getDocSectionName(int s) static bool makeStructuralIndicator(Entry::Sections s) { //printf("current->section=%x\n",current->section); - if (!getDocSectionName(current->section).isEmpty()) + if (getDocSectionName(current->section)) { return TRUE; } @@ -558,8 +560,9 @@ static void addXRefItem(const char *listName,const char *itemTitle, docEntry->doc += cmdString; } SectionInfo *si=new SectionInfo(listName,anchorLabel, - sectionTitle,SectionInfo::Anchor); - Doxygen::sectionDict.insert(anchorLabel,si); + g_sectionTitle,SectionInfo::Anchor, + g_sectionLevel); + Doxygen::sectionDict.append(anchorLabel,si); docEntry->anchors->append(si); } outputXRef.resize(0); @@ -598,14 +601,26 @@ static QCString addFormula() static void checkFormula(); //----------------------------------------------------------------------------- +static SectionInfo::SectionType sectionLevelToType(int level) +{ + if (level>=0 && level<5) return (SectionInfo::SectionType)level; + return SectionInfo::Anchor; +} + static void addSection() { - sectionTitle+=yytext; - sectionTitle=sectionTitle.stripWhiteSpace(); - //printf("Adding new section file=%s label=%s title=%s\n",yyFileName,sectionLabel.data(),sectionTitle.data()); - SectionInfo *si = new SectionInfo(yyFileName,sectionLabel,sectionTitle,SectionInfo::Anchor); + // create a new section element + g_sectionTitle+=yytext; + g_sectionTitle=g_sectionTitle.stripWhiteSpace(); + SectionInfo *si = new SectionInfo(yyFileName,g_sectionLabel, + g_sectionTitle,sectionLevelToType(g_sectionLevel),g_sectionLevel); + + // add section to this entry 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$]+"$" addOutput(yytext); } <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) { briefEndsAtDot=FALSE; @@ -1492,9 +1522,9 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ----- handle arguments of the section/subsection/.. commands ------- */ <SectionLabel>{LABELID} { // first argyment - sectionLabel=yytext; + g_sectionLabel=yytext; addOutput(yytext); - sectionTitle.resize(0); + g_sectionTitle.resize(0); BEGIN(SectionTitle); } <SectionLabel>{DOCNL} { // missing argument @@ -1511,8 +1541,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" ); BEGIN(Comment); } - -<SectionTitle>[^\n@\\*]*/"\n" { // end of section title +<SectionTitle>[^\n@\\*]*/"\n" { // end of section title addSection(); addOutput(yytext); BEGIN( Comment ); @@ -1527,19 +1556,19 @@ RCSTAG "$"{ID}":"[^\n$]+"$" addOutput('\n'); } <SectionTitle>[^\n@\\]* { // any character without special meaning - sectionTitle+=yytext; + g_sectionTitle+=yytext; addOutput(yytext); } <SectionTitle>("\\\\"|"@@"){ID} { // unescape escaped command - sectionTitle+=&yytext[1]; + g_sectionTitle+=&yytext[1]; addOutput(yytext); } <SectionTitle>{CMD}[$@\\&~<>#%] { // unescape escaped character - sectionTitle+=yytext[1]; + g_sectionTitle+=yytext[1]; addOutput(yytext); } <SectionTitle>. { // anything else - sectionTitle+=yytext; + g_sectionTitle+=yytext; addOutput(*yytext); } @@ -1576,8 +1605,8 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ----- handle arguments of the anchor command ------- */ <AnchorLabel>{LABELID} { // found argument - SectionInfo *si = new SectionInfo(yyFileName,yytext,0,SectionInfo::Anchor); - Doxygen::sectionDict.insert(yytext,si); + SectionInfo *si = new SectionInfo(yyFileName,yytext,0,SectionInfo::Anchor,0); + Doxygen::sectionDict.append(yytext,si); current->anchors->append(si); addOutput(yytext); BEGIN( Comment ); @@ -2646,9 +2675,9 @@ bool parseCommentBlock(/* in */ ParserInterface *parser, if (Doxygen::markdownSupport) { - current->brief = processMarkdown(current->brief); - current->doc = processMarkdown(current->doc); - current->inbodyDocs = processMarkdown(current->inbodyDocs); + current->brief = processMarkdown(fileName,current,current->brief); + current->doc = processMarkdown(fileName,current,current->doc); + current->inbodyDocs = processMarkdown(fileName,current,current->inbodyDocs); } Debug::print(Debug::CommentScan,0, diff --git a/src/definition.cpp b/src/definition.cpp index e04c767..4bca129 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -320,10 +320,11 @@ void Definition::addSectionsToDefinition(QList<SectionInfo> *anchorList) //printf("Add section `%s' to definition `%s'\n", // si->label.data(),name().data()); SectionInfo *gsi=Doxygen::sectionDict.find(si->label); + //printf("===== label=%s gsi=%p\n",si->label.data(),gsi); if (gsi==0) { gsi = new SectionInfo(*si); - Doxygen::sectionDict.insert(si->label,gsi); + Doxygen::sectionDict.append(si->label,gsi); } if (m_impl->sectionDict==0) { @@ -331,20 +332,82 @@ void Definition::addSectionsToDefinition(QList<SectionInfo> *anchorList) } 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; } 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() { makeResident(); if (!Config_getString("GENERATE_TAGFILE").isEmpty() && m_impl->sectionDict) { //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; for (;(si=sdi.current());++sdi) { diff --git a/src/definition.h b/src/definition.h index 1e51a1c..c07eb3e 100644 --- a/src/definition.h +++ b/src/definition.h @@ -260,6 +260,7 @@ class Definition : public DefinitionIntf, public LockableObj LockingPtr<MemberSDict> getReferencesMembers() const; LockingPtr<MemberSDict> getReferencedByMembers() const; + bool hasSections() const; //----------------------------------------------------------------------------------- // ---- setters ----- @@ -328,6 +329,8 @@ class Definition : public DefinitionIntf, public LockableObj void writeDocAnchorsToTagFile(); void setLocalName(const QCString name); + void addSectionsToIndex(); + protected: virtual void flushToDisk() const; diff --git a/src/docparser.cpp b/src/docparser.cpp index 3ec6631..526e349 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -1720,7 +1720,7 @@ DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor) if (g_sectionDict && g_sectionDict->find(id)==0) { //printf("Inserting in dictionary!\n"); - g_sectionDict->insert(id,sec); + g_sectionDict->append(id,sec); } } else @@ -1736,9 +1736,10 @@ DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor) DocVerbatim::DocVerbatim(DocNode *parent,const QCString &context, 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_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; } @@ -2134,7 +2135,7 @@ void DocSecRefItem::parse() m_anchor = sec->label; if (g_sectionDict && g_sectionDict->find(m_target)==0) { - g_sectionDict->insert(m_target,sec); + g_sectionDict->append(m_target,sec); } } else @@ -2278,7 +2279,7 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) : m_parent = parent; Definition *compound = 0; 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()); m_relPath = g_relPath; SectionInfo *sec = Doxygen::sectionDict[target]; @@ -2299,7 +2300,8 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) : else if (resolveLink(context,target,TRUE,&compound,anchor)) { bool isFile = compound ? - (compound->definitionType()==Definition::TypeFile ? TRUE : FALSE) : + (compound->definitionType()==Definition::TypeFile || + compound->definitionType()==Definition::TypePage ? TRUE : FALSE) : FALSE; m_text = linkToText(compound?compound->getLanguage():SrcLangExt_Unknown,target,isFile); m_anchor = anchor; @@ -2323,6 +2325,8 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) : m_file = compound->getOutputFileBase(); m_ref = compound->getReference(); + //printf("isFile=%d compound=%s (%d)\n",isFile,compound->name().data(), + // compound->definitionType()); return; } else if (compound->definitionType()==Definition::TypeFile && @@ -2334,7 +2338,7 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) : 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", qPrint(target)); } @@ -4902,6 +4906,11 @@ bool DocPara::injectToken(int tok,const QCString &tokText) int DocPara::handleStartCode() { 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 int i=0,li=0,l=g_token->verb.length(); while (i<l && (g_token->verb.at(i)==' ' || g_token->verb.at(i)=='\n')) @@ -4909,7 +4918,7 @@ int DocPara::handleStartCode() if (g_token->verb.at(i)=='\n') li=i+1; 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"); doctokenizerYYsetStatePara(); return retval; @@ -6264,7 +6273,7 @@ int DocSection::parse() if (m_title.isEmpty()) m_title = sec->label; if (g_sectionDict && g_sectionDict->find(m_id)==0) { - g_sectionDict->insert(m_id,sec); + g_sectionDict->append(m_id,sec); } } } diff --git a/src/docparser.h b/src/docparser.h index 4e8587c..1e7f7d8 100644 --- a/src/docparser.h +++ b/src/docparser.h @@ -375,7 +375,7 @@ class DocVerbatim : public DocNode enum Type { Code, HtmlOnly, ManOnly, LatexOnly, XmlOnly, Verbatim, Dot, Msc }; DocVerbatim(DocNode *parent,const QCString &context, const QCString &text, Type t,bool isExample, - const QCString &exampleFile); + const QCString &exampleFile,const QCString &lang=QCString()); Kind kind() const { return Kind_Verbatim; } Type type() const { return m_type; } QCString text() const { return m_text; } @@ -384,14 +384,16 @@ class DocVerbatim : public DocNode bool isExample() const { return m_isExample; } QCString exampleFile() const { return m_exampleFile; } QCString relPath() const { return m_relPath; } + QCString language() const { return m_lang; } private: QCString m_context; QCString m_text; - Type m_type; - bool m_isExample; + Type m_type; + bool m_isExample; QCString m_exampleFile; QCString m_relPath; + QCString m_lang; }; @@ -1190,6 +1192,9 @@ class DocHtmlRow : public CompAccept<DocHtmlRow>, public DocNode const HtmlAttribList &attribs() const { return m_attribs; } int parse(); int parseXml(bool header); + bool isHeading() const { return m_children.count()>0 && + ((DocHtmlCell*)m_children.getFirst())->isHeading(); + } private: HtmlAttribList m_attribs; diff --git a/src/docsets.cpp b/src/docsets.cpp index fa86dc8..7a6ff9d 100644 --- a/src/docsets.cpp +++ b/src/docsets.cpp @@ -290,7 +290,8 @@ void DocSets::addIndexItem(Definition *context,MemberDef *md,const char *) case SrcLangExt_VHDL: lang="vhdl"; break; // VHDL case SrcLangExt_XML: lang="xml"; break; // DBUS XML 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) diff --git a/src/doctokenizer.l b/src/doctokenizer.l index 765e6c8..c9e5756 100644 --- a/src/doctokenizer.l +++ b/src/doctokenizer.l @@ -389,6 +389,7 @@ REFWORD {LABELID}|{REFWORD2}|{REFWORD3} %x St_TitleA %x St_TitleV %x St_Code +%x St_CodeOpt %x St_XmlCode %x St_HtmlOnly %x St_ManOnly @@ -696,6 +697,16 @@ REFWORD {LABELID}|{REFWORD2}|{REFWORD3} 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" { return RetVal_OK; } @@ -1154,12 +1165,14 @@ void doctokenizerYYsetStateTitleAttrValue() void doctokenizerYYsetStateCode() { g_token->verb=""; - BEGIN(St_Code); + g_token->name=""; + BEGIN(St_CodeOpt); } void doctokenizerYYsetStateXmlCode() { g_token->verb=""; + g_token->name=""; BEGIN(St_XmlCode); } diff --git a/src/doxygen.cpp b/src/doxygen.cpp index aa61647..34fe2d1 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -163,8 +163,6 @@ static bool g_successfulRun = FALSE; static bool g_dumpSymbolMap = FALSE; static bool g_dumpConfigAsXML = FALSE; - - void clearAll() { g_inputFiles.clear(); @@ -8233,8 +8231,9 @@ static void findMainPage(EntryNav *rootNav) indexName, Doxygen::mainPage->name(), Doxygen::mainPage->title(), - SectionInfo::Page); - Doxygen::sectionDict.insert(indexName,si); + SectionInfo::Page, + 0); // level 0 + Doxygen::sectionDict.append(indexName,si); Doxygen::mainPage->addSectionsToDefinition(root->anchors); } else @@ -8310,7 +8309,7 @@ static void checkPageRelations() static void resolveUserReferences() { - QDictIterator<SectionInfo> sdi(Doxygen::sectionDict); + SDict<SectionInfo>::Iterator sdi(Doxygen::sectionDict); SectionInfo *si; for (;(si=sdi.current());++sdi) { @@ -9380,7 +9379,7 @@ void initDoxygen() Doxygen::memGrpInfoDict.setAutoDelete(TRUE); Doxygen::tagDestinationDict.setAutoDelete(TRUE); Doxygen::dirRelations.setAutoDelete(TRUE); - Doxygen::citeDict = new CiteDict(256); + Doxygen::citeDict = new CiteDict(257); } void cleanUpDoxygen() diff --git a/src/doxygen.css b/src/doxygen.css index 613a3d3..b146398 100644 --- a/src/doxygen.css +++ b/src/doxygen.css @@ -638,7 +638,6 @@ table.doxtable th { font-size: 110%; padding-bottom: 4px; padding-top: 5px; - text-align:left; } table.fieldtable { diff --git a/src/doxygen_css.h b/src/doxygen_css.h index 1e4f161..15c68da 100644 --- a/src/doxygen_css.h +++ b/src/doxygen_css.h @@ -638,7 +638,6 @@ " font-size: 110%;\n" " padding-bottom: 4px;\n" " padding-top: 5px;\n" -" text-align:left;\n" "}\n" "\n" "table.fieldtable {\n" diff --git a/src/fortrancode.l b/src/fortrancode.l index a9bfd8b..f111e58 100644 --- a/src/fortrancode.l +++ b/src/fortrancode.l @@ -661,7 +661,7 @@ ATTR_SPEC (ALLOCATABLE|DIMENSION{ARGS}|EXTERNAL|{INTENT_SPEC}|INTRINSIC|OPTIONAL ACCESS_SPEC (PRIVATE|PUBLIC) /* Assume that attribute statements are almost the same as attributes. */ 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) /* | */ @@ -741,7 +741,7 @@ IGNORE (CALL) } /*-------- 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(); startFontClass("keyword"); codifyLines(yytext); diff --git a/src/fortranscanner.l b/src/fortranscanner.l index 16d17f8..a512647 100644 --- a/src/fortranscanner.l +++ b/src/fortranscanner.l @@ -230,6 +230,7 @@ IDSYM [a-z_A-Z0-9] NOTIDSYM [^a-z_A-Z0-9] SEPARATE [:, \t] ID [a-z_A-Z%]+{IDSYM}* +ID_ [a-z_A-Z%]*{IDSYM}* PP_ID {ID} LABELID [a-z_A-Z]+[a-z_A-Z0-9\-]* SUBPROG (subroutine|function) @@ -299,6 +300,7 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA %x DocBackLine %x EndDoc +%x BlockData %% /*-----------------------------------------------------------------------------------*/ @@ -505,6 +507,11 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA <TypedefBody>^{BS}{CONTAINS}/({BS}|\n|!) { BEGIN(TypedefBodyContains); } /*------ module handling ------------------------------------------------------------*/ +<Start>block{BS}data{BS}{ID_} { // + v_type = V_IGNORE; + yy_push_state(BlockData); + defaultProtection = Public; + } <Start>module|program{BS_} { // v_type = V_IGNORE; if(yytext[0]=='m' || yytext[0]=='M') @@ -513,6 +520,12 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA yy_push_state(Program); 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 resolveModuleProcedures(moduleProcedures, current_root); if (!endScope(current_root)) @@ -660,6 +673,10 @@ private { subrCurrent.remove(0u); yy_pop_state() ; } +<BlockData>{ +{ID} { + } +} <Start,ModuleBody,TypedefBody,SubprogBody>{ ^{BS}{TYPE_SPEC}/{SEPARATE} { /* variable declaration starts */ diff --git a/src/ftvhelp.cpp b/src/ftvhelp.cpp index 5d1061c..a8f9de3 100644 --- a/src/ftvhelp.cpp +++ b/src/ftvhelp.cpp @@ -31,6 +31,7 @@ #include "language.h" #include "htmlgen.h" #include "layout.h" +#include "pagedef.h" #define MAX_INDENT 1024 @@ -849,10 +850,17 @@ void FTVHelp::generateTreeViewScripts() QCString &projName = Config_getString("PROJECT_NAME"); if (projName.isEmpty()) { - LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::MainPage); - t << "\"" << convertToJSString(lne->title()) << "\", "; + if (Doxygen::mainPage && !Doxygen::mainPage->title().isEmpty()) // Use title of main page as root + { + 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) << "\", "; } diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp index 5ecb124..70fa3f8 100644 --- a/src/htmldocvisitor.cpp +++ b/src/htmldocvisitor.cpp @@ -330,12 +330,17 @@ void HtmlDocVisitor::visit(DocStyleChange *s) void HtmlDocVisitor::visit(DocVerbatim *s) { if (m_hide) return; + QCString lang = m_langExt; + if (!s->language().isEmpty()) // explicit language setting + { + lang = s->language(); + } switch(s->type()) { case DocVerbatim::Code: forceEndParagraph(s); m_t << PREFRAG_START; - Doxygen::parserManager->getParser(m_langExt) + Doxygen::parserManager->getParser(lang) ->parseCode(m_ci,s->context(),s->text(), s->isExample(),s->exampleFile()); m_t << PREFRAG_END; diff --git a/src/index.cpp b/src/index.cpp index 09e152c..68725aa 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -2765,7 +2765,7 @@ static void writePageIndex(OutputList &ol) ol.startContents(); ol.startTextBlock(); 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.incContentsDepth(); @@ -2777,7 +2777,7 @@ static void writePageIndex(OutputList &ol) PageDef *pd=0; for (pdi.toFirst();(pd=pdi.current());++pdi) { - if ( pd->visibleInIndex()) + if (pd->visibleInIndex()) { QCString pageTitle; @@ -2787,6 +2787,7 @@ static void writePageIndex(OutputList &ol) pageTitle=pd->title(); bool hasSubPages = pd->hasSubPages(); + bool hasSections = pd->hasSections(); ol.startIndexListItem(); ol.startIndexItem(pd->getReference(),pd->getOutputFileBase()); @@ -2801,14 +2802,25 @@ static void writePageIndex(OutputList &ol) ol.writeString("\n"); 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); ol.endIndexListItem(); } } endIndexHierarchy(ol,0); - if (addToIndex) + if (0 /*addToIndex*/) // skip Related Pages section in navigation index { Doxygen::indexList.decContentsDepth(); } @@ -3445,8 +3457,12 @@ static void writeIndex(OutputList &ol) 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()) { writeSubPages(Doxygen::mainPage); diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp index dc3b4e7..3dab3ce 100644 --- a/src/latexdocvisitor.cpp +++ b/src/latexdocvisitor.cpp @@ -53,8 +53,9 @@ static const char *secLabels[maxLevels] = static const char *getSectionName(int level) { + static bool compactLatex = Config_getBool("COMPACT_LATEX"); int l = level; - if (Config_getBool("COMPACT_LATEX")) l++; + if (compactLatex) l++; if (Doxygen::insideMainPage) l--; return secLabels[QMIN(maxLevels-1,l)]; } @@ -62,10 +63,11 @@ static const char *getSectionName(int level) static int rowspan(DocHtmlCell *cell) { int retval = 0; - HtmlAttribList attrs = cell->attribs (); - for (unsigned int i = 0; i < attrs.count(); ++i) + HtmlAttribList attrs = cell->attribs(); + 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(); break; @@ -74,6 +76,24 @@ static int rowspan(DocHtmlCell *cell) 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 result; @@ -277,26 +297,19 @@ void LatexDocVisitor::visit(DocVerbatim *s) { //static bool latexSourceCode = Config_getBool("LATEX_SOURCE_CODE"); if (m_hide) return; + QCString lang = m_langExt; + if (!s->language().isEmpty()) // explicit language setting + { + lang = s->language(); + } switch(s->type()) { case DocVerbatim::Code: - //if (latexSourceCode) - //{ - // m_t << "\n\n\\begin{footnotesize}\\begin{alltt}" << endl; - //} - //else { m_t << "\n\\begin{DoxyCode}\n"; - } - Doxygen::parserManager->getParser(m_langExt) - ->parseCode(m_ci,s->context(),s->text(), - s->isExample(),s->exampleFile()); - //if (latexSourceCode) - //{ - // m_t << "\\end{alltt}\\end{footnotesize}" << endl; - //} - //else - { + Doxygen::parserManager->getParser(lang) + ->parseCode(m_ci,s->context(),s->text(), + s->isExample(),s->exampleFile()); m_t << "\\end{DoxyCode}\n"; } break; @@ -883,9 +896,10 @@ void LatexDocVisitor::visitPost(DocHtmlCaption *) m_t << "}\n"; } -void LatexDocVisitor::visitPre(DocHtmlRow *) +void LatexDocVisitor::visitPre(DocHtmlRow *r) { m_currentColumn = 0; + if (r->isHeading()) m_t << "\\rowcolor{lightgray}"; } void LatexDocVisitor::visitPost(DocHtmlRow *) @@ -896,24 +910,30 @@ void LatexDocVisitor::visitPost(DocHtmlRow *) QMap<int, int>::Iterator it; 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()--; if (it.data () <= 0) + { m_rowspanIndices.remove (it); + } else if (0 < it.data() - col) + { m_t << "\\cline{" << col << "-" << it.data() - col << "}"; - - col = 1 + it.data (); } + + col = 1 + it.data(); + } if (col <= m_currentColumn) + { m_t << "\\cline{" << col << "-" << m_currentColumn << "}"; + } m_t << "\n"; } -void LatexDocVisitor::visitPre(DocHtmlCell *cell) +void LatexDocVisitor::visitPre(DocHtmlCell *c) { if (m_hide) return; @@ -927,18 +947,35 @@ void LatexDocVisitor::visitPre(DocHtmlCell *cell) it++; } - int rs = rowspan(cell); - if (0 < rs) + int rs = rowspan(c); + if (rs>0) { m_inRowspan = TRUE; m_rowspanIndices[m_currentColumn] = rs; 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) { if (m_hide) return; + if (c->isHeading()) + { + m_t << "}"; + } if (m_inRowspan) { m_inRowspan = FALSE; diff --git a/src/latexgen.cpp b/src/latexgen.cpp index 6f92f79..65ed16b 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -72,18 +72,10 @@ LatexGenerator::~LatexGenerator() { } -void LatexGenerator::init() +static void writeLatexMakefile() { bool generateBib = !Doxygen::citeDict->isEmpty(); - 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"; QFile file(fileName); if (!file.open(IO_WriteOnly)) @@ -182,6 +174,66 @@ void LatexGenerator::init() << "\trm -f " #endif << "*.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); } @@ -345,6 +397,7 @@ static void writeDefaultStyleSheetPart1(FTextStream &t) "\\RequirePackage{longtable}\n" "\\RequirePackage{verbatim}\n" "\\RequirePackage{ifthen}\n" + "\\RequirePackage{xtab}\n" "\\RequirePackage[table]{xcolor}\n\n"; t << "% Use helvetica font instead of times roman\n" @@ -788,10 +841,10 @@ static void writeDefaultStyleSheetPart3(FTextStream &t) t << "{\n"; t << "\\setlength{\\tmplength}\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 << "}\n"; - t << "{\\end{tabular*}\\par}\n"; + t << "{\\end{xtabular*}\\par}\n"; t << "\\newcommand{\\entrylabel}[1]{\n"; t << " {\\parbox[b]{\\labelwidth-4pt}{\\makebox[0pt][l]{%\n"; t << " \\usefont{OT1}{phv}{bc}{n}\\color{darkgray}#1}\\vspace{1.5\\baselineskip}}}}\n"; diff --git a/src/markdown.cpp b/src/markdown.cpp index 42b5bee..95cf3c1 100644 --- a/src/markdown.cpp +++ b/src/markdown.cpp @@ -43,6 +43,14 @@ #include "util.h" #include "doxygen.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 }; static QDict<LinkRef> g_linkRefs(257); static action_t g_actions[256]; +static Entry *g_current; +static QCString g_fileName; //static QDict<void> g_htmlBlockTags(17); //---------- @@ -206,11 +216,7 @@ static int findEmphasisChar(const char *data, int size, char c) if (data[i] == c) { - if (i<size-1 && ((data[i+1]>='a' && data[i+1]<='z') || - (data[i+1]>='A' && data[i+1]<='Z') || - (data[i+1]>='0' && data[i+1]<='9') - ) - ) // to prevent touching some_underscore_identifier + if (i<size-1 && isIdChar(i+1)) // to prevent touching some_underscore_identifier { i++; continue; @@ -397,11 +403,110 @@ static int processEmphasis3(GrowBuf &out, const char *data, int size, char c) 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]; - size_t ret; - if (size>2 && data[1]!=c) + int ret; + if (size>2 && data[1]!=c) // _bla or *bla { // whitespace cannot follow an opening emphasis if (data[1]==' ' || data[1]=='\n' || @@ -411,7 +516,7 @@ static int processEmphasis(GrowBuf &out,const char *data,int,int size) } 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' || (ret = processEmphasis2(out, data+2, size-2, c)) == 0) @@ -420,7 +525,7 @@ static int processEmphasis(GrowBuf &out,const char *data,int,int size) } 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' || (ret = processEmphasis3(out, data+3, size-3, c)) == 0) @@ -478,7 +583,7 @@ static int processLink(GrowBuf &out,const char *data,int,int size) contentEnd=i; convertStringFragment(content,data+contentStart,contentEnd-contentStart); //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 ] // skip whitespace @@ -588,7 +693,7 @@ static int processLink(GrowBuf &out,const char *data,int,int size) } 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()); //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) { return 0; } - if (isImageLink) // TODO: use @image? + static QRegExp re("^[@\\]ref "); + if (isImageLink) { - out.addStr("<img src=\""); - out.addStr(link); - out.addStr("\" alt=\""); - out.addStr(content); - out.addStr("\""); - if (!title.isEmpty()) + if (link.find("@ref ")!=-1 || link.find("\\ref ")!=-1) + // assume doxygen symbol link { - out.addStr(" title=\""); - out.addStr(substitute(title.simplifyWhiteSpace(),"\"",""")); - out.addStr("\""); + out.addStr("@image html "); + out.addStr(link.mid(5)); + 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 - { - static QRegExp re("^[@\\]ref "); - if (link.find('/')!=-1) // file/url link + else { - out.addStr("<a href=\""); + out.addStr("<img src=\""); out.addStr(link); + out.addStr("\" alt=\""); + out.addStr(content); out.addStr("\""); if (!title.isEmpty()) { @@ -638,11 +748,12 @@ static int processLink(GrowBuf &out,const char *data,int,int size) out.addStr(substitute(title.simplifyWhiteSpace(),"\"",""")); out.addStr("\""); } - out.addStr(">"); - out.addStr(content.simplifyWhiteSpace()); - out.addStr("</a>"); + out.addStr("/>"); } - else if (link.find("@ref ")!=-1 || link.find("\\ref ")!=-1) + } + else + { + if (link.find("@ref ")!=-1 || link.find("\\ref ")!=-1) // assume doxygen symbol link { out.addStr(link); @@ -657,7 +768,22 @@ static int processLink(GrowBuf &out,const char *data,int,int size) } 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(),"\"",""")); + 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()); return 0; @@ -722,17 +848,14 @@ static int processCodeSpan(GrowBuf &out, const char *data, int /*offset*/, int s i=f_begin; while (i<f_end-1) { - if (data[i]=='\'' && !((data[i+1]>='a' && data[i+1]<='z') || - (data[i+1]>='A' && data[i+1]<='Z') || - (data[i+1]>='0' && data[i+1]<='9') - )) // reject `some word' and not `it's cool` + if (data[i]=='\'' && !isIdChar(i+1)) // reject `some word' and not `it's cool` { return 0; } 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 */ if (f_begin < f_end) @@ -783,28 +906,6 @@ static int processSpecialCommand(GrowBuf &out, const char *data, int offset, int 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) { int i=0, end=0; @@ -856,7 +957,24 @@ static bool isBlockQuote(const char *data,int size,int indent) { int i = 0; 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. */ @@ -979,7 +1097,7 @@ static int isHRuler(const char *data,int size) 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\\-]*\\}$"); int l=0; int i = r2.match(title,0,&l); @@ -990,20 +1108,21 @@ static QCString extractTitleId(QCString &title) //printf("found id='%s' title='%s'\n",id.data(),title.data()); return id; } - i = r1.match(title,0,&l); - if (i!=-1) // found id: style id - { - QCString id = title.mid(i,l-1); - title = title.left(i)+title.mid(i+l); - //printf("found id='%s' title='%s'\n",id.data(),title.data()); - return id; - } + //i = r1.match(title,0,&l); + //if (i!=-1) // found id: style id + //{ + // QCString id = title.mid(i,l-1); + // title = title.left(i)+title.mid(i+l); + // //printf("found id='%s' title='%s'\n",id.data(),title.data()); + // return id; + //} //printf("no id found in title '%s'\n",title.data()); 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 level = 0; @@ -1021,6 +1140,13 @@ static int isAtxHeader(const char *data,int size,QCString &header) // store result 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; } @@ -1037,19 +1163,29 @@ static int isEmptyLine(const char *data,int size) 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 -// such as -, *, +, and 1. +// such as -, -#, *, +, 1., and <li> static int computeIndentExcludingListMarkers(const char *data,int size) { int i=0; int indent=0; bool isDigit=FALSE; + bool isLi=FALSE; bool listMarkerSkipped=FALSE; while (i<size && (data[i]==' ' || // space (!listMarkerSkipped && // first list marker (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) 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 } if (data[i]!=' ' && !listMarkerSkipped) - { + { // end of indent break; } indent++,i++; @@ -1090,6 +1238,44 @@ static int computeIndentExcludingListMarkers(const char *data,int size) 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) { //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) // write table header, in range [start..end] out.addStr("<tr>"); - j=start; - for (k=0;k<columns;k++) - { - out.addStr("<th>"); - while (j<=end && (data[j]!='|' || (j>0 && data[j-1]=='\\'))) - { - out.addChar(data[j++]); - } - j++; - } + + int headerStart = start; + int headerEnd = end; // read cell alignments int ret = findTableColumns(data+i,size-i,start,end,cc); @@ -1295,6 +1474,25 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size) // proceed to next line 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 while (i<size) { @@ -1348,17 +1546,44 @@ void writeOneLineHeaderOrRuler(GrowBuf &out,const char *data,int size) { int level; QCString header; + QCString id; if (isHRuler(data,size)) { out.addStr("<hr>\n"); } - else if ((level=isAtxHeader(data,size,header))) + else if ((level=isAtxHeader(data,size,header,id))) { QCString hTag; - hTag.sprintf("h%d",level); - out.addStr("<"+hTag+">"); - out.addStr(header); - out.addStr("</"+hTag+">\n"); + if (level<5 && !id.isEmpty()) + { + switch(level) + { + 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 { @@ -1387,6 +1612,11 @@ static int writeBlockQuote(GrowBuf &out,const char *data,int size) else if (j>0 && data[j-1]=='>') indent=j+1; 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 { for (l=curLevel;l<level;l++) @@ -1458,11 +1688,12 @@ static void findEndOfLine(GrowBuf &out,const char *data,int size, int &pi,int&i,int &end) { // find end of the line + int nb=0; for (end=i+1; end<size && data[end-1]!='\n'; end++) { // while looking for the end of the line we might encounter a block // 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 ) { @@ -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) if (pi!=-1) { + int blockStart,blockEnd,blockOffset; + QCString lang; blockIndent = indent; //printf("isHeaderLine(%s)=%d\n",QCString(data+i).left(size-i).data(),level); if ((level=isHeaderline(data+i,size-i))>0) { //printf("Found header at %d-%d\n",i,end); 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>"); - out.addStr(data+pi,i-pi-1); - out.addStr(level==1?"</h1>\n":"</h2>\n"); + if (!id.isEmpty()) + { + 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 { @@ -1608,6 +1890,23 @@ static QCString processBlocks(const QCString &s,int indent) pi=-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)) //if (isCodeBlock(data+pi,pi,end-pi,blockIndent)) { @@ -1651,7 +1950,7 @@ static QCString processBlocks(const QCString &s,int indent) return out.get(); } -static QCString extractPageTitle(QCString &docs) +static QCString extractPageTitle(QCString &docs,QCString &id) { // first first non-empty line QCString title; @@ -1671,16 +1970,19 @@ static QCString extractPageTitle(QCString &docs) while (end2<size && data[end2-1]!='\n') end2++; if (isHeaderline(data+end1,size-end1)) { - convertStringFragment(title,data+i,end1-i); + convertStringFragment(title,data+i,end1-i-1); docs=docs.mid(end2); + id = extractTitleId(title); + //printf("extractPageTitle(title='%s' docs='%s' id='%s')\n",title.data(),docs.data(),id.data()); 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); } - //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; } @@ -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.clear(); + g_current = e; + g_fileName = fileName; static GrowBuf out; if (input.isEmpty()) return input; out.clear(); @@ -1777,7 +2055,7 @@ QCString processMarkdown(const QCString &input) g_actions['@']=processSpecialCommand; g_actions['[']=processLink; g_actions['!']=processLink; - //g_actions['<']=processHtmlBlock; + g_actions['<']=processHtmlTag; // finally process the inline markup (links, emphasis and code spans) processInline(out,s,size); out.addChar(0); @@ -1794,10 +2072,11 @@ void MarkdownFileParser::parseInput(const char *fileName, Entry *current = new Entry; current->lang = SrcLangExt_Markdown; QCString docs = fileBuf; - QCString title=extractPageTitle(docs).stripWhiteSpace(); - QCString id=extractTitleId(title); + QCString id; + QCString title=extractPageTitle(docs,id).stripWhiteSpace(); QCString baseName = substitute(QFileInfo(fileName).baseName().utf8()," ","_"); if (id.isEmpty()) id = "md_"+baseName; + if (title.isEmpty()) title = baseName; if (id=="mainpage" || id=="index") { docs.prepend("@mainpage "+title+"\n"); diff --git a/src/markdown.h b/src/markdown.h index 616c01e..885d659 100644 --- a/src/markdown.h +++ b/src/markdown.h @@ -19,8 +19,10 @@ #include <qcstring.h> #include "parserintf.h" +class Entry; + /** 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 { diff --git a/src/marshal.cpp b/src/marshal.cpp index 0675277..d366c57 100644 --- a/src/marshal.cpp +++ b/src/marshal.cpp @@ -157,6 +157,7 @@ void marshalSectionInfoList(StorageIntf *s, QList<SectionInfo> *anchors) marshalQCString(s,si->ref); marshalInt(s,(int)si->type); marshalQCString(s,si->fileName); + marshalInt(s,si->level); } } } @@ -195,7 +196,7 @@ void marshalSectionDict(StorageIntf *s,SectionDict *sections) else { marshalUInt(s,sections->count()); - QDictIterator<SectionInfo> sli(*sections); + SDict<SectionInfo>::IteratorDict sli(*sections); SectionInfo *si; for (sli.toFirst();(si=sli.current());++sli) { @@ -576,7 +577,8 @@ QList<SectionInfo> *unmarshalSectionInfoList(StorageIntf *s) QCString ref = unmarshalQCString(s); SectionInfo::SectionType type = (SectionInfo::SectionType)unmarshalInt(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; } @@ -619,7 +621,7 @@ SectionDict *unmarshalSectionDict(StorageIntf *s) QCString key = unmarshalQCString(s); SectionInfo *si = (SectionInfo *)unmarshalObjPointer(s); //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; } diff --git a/src/navtree.js b/src/navtree.js index b0c4936..eb18215 100644 --- a/src/navtree.js +++ b/src/navtree.js @@ -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) { if (node.childrenData && !node.expanded) { @@ -249,15 +264,12 @@ function showNode(o, node, index) if ($(location).attr('hash')) { var link=stripPath($(location).attr('pathname'))+':'+ $(location).attr('hash').substring(1); - a=$('.item a[class*=\""'+link+'"\"]'); + a=$('.item a[class$=\""'+link+'"\"]'); } if (a && a.length) { a.parent().parent().addClass('selected'); a.parent().parent().attr('id','selected'); - var anchor = $($(location).attr('hash')); - var targetDiv = anchor.next(); - $(targetDiv).children('.memproto,.memdoc'). - effect("highlight", {}, 1500); + highlightAnchor(); } else { $(n.itemDiv).addClass('selected'); $(n.itemDiv).attr('id','selected'); @@ -302,7 +314,8 @@ function initNavTree(toroot,relpath) getScript(relpath+"navtreeindex",function(){ var navTreeIndex = eval('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"]; o.breadcrumbs.unshift(0); showNode(o, o.node, 0); @@ -311,20 +324,12 @@ function initNavTree(toroot,relpath) $(window).bind('hashchange', function(){ if (window.location.hash && window.location.hash.length>1){ - var anchor = $(window.location.hash); - 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); - } + highlightAnchor(); var a; if ($(location).attr('hash')){ var link=stripPath($(location).attr('pathname'))+':'+ $(location).attr('hash').substring(1); - a=$('.item a[class*=\""'+link+'"\"]'); + a=$('.item a[class$=\""'+link+'"\"]'); } if (a && a.length){ $('.item').removeClass('selected'); diff --git a/src/navtree_js.h b/src/navtree_js.h index c231b6b..63c104b 100644 --- a/src/navtree_js.h +++ b/src/navtree_js.h @@ -210,6 +210,21 @@ " }\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" "{\n" " if (node.childrenData && !node.expanded) {\n" @@ -249,15 +264,12 @@ " if ($(location).attr('hash')) {\n" " var link=stripPath($(location).attr('pathname'))+':'+\n" " $(location).attr('hash').substring(1);\n" -" a=$('.item a[class*=\\\"\"'+link+'\"\\\"]');\n" +" a=$('.item a[class$=\\\"\"'+link+'\"\\\"]');\n" " }\n" " if (a && a.length) {\n" " a.parent().parent().addClass('selected');\n" " a.parent().parent().attr('id','selected');\n" -" var anchor = $($(location).attr('hash'));\n" -" var targetDiv = anchor.next();\n" -" $(targetDiv).children('.memproto,.memdoc').\n" -" effect(\"highlight\", {}, 1500);\n" +" highlightAnchor();\n" " } else {\n" " $(n.itemDiv).addClass('selected');\n" " $(n.itemDiv).attr('id','selected');\n" @@ -302,7 +314,8 @@ " getScript(relpath+\"navtreeindex\",function(){\n" " var navTreeIndex = eval('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" " o.breadcrumbs.unshift(0);\n" " showNode(o, o.node, 0);\n" @@ -311,20 +324,12 @@ "\n" " $(window).bind('hashchange', function(){\n" " if (window.location.hash && window.location.hash.length>1){\n" -" var anchor = $(window.location.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 {\n" -" var targetDiv = anchor.next();\n" -" $(targetDiv).children('.memproto,.memdoc').effect(\"highlight\",{},1500);\n" -" }\n" +" highlightAnchor();\n" " var a;\n" " if ($(location).attr('hash')){\n" " var link=stripPath($(location).attr('pathname'))+':'+\n" " $(location).attr('hash').substring(1);\n" -" a=$('.item a[class*=\\\"\"'+link+'\"\\\"]');\n" +" a=$('.item a[class$=\\\"\"'+link+'\"\\\"]');\n" " }\n" " if (a && a.length){\n" " $('.item').removeClass('selected');\n" diff --git a/src/parserintf.h b/src/parserintf.h index 6e79162..2e5397e 100644 --- a/src/parserintf.h +++ b/src/parserintf.h @@ -120,8 +120,8 @@ class ParserManager * @param[in] name A symbolic name of the parser, i.e. "c", * "python", "fortran", "vhdl", ... * @param[in] parser The parser that is to be used for the - * given extension. - * @param[in] defParser Use this parser as the default parser, using + * given name. + * @param[in] defParser Use this parser as the default parser, used * for unregistered file extensions. */ void registerParser(const char *name,ParserInterface *parser,bool defParser=FALSE) diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp index 4923bb1..e49a8ed 100644 --- a/src/rtfdocvisitor.cpp +++ b/src/rtfdocvisitor.cpp @@ -328,13 +328,18 @@ void RTFDocVisitor::visit(DocVerbatim *s) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visit(DocVerbatim)}\n"); + QCString lang = m_langExt; + if (!s->language().isEmpty()) // explicit language setting + { + lang = s->language(); + } switch(s->type()) { case DocVerbatim::Code: // fall though m_t << "{" << endl; m_t << "\\par" << endl; m_t << rtf_Style_Reset << getStyle("CodeExample"); - Doxygen::parserManager->getParser(m_langExt) + Doxygen::parserManager->getParser(lang) ->parseCode(m_ci,s->context(),s->text(), s->isExample(),s->exampleFile()); //m_t << "\\par" << endl; diff --git a/src/scanner.l b/src/scanner.l index d211301..63bfde0 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -69,6 +69,7 @@ static int lastPreLineCtrlContext; static int lastSkipVerbStringContext; static int lastCommentInArgContext; static int lastCSConstraint; +static int lastHereDocContext; static Protection protection; static Protection baseProt; static int sharpCount = 0 ; @@ -138,6 +139,7 @@ static QCString *pCopyCurlyString; static QGString *pCopyCurlyGString; static QGString *pCopyRoundGString; static QGString *pCopyQuotedGString; +static QGString *pCopyHereDocGString; static QGString *pSkipVerbString; static QStack<Grouping> autoGroupStack; @@ -698,6 +700,8 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) %x CopyArgVerbatim %x HereDoc %x HereDocEnd +%x CopyHereDoc +%x CopyHereDocEnd %x IDLAttribute %x IDLProp @@ -1833,13 +1837,14 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) else BEGIN( EndTemplate ); } -<EndTemplate>"<<<" { +<EndTemplate>"<<<" { if (!insidePHP) { REJECT; } else { + lastHereDocContext = YY_START; BEGIN(HereDoc); } } @@ -1922,20 +1927,44 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) else 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 g_hereDocId = yytext; BEGIN(HereDocEnd); } <HereDoc>"'"{ID}/"'" { // PHP nowdoc g_hereDocId = &yytext[1]; + BEGIN(HereDocEnd); } <HereDocEnd>^{ID} { // id at start of the line could mark the end of the block if (g_hereDocId==yytext) // it is the end marker { - BEGIN(FindMembers); + BEGIN(lastHereDocContext); } } <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_PROPERTY" { // Qt property declaration @@ -3130,7 +3159,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) /* <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>"#".* { if (!insidePHP) REJECT; @@ -3142,6 +3171,18 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) lastSkipVerbStringContext=YY_START; BEGIN( SkipVerbString ); } +<ReadBody,ReadNSBody,ReadBodyIntf>"<<<" { if (insidePHP) + { + current->program += yytext ; + pCopyHereDocGString = ¤t->program; + lastHereDocContext=YY_START; + BEGIN( CopyHereDoc ); + } + else + { + REJECT; + } + } <ReadBody,ReadNSBody,ReadBodyIntf>\" { current->program += yytext ; pCopyQuotedGString = ¤t->program; lastStringContext=YY_START; @@ -4470,7 +4511,18 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) yyLineNr++; //addToBody(yytext); } -<SkipCurly,SkipCurlyCpp>[^\n#"'@\\/{}]+ { +<SkipCurly,SkipCurlyCpp>"<<<" { + if (!insidePHP) + { + REJECT; + } + else + { + lastHereDocContext = YY_START; + BEGIN(HereDoc); + } + } +<SkipCurly,SkipCurlyCpp>[^\n#"'@\\/{}<]+ { //addToBody(yytext); } <SkipCurlyCpp>\n { diff --git a/src/section.h b/src/section.h index c4c9517..78516ae 100644 --- a/src/section.h +++ b/src/section.h @@ -28,13 +28,17 @@ class Definition; struct SectionInfo { - enum SectionType { Page, Section, Subsection, - Subsubsection, Paragraph, Anchor + enum SectionType { Page = 0, + Section = 1, + Subsection = 2, + Subsubsection = 3, + Paragraph = 4, + Anchor = 5 }; 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), - fileName(f), generated(FALSE) + fileName(f), generated(FALSE), level(lev) { } SectionInfo(const SectionInfo &s) @@ -51,12 +55,13 @@ struct SectionInfo Definition *definition; QCString fileName; bool generated; + int level; }; -class SectionDict : public QDict<SectionInfo> +class SectionDict : public SDict<SectionInfo> { public: - SectionDict(int size) : QDict<SectionInfo>(size) {} + SectionDict(int size) : SDict<SectionInfo>(size) {} ~SectionDict() {} }; diff --git a/src/tagreader.cpp b/src/tagreader.cpp index b7a7b7a..36119e2 100644 --- a/src/tagreader.cpp +++ b/src/tagreader.cpp @@ -1035,8 +1035,8 @@ void TagFileParser::addDocAnchors(Entry *e,const TagAnchorInfoList &l) //printf("New sectionInfo file=%s anchor=%s\n", // ta->fileName.data(),ta->label.data()); SectionInfo *si=new SectionInfo(ta->fileName,ta->label,ta->label, - SectionInfo::Anchor,m_tagName); - Doxygen::sectionDict.insert(ta->label,si); + SectionInfo::Anchor,0,m_tagName); + Doxygen::sectionDict.append(ta->label,si); e->anchors->append(si); } else diff --git a/src/util.cpp b/src/util.cpp index 6addbc7..3859c97 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -5908,13 +5908,13 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle, file=pd->getOutputFileBase(); } 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", // si->label.data(),si->definition?si->definition->name().data():"<none>", // 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()); - Doxygen::sectionDict.insert(pd->name(),si); + Doxygen::sectionDict.append(pd->name(),si); } } return pd; @@ -6303,6 +6303,7 @@ bool updateLanguageMapping(const QCString &extension,const QCString &language) void initDefaultExtensionMapping() { g_extLookup.setAutoDelete(TRUE); + // extension parser id updateLanguageMapping(".idl", "idl"); updateLanguageMapping(".ddl", "idl"); updateLanguageMapping(".odl", "idl"); @@ -7166,20 +7167,21 @@ QCString langToString(SrcLangExt lang) { switch(lang) { - case SrcLangExt_Unknown: return "Unknown"; - case SrcLangExt_IDL: return "IDL"; - case SrcLangExt_Java: return "Java"; - case SrcLangExt_CSharp: return "C#"; - case SrcLangExt_D: return "D"; - case SrcLangExt_PHP: return "PHP"; - case SrcLangExt_ObjC: return "Objective-C"; - case SrcLangExt_Cpp: return "C++"; - case SrcLangExt_JS: return "Javascript"; - case SrcLangExt_Python: return "Python"; - case SrcLangExt_Fortran: return "Fortran"; - case SrcLangExt_VHDL: return "VHDL"; - case SrcLangExt_XML: return "XML"; - case SrcLangExt_Tcl: return "Tcl"; + case SrcLangExt_Unknown: return "Unknown"; + case SrcLangExt_IDL: return "IDL"; + case SrcLangExt_Java: return "Java"; + case SrcLangExt_CSharp: return "C#"; + case SrcLangExt_D: return "D"; + case SrcLangExt_PHP: return "PHP"; + case SrcLangExt_ObjC: return "Objective-C"; + case SrcLangExt_Cpp: return "C++"; + case SrcLangExt_JS: return "Javascript"; + case SrcLangExt_Python: return "Python"; + case SrcLangExt_Fortran: return "Fortran"; + case SrcLangExt_VHDL: return "VHDL"; + case SrcLangExt_XML: return "XML"; + case SrcLangExt_Tcl: return "Tcl"; + case SrcLangExt_Markdown: return "Markdown"; } return "Unknown"; } |