Doxygen source rename
Source/DoxygenTranslator/src directory is renamed Source/Doxygen Renamed files in this directory to short names using lowercase as is the convention for the rest of the SWIG source. C++ extension is also .cxx like other SWIG source code. I used doxy as the prefix for most file renames because without this Doxygen/parser.* would be easily confused with CParse/parser.* so Doxygen/doxyparser.* is renamed from DoxygenTranslator/src/DoxygenParser.*
This commit is contained in:
parent
0ae73a67ff
commit
ac85784a76
16 changed files with 43 additions and 43 deletions
170
Source/Doxygen/doxycommands.h
Normal file
170
Source/Doxygen/doxycommands.h
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* This file is part of SWIG, which is licensed as a whole under version 3
|
||||
* (or any later version) of the GNU General Public License. Some additional
|
||||
* terms also apply to certain portions of SWIG. The full details of the SWIG
|
||||
* license and copyrights can be found in the LICENSE and COPYRIGHT files
|
||||
* included with the SWIG source code as distributed by the SWIG developers
|
||||
* and at http://www.swig.org/legal.html.
|
||||
*
|
||||
* doxycommands.h
|
||||
*
|
||||
* Part of the Doxygen comment translation module of SWIG.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef DOXYGENCOMMANDS_H
|
||||
#define DOXYGENCOMMANDS_H
|
||||
|
||||
// doxy commands are not processed inside this block
|
||||
const char *CMD_HTML_ONLY = "htmlonly";
|
||||
// doxy commands are not processed inside this block
|
||||
const char *CMD_VERBATIM = "verbatim";
|
||||
const char *CMD_LATEX_1 = "f$";
|
||||
const char *CMD_LATEX_2 = "f{";
|
||||
const char *CMD_LATEX_3 = "f[";
|
||||
const char *CMD_END_HTML_ONLY = "endhtmlonly";
|
||||
const char *CMD_END_VERBATIM = "endverbatim";
|
||||
const char *CMD_END_LATEX_1 = "f$";
|
||||
const char *CMD_END_LATEX_2 = "f}";
|
||||
const char *CMD_END_LATEX_3 = "f]";
|
||||
|
||||
const char *sectionIndicators[] = {
|
||||
"attention", "author", "authors", "brief", "bug", "cond", "date",
|
||||
"deprecated", "details", "else", "elseif", "endcond", "endif",
|
||||
"exception", "if", "ifnot", "invariant", "note", "par", "param",
|
||||
"tparam", "post", "pre", "remarks", "remark", "result", "return",
|
||||
"returns", "retval", "sa", "see", "since", "test", "throw", "throws",
|
||||
"todo", "version", "warning", "xrefitem"
|
||||
};
|
||||
|
||||
const int sectionIndicatorsSize = sizeof(sectionIndicators) / sizeof(*sectionIndicators);
|
||||
|
||||
/* All of the doxygen commands divided up by how they are parsed */
|
||||
const char *simpleCommands[] = {
|
||||
// the first line are escaped chars, except \~, which is a language ID command.
|
||||
"n", "$", "@", "\\", "&", "~", "<", ">", "#", "%", "\"", ".", "::",
|
||||
"endcond",
|
||||
"callgraph", "callergraph", "showinitializer", "hideinitializer", "internal",
|
||||
"nosubgrouping", "public", "publicsection", "private", "privatesection",
|
||||
"protected", "protectedsection", "tableofcontents"
|
||||
};
|
||||
|
||||
const int simpleCommandsSize = sizeof(simpleCommands) / sizeof(*simpleCommands);
|
||||
|
||||
const char *commandWords[] = {
|
||||
"a", "b", "c", "e", "em", "p", "def", "enum", "package", "relates",
|
||||
"namespace", "relatesalso", "anchor", "dontinclude", "include",
|
||||
"includelineno", "copydoc", "copybrief", "copydetails", "verbinclude",
|
||||
"htmlinclude", "extends", "implements", "memberof", "related", "relatedalso",
|
||||
"cite"
|
||||
};
|
||||
|
||||
const int commandWordsSize = sizeof(commandWords) / sizeof(*commandWords);
|
||||
|
||||
const char *commandLines[] = {
|
||||
"addindex", "fn", "name", "line", "var", "skipline", "typedef", "skip",
|
||||
"until", "property"
|
||||
};
|
||||
|
||||
const int commandLinesSize = sizeof(commandLines) / sizeof(*commandLines);
|
||||
|
||||
const char *commandParagraph[] = {
|
||||
"partofdescription", "result", "return", "returns", "remarks", "remark",
|
||||
"since", "test", "sa", "see", "pre", "post", "details", "invariant",
|
||||
"deprecated", "date", "note", "warning", "version", "todo", "bug",
|
||||
"attention", "brief", "author", "authors", "copyright", "short"
|
||||
};
|
||||
|
||||
const int commandParagraphSize = sizeof(commandParagraph) / sizeof(*commandParagraph);
|
||||
|
||||
const char *commandEndCommands[] = {
|
||||
CMD_HTML_ONLY, "latexonly", "manonly", "xmlonly", "link", "rtfonly"
|
||||
};
|
||||
|
||||
const int commandEndCommandsSize = sizeof(commandEndCommands) / sizeof(*commandEndCommands);
|
||||
|
||||
const char *commandWordParagraphs[] = {
|
||||
"param", "tparam", "throw", "throws", "retval", "exception", "example"
|
||||
};
|
||||
|
||||
const int commandWordParagraphsSize = sizeof(commandWordParagraphs) / sizeof(*commandWordParagraphs);
|
||||
|
||||
const char *commandWordLines[] = {
|
||||
"page", "subsection", "subsubsection", "section", "paragraph", "defgroup",
|
||||
"snippet", "mainpage"
|
||||
};
|
||||
|
||||
const int commandWordLinesSize = sizeof(commandWordLines) / sizeof(*commandWordLines);
|
||||
|
||||
const char *commandWordOWordOWords[] = {
|
||||
"category", "class", "protocol", "interface", "struct", "union"
|
||||
};
|
||||
|
||||
const int commandWordOWordOWordsSize = sizeof(commandWordOWordOWords) / sizeof(*commandWordOWordOWords);
|
||||
|
||||
const char *commandOWords[] = {
|
||||
"dir", "file", "cond"
|
||||
};
|
||||
|
||||
const int commandOWordsSize = sizeof(commandOWords) / sizeof(*commandOWords);
|
||||
|
||||
const char *commandErrorThrowings[] = {
|
||||
"annotatedclassstd::list", "classhierarchy", "define", "functionindex", "header",
|
||||
"headerfilestd::list", "inherit", "l", "postheader", "endcode", "enddot", "endmsc", "endhtmlonly",
|
||||
"endlatexonly", "endmanonly", "endlink", "endverbatim", "endxmlonly", "f]", "f}", "endif", "else",
|
||||
"endrtfonly"
|
||||
};
|
||||
|
||||
const int commandErrorThrowingsSize = sizeof(commandErrorThrowings) / sizeof(*commandErrorThrowings);
|
||||
|
||||
const char *commandUniques[] = {
|
||||
"xrefitem", "arg", "ingroup", "par", "headerfile", "overload", "weakgroup", "ref", "subpage", "dotfile", "image", "addtogroup", "li",
|
||||
"if", "ifnot", "elseif", "else", "mscfile", "code", CMD_VERBATIM, "f{", "f[", "f$", "dot", "msc"
|
||||
};
|
||||
|
||||
const int commandUniquesSize = sizeof(commandUniques) / sizeof(*commandUniques);
|
||||
|
||||
// These HTML commands are transformed when producing output in other formats.
|
||||
// Other commands are left intact, but '<' and '> are replaced with entities in HTML
|
||||
// output. So <varName> appears as <varName> in HTML output. The same
|
||||
// behavior must be repeated by SWIG. See Doxygen doc for the list of commands.
|
||||
// '<' is prepended to distinguish HTML tags from Doxygen commands.
|
||||
const char *commandHtml[] = {
|
||||
"<a", "<b", "<blockquote", "<body", "<br", "<center", "<caption", "<code", "<dd", "<dfn",
|
||||
"<div", "<dl", "<dt", "<em", "<form", "<hr", "<h1", "<h2", "<h3", "<i", "<input", "<img",
|
||||
"<li", "<meta", "<multicol", "<ol", "<p", "<pre", "<small", "<span", "<strong",
|
||||
"<sub", "<sup", "<table", "<td", "<th", "<tr", "<tt", "<kbd", "<ul", "<var"
|
||||
};
|
||||
|
||||
const int commandHtmlSize = sizeof(commandHtml) / sizeof(*commandHtml);
|
||||
|
||||
// Only entities which are translatable to plain text are used here. Others
|
||||
// are copied unchanged to output.
|
||||
const char *commandHtmlEntities[] = {
|
||||
"©", // (C)
|
||||
"&trade", // (TM)
|
||||
"®", // (R)
|
||||
"<", // less-than symbol
|
||||
">", // greater-than symbol
|
||||
"&", // ampersand
|
||||
"&apos", // single quotation mark (straight)
|
||||
""", // double quotation mark (straight)
|
||||
"&lsquo", // left single quotation mark
|
||||
"&rsquo", // right single quotation mark
|
||||
"&ldquo", // left double quotation mark
|
||||
"&rdquo", // right double quotation mark
|
||||
"&ndash", // n-dash (for numeric ranges, e.g. 2–8)
|
||||
"&mdash", // --
|
||||
" ", //
|
||||
"×", // x
|
||||
"&minus", // -
|
||||
"&sdot", // .
|
||||
"&sim", // ~
|
||||
"&le", // <=
|
||||
"&ge", // >=
|
||||
"&larr", // <--
|
||||
"&rarr" // -->
|
||||
};
|
||||
|
||||
const int commandHtmlEntitiesSize = sizeof(commandHtmlEntities) / sizeof(*commandHtmlEntities);
|
||||
|
||||
#endif
|
||||
69
Source/Doxygen/doxyentity.cxx
Normal file
69
Source/Doxygen/doxyentity.cxx
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* This file is part of SWIG, which is licensed as a whole under version 3
|
||||
* (or any later version) of the GNU General Public License. Some additional
|
||||
* terms also apply to certain portions of SWIG. The full details of the SWIG
|
||||
* license and copyrights can be found in the LICENSE and COPYRIGHT files
|
||||
* included with the SWIG source code as distributed by the SWIG developers
|
||||
* and at http://www.swig.org/legal.html.
|
||||
*
|
||||
* doxyentity.cxx
|
||||
*
|
||||
* Part of the Doxygen comment translation module of SWIG.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#include "doxyentity.h"
|
||||
#include <iostream>
|
||||
|
||||
using std::cout;
|
||||
|
||||
DoxygenEntity::DoxygenEntity(const std::string &typeEnt):typeOfEntity(typeEnt), isLeaf(true) {
|
||||
}
|
||||
|
||||
|
||||
/* Basic node for commands that have
|
||||
* only 1 item after them
|
||||
* example: \b word
|
||||
* OR holding a std::string
|
||||
*/
|
||||
DoxygenEntity::DoxygenEntity(const std::string &typeEnt, const std::string ¶m1) : typeOfEntity(typeEnt), data(param1), isLeaf(true) {
|
||||
}
|
||||
|
||||
|
||||
/* Nonterminal node
|
||||
* contains
|
||||
*/
|
||||
DoxygenEntity::DoxygenEntity(const std::string &typeEnt, const DoxygenEntityList &entList) : typeOfEntity(typeEnt), isLeaf(false), entityList(entList) {
|
||||
}
|
||||
|
||||
|
||||
void DoxygenEntity::printEntity(int level) const {
|
||||
|
||||
int thisLevel = level;
|
||||
|
||||
if (isLeaf) {
|
||||
for (int i = 0; i < thisLevel; i++) {
|
||||
cout << "\t";
|
||||
}
|
||||
|
||||
cout << "Node Leaf Command: '" << typeOfEntity << "', ";
|
||||
|
||||
if (!data.empty()) {
|
||||
cout << "Node Data: '" << data << "'";
|
||||
}
|
||||
cout << std::endl;
|
||||
|
||||
} else {
|
||||
|
||||
for (int i = 0; i < thisLevel; i++) {
|
||||
cout << "\t";
|
||||
}
|
||||
|
||||
cout << "Node Command: '" << typeOfEntity << "'" << std::endl;
|
||||
|
||||
thisLevel++;
|
||||
|
||||
for (DoxygenEntityListCIt p = entityList.begin(); p != entityList.end(); p++) {
|
||||
p->printEntity(thisLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
45
Source/Doxygen/doxyentity.h
Normal file
45
Source/Doxygen/doxyentity.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* This file is part of SWIG, which is licensed as a whole under version 3
|
||||
* (or any later version) of the GNU General Public License. Some additional
|
||||
* terms also apply to certain portions of SWIG. The full details of the SWIG
|
||||
* license and copyrights can be found in the LICENSE and COPYRIGHT files
|
||||
* included with the SWIG source code as distributed by the SWIG developers
|
||||
* and at http://www.swig.org/legal.html.
|
||||
*
|
||||
* doxyentity.h
|
||||
*
|
||||
* Part of the Doxygen comment translation module of SWIG.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef DOXYGENENTITY_H_
|
||||
#define DOXYGENENTITY_H_
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
||||
|
||||
class DoxygenEntity;
|
||||
|
||||
typedef std::list<DoxygenEntity> DoxygenEntityList;
|
||||
typedef DoxygenEntityList::iterator DoxygenEntityListIt;
|
||||
typedef DoxygenEntityList::const_iterator DoxygenEntityListCIt;
|
||||
|
||||
|
||||
/*
|
||||
* Structure to represent a doxygen comment entry
|
||||
*/
|
||||
class DoxygenEntity {
|
||||
public:
|
||||
std::string typeOfEntity;
|
||||
std::string data;
|
||||
bool isLeaf;
|
||||
DoxygenEntityList entityList;
|
||||
|
||||
DoxygenEntity(const std::string &typeEnt);
|
||||
DoxygenEntity(const std::string &typeEnt, const std::string ¶m1);
|
||||
DoxygenEntity(const std::string &typeEnt, const DoxygenEntityList &entList);
|
||||
|
||||
void printEntity(int level) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
1422
Source/Doxygen/doxyparser.cxx
Normal file
1422
Source/Doxygen/doxyparser.cxx
Normal file
File diff suppressed because it is too large
Load diff
372
Source/Doxygen/doxyparser.h
Normal file
372
Source/Doxygen/doxyparser.h
Normal file
|
|
@ -0,0 +1,372 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* This file is part of SWIG, which is licensed as a whole under version 3
|
||||
* (or any later version) of the GNU General Public License. Some additional
|
||||
* terms also apply to certain portions of SWIG. The full details of the SWIG
|
||||
* license and copyrights can be found in the LICENSE and COPYRIGHT files
|
||||
* included with the SWIG source code as distributed by the SWIG developers
|
||||
* and at http://www.swig.org/legal.html.
|
||||
*
|
||||
* doxyparser.h
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef DOXYGENPARSER_H_
|
||||
#define DOXYGENPARSER_H_
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#include "swig.h"
|
||||
|
||||
#include "doxyentity.h"
|
||||
|
||||
class DoxygenParser {
|
||||
private:
|
||||
|
||||
enum DoxyCommandEnum {
|
||||
NONE = -1,
|
||||
SIMPLECOMMAND,
|
||||
COMMANDWORD,
|
||||
COMMANDLINE,
|
||||
COMMANDPARAGRAPH,
|
||||
COMMANDENDCOMMAND,
|
||||
COMMANDWORDPARAGRAPH,
|
||||
COMMANDWORDLINE,
|
||||
COMMANDWORDOWORDWORD,
|
||||
COMMANDOWORD,
|
||||
COMMANDERRORTHROW,
|
||||
COMMANDUNIQUE,
|
||||
COMMAND_HTML,
|
||||
COMMAND_HTML_ENTITY,
|
||||
COMMAND_ALIAS,
|
||||
COMMAND_IGNORE,
|
||||
END_LINE,
|
||||
PARAGRAPH_END,
|
||||
PLAINSTRING,
|
||||
COMMAND
|
||||
};
|
||||
|
||||
|
||||
/** This class contains parts of Doxygen comment as a token. */
|
||||
class Token {
|
||||
public:
|
||||
DoxyCommandEnum m_tokenType;
|
||||
std::string m_tokenString; /* the data , such as param for @param */
|
||||
|
||||
Token(DoxyCommandEnum tType, std::string tString) : m_tokenType(tType), m_tokenString(tString) {
|
||||
}
|
||||
|
||||
std::string toString() const {
|
||||
switch (m_tokenType) {
|
||||
case END_LINE:
|
||||
return "{END OF LINE}";
|
||||
case PARAGRAPH_END:
|
||||
return "{END OF PARAGRAPH}";
|
||||
case PLAINSTRING:
|
||||
return "{PLAINSTRING :" + m_tokenString + "}";
|
||||
case COMMAND:
|
||||
return "{COMMAND : " + m_tokenString + "}";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector<Token> TokenList;
|
||||
typedef TokenList::const_iterator TokenListCIt;
|
||||
typedef TokenList::iterator TokenListIt;
|
||||
|
||||
TokenList m_tokenList;
|
||||
TokenListCIt m_tokenListIt;
|
||||
|
||||
typedef std::map<std::string, DoxyCommandEnum> DoxyCommandsMap;
|
||||
typedef DoxyCommandsMap::iterator DoxyCommandsMapIt;
|
||||
|
||||
/*
|
||||
* Map of Doxygen commands to determine if a string is a
|
||||
* command and how it needs to be parsed
|
||||
*/
|
||||
static DoxyCommandsMap doxygenCommands;
|
||||
static std::set<std::string> doxygenSectionIndicators;
|
||||
|
||||
bool m_isVerbatimText; // used to handle \htmlonly and \verbatim commands
|
||||
bool m_isInQuotedString;
|
||||
|
||||
Node *m_node;
|
||||
std::string m_fileName;
|
||||
int m_fileLineNo;
|
||||
|
||||
/*
|
||||
* Return the end command for a command appearing in "ignore" feature or empty
|
||||
* string if this is a simple command and not a block one.
|
||||
*/
|
||||
std::string getIgnoreFeatureEndCommand(const std::string &theCommand) const;
|
||||
|
||||
/*
|
||||
* Helper for getting the value of doxygen:ignore feature or its argument.
|
||||
*/
|
||||
String *getIgnoreFeature(const std::string &theCommand, const char *argument = NULL) const;
|
||||
|
||||
/*
|
||||
* Whether to print lots of debug info during parsing
|
||||
*/
|
||||
bool noisy;
|
||||
|
||||
/*
|
||||
*Changes a std::string to all lower case
|
||||
*/
|
||||
std::string stringToLower(const std::string &stringToConvert);
|
||||
|
||||
/*
|
||||
* isSectionIndicator returns a boolean if the command is a section indicator
|
||||
* This is a helper method for finding the end of a paragraph
|
||||
* by Doxygen's terms
|
||||
*/
|
||||
bool isSectionIndicator(const std::string &smallString);
|
||||
/*
|
||||
* Determines how a command should be handled (what group it belongs to
|
||||
* for parsing rules
|
||||
*/
|
||||
DoxyCommandEnum commandBelongs(const std::string &theCommand);
|
||||
|
||||
/*
|
||||
*prints the parse tree
|
||||
*/
|
||||
void printTree(const std::list<DoxygenEntity> &rootList);
|
||||
|
||||
/**
|
||||
* Returns true if the next token is end of line token. This is important
|
||||
* when single word commands like \c are at the end of line.
|
||||
*/
|
||||
bool isEndOfLine();
|
||||
|
||||
/**
|
||||
* Skips spaces, tabs, and end of line tokens.
|
||||
*/
|
||||
void skipWhitespaceTokens();
|
||||
|
||||
/**
|
||||
* Removes all spaces and tabs from beginning end end of string.
|
||||
*/
|
||||
std::string trim(const std::string &text);
|
||||
|
||||
/*
|
||||
* Returns string of the next token if the next token is PLAINSTRING. Returns
|
||||
* empty string otherwise.
|
||||
*/
|
||||
std::string getNextToken();
|
||||
|
||||
/*
|
||||
* Returns the next word ON THE CURRENT LINE ONLY
|
||||
* if a new line is encountered, returns a blank std::string.
|
||||
* Updates the iterator if successful.
|
||||
*/
|
||||
std::string getNextWord();
|
||||
|
||||
/*
|
||||
* Returns the next word, which is not necessarily on the same line.
|
||||
* Updates the iterator if successful.
|
||||
*/
|
||||
std::string getNextWordInComment();
|
||||
|
||||
/*
|
||||
* Returns the location of the end of the line as
|
||||
* an iterator.
|
||||
*/
|
||||
TokenListCIt getOneLine(const TokenList &tokList);
|
||||
|
||||
/*
|
||||
* Returns a properly formatted std::string
|
||||
* up til ANY command or end of line is encountered.
|
||||
*/
|
||||
std::string getStringTilCommand(const TokenList &tokList);
|
||||
|
||||
/*
|
||||
* Returns a properly formatted std::string
|
||||
* up til the command specified is encountered
|
||||
*/
|
||||
//TODO check that this behaves properly for formulas
|
||||
std::string getStringTilEndCommand(const std::string &theCommand, const TokenList &tokList);
|
||||
|
||||
/*
|
||||
* Returns the end of a Paragraph as an iterator-
|
||||
* Paragraph is defined in Doxygen to be a paragraph of text
|
||||
* separated by either a structural command or a blank line
|
||||
*/
|
||||
TokenListCIt getEndOfParagraph(const TokenList &tokList);
|
||||
|
||||
/*
|
||||
* Returns the end of a section, defined as the first blank line OR first
|
||||
* encounter of the same command. Example of this behaviour is \arg.
|
||||
* If no end is encountered, returns the last token of the std::list.
|
||||
*/
|
||||
TokenListCIt getEndOfSection(const std::string &theCommand, const TokenList &tokList);
|
||||
|
||||
/*
|
||||
* This method is for returning the end of a specific form of doxygen command
|
||||
* that begins with a \command and ends in \endcommand
|
||||
* such as \code and \endcode. The proper usage is
|
||||
* progressTilEndCommand("endcode", tokenList);
|
||||
* If the end is never encountered, it returns the end of the std::list.
|
||||
*/
|
||||
TokenListCIt getEndCommand(const std::string &theCommand, const TokenList &tokList);
|
||||
/*
|
||||
* A special method for commands such as \arg that end at the end of a
|
||||
* paragraph OR when another \arg is encountered
|
||||
//TODO getTilAnyCommand
|
||||
TokenListCIt getTilAnyCommand(const std::string &theCommand, const TokenList &tokList);
|
||||
*/
|
||||
|
||||
/**
|
||||
* This methods skips end of line token, if it is the next token to be
|
||||
* processed. It is called with comment commands which have args till the
|
||||
* end of line, such as 'addtogroup' or 'addindex'.
|
||||
* It is up to translator to specific language to decide whether
|
||||
* to insert eol or not. For example, if a command is ignored in target
|
||||
* language, new lines may make formatting ugly (Python).
|
||||
*/
|
||||
void skipEndOfLine();
|
||||
|
||||
/*
|
||||
* Method for Adding a Simple Command
|
||||
* Format: @command
|
||||
* Plain commands, such as newline etc, they contain no other data
|
||||
* \n \\ \@ \& \$ \# \< \> \%
|
||||
*/
|
||||
void addSimpleCommand(const std::string &theCommand, DoxygenEntityList &doxyList);
|
||||
/*
|
||||
* CommandWord
|
||||
* Format: @command <word>
|
||||
* Commands with a single WORD after then such as @b
|
||||
* "a", "b", "c", "e", "em", "p", "def", "enum", "example", "package",
|
||||
* "relates", "namespace", "relatesalso","anchor", "dontinclude", "include",
|
||||
* "includelineno"
|
||||
*/
|
||||
void addCommandWord(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
/*
|
||||
* CommandLine
|
||||
* Format: @command (line)
|
||||
* Commands with a single LINE after then such as @var
|
||||
* "addindex", "fn", "name", "line", "var", "skipline", "typedef", "skip",
|
||||
* "until", "property"
|
||||
*/
|
||||
void addCommandLine(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
/*
|
||||
* CommandParagraph
|
||||
* Format: @command {paragraph}
|
||||
* Commands with a single paragraph after then such as @return
|
||||
* "return", "remarks", "since", "test", "sa", "see", "pre", "post",
|
||||
* "details", "invariant", "deprecated", "date", "note", "warning",
|
||||
* "version", "todo", "bug", "attention", "brief", "arg", "author"
|
||||
*/
|
||||
void addCommandParagraph(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
/*
|
||||
* Command EndCommand
|
||||
* Format: @command and ends at @endcommand
|
||||
* Commands that take in a block of text such as @code:
|
||||
* "code", "dot", "msc", "f$", "f[", "f{environment}{", "htmlonly",
|
||||
* "latexonly", "manonly", "verbatim", "xmlonly", "cond", "if", "ifnot",
|
||||
* "link"
|
||||
* Returns 1 if success, 0 if the endcommand is never encountered.
|
||||
*/
|
||||
void addCommandEndCommand(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
/*
|
||||
* CommandWordParagraph
|
||||
* Format: @command <word> {paragraph}
|
||||
* Commands such as param
|
||||
* "param", "tparam", "throw", "throws", "retval", "exception"
|
||||
*/
|
||||
void addCommandWordParagraph(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
/*
|
||||
* CommandWordLine
|
||||
* Format: @command <word> (line)
|
||||
* Commands such as param
|
||||
* "page", "subsection", "subsubsection", "section", "paragraph", "defgroup"
|
||||
*/
|
||||
void addCommandWordLine(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
/*
|
||||
* Command Word Optional Word Optional Word
|
||||
* Format: @command <word> [<header-file>] [<header-name>]
|
||||
* Commands such as class
|
||||
* "category", "class", "protocol", "interface", "struct", "union"
|
||||
*/
|
||||
void addCommandWordOWordOWord(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
/*
|
||||
* Command Optional Word
|
||||
* Format: @command [<word>]
|
||||
* Commands such as dir
|
||||
* "dir", "file", "cond"
|
||||
*/
|
||||
void addCommandOWord(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
|
||||
/*
|
||||
* Commands that should not be encountered (such as PHP only)
|
||||
* goes til the end of line then returns
|
||||
*/
|
||||
void addCommandErrorThrow(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
|
||||
void addCommandHtml(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
|
||||
void addCommandHtmlEntity(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
|
||||
/*
|
||||
*Adds the unique commands- different process for each unique command
|
||||
*/
|
||||
void addCommandUnique(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
|
||||
/*
|
||||
* Replace the given command with its predefined alias expansion.
|
||||
*/
|
||||
void aliasCommand(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
|
||||
/*
|
||||
* Simply ignore the given command, possibly with the word following it or
|
||||
* until the matching end command.
|
||||
*/
|
||||
void ignoreCommand(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
|
||||
/*
|
||||
* The actual "meat" of the doxygen parser. Calls the correct addCommand...()
|
||||
* function.
|
||||
*/
|
||||
void addCommand(const std::string &commandString, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
|
||||
DoxygenEntityList parse(TokenListCIt endParsingIndex, const TokenList &tokList, bool root = false);
|
||||
|
||||
/*
|
||||
* Fill static doxygenCommands and sectionIndicators containers
|
||||
*/
|
||||
void fillTables();
|
||||
|
||||
/** Processes comment when \htmlonly and \verbatim commands are encountered. */
|
||||
size_t processVerbatimText(size_t pos, const std::string &line);
|
||||
|
||||
bool processEscapedChars(size_t &pos, const std::string &line);
|
||||
void processWordCommands(size_t &pos, const std::string &line);
|
||||
void processHtmlTags(size_t &pos, const std::string &line);
|
||||
void processHtmlEntities(size_t &pos, const std::string &line);
|
||||
|
||||
|
||||
/** Processes comment outside \htmlonly and \verbatim commands. */
|
||||
size_t processNormalComment(size_t pos, const std::string &line);
|
||||
|
||||
void tokenizeDoxygenComment(const std::string &doxygenComment, const std::string &fileName, int fileLine);
|
||||
void printList();
|
||||
void printListError(int warningType, const std::string &message);
|
||||
|
||||
typedef std::vector<std::string> StringVector;
|
||||
typedef StringVector::const_iterator StringVectorCIt;
|
||||
|
||||
StringVector split(const std::string &text, char separator);
|
||||
bool isStartOfDoxyCommentChar(char c);
|
||||
bool addDoxyCommand(DoxygenParser::TokenList &tokList, const std::string &cmd);
|
||||
|
||||
public:
|
||||
DoxygenParser(bool noisy = false);
|
||||
virtual ~DoxygenParser();
|
||||
DoxygenEntityList createTree(Node *node, String *documentation);
|
||||
};
|
||||
|
||||
#endif
|
||||
50
Source/Doxygen/doxytranslator.cxx
Normal file
50
Source/Doxygen/doxytranslator.cxx
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* This file is part of SWIG, which is licensed as a whole under version 3
|
||||
* (or any later version) of the GNU General Public License. Some additional
|
||||
* terms also apply to certain portions of SWIG. The full details of the SWIG
|
||||
* license and copyrights can be found in the LICENSE and COPYRIGHT files
|
||||
* included with the SWIG source code as distributed by the SWIG developers
|
||||
* and at http://www.swig.org/legal.html.
|
||||
*
|
||||
* doxytranslator.cxx
|
||||
*
|
||||
* Module to return documentation for nodes formatted for various documentation
|
||||
* systems.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#include "doxytranslator.h"
|
||||
|
||||
DoxygenTranslator::DoxygenTranslator(int flags) : m_flags(flags), parser((flags &debug_parser) != 0) {
|
||||
}
|
||||
|
||||
|
||||
DoxygenTranslator::~DoxygenTranslator() {
|
||||
}
|
||||
|
||||
|
||||
bool DoxygenTranslator::hasDocumentation(Node *node) {
|
||||
return getDoxygenComment(node) != NULL;
|
||||
}
|
||||
|
||||
|
||||
String *DoxygenTranslator::getDoxygenComment(Node *node) {
|
||||
return Getattr(node, "doxygen");
|
||||
}
|
||||
|
||||
|
||||
String *DoxygenTranslator::getDocumentation(Node *node) {
|
||||
|
||||
if (!hasDocumentation(node)) {
|
||||
return NewString("");
|
||||
}
|
||||
|
||||
return makeDocumentation(node);
|
||||
}
|
||||
|
||||
|
||||
void DoxygenTranslator::printTree(const DoxygenEntityList &entityList) {
|
||||
|
||||
for (DoxygenEntityListCIt p = entityList.begin(); p != entityList.end(); p++) {
|
||||
p->printEntity(0);
|
||||
}
|
||||
}
|
||||
89
Source/Doxygen/doxytranslator.h
Normal file
89
Source/Doxygen/doxytranslator.h
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* This file is part of SWIG, which is licensed as a whole under version 3
|
||||
* (or any later version) of the GNU General Public License. Some additional
|
||||
* terms also apply to certain portions of SWIG. The full details of the SWIG
|
||||
* license and copyrights can be found in the LICENSE and COPYRIGHT files
|
||||
* included with the SWIG source code as distributed by the SWIG developers
|
||||
* and at http://www.swig.org/legal.html.
|
||||
*
|
||||
* doxytranslator.h
|
||||
*
|
||||
* Module to return documentation for nodes formatted for various documentation
|
||||
* systems.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef DOXYGENTRANSLATOR_H_
|
||||
#define DOXYGENTRANSLATOR_H_
|
||||
|
||||
#include "swig.h"
|
||||
#include "doxyentity.h"
|
||||
#include "doxyparser.h"
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
|
||||
/*
|
||||
* This is a base class for translator classes. It defines the basic interface
|
||||
* for translators, which convert Doxygen comments into alternative formats for
|
||||
* target languages.
|
||||
*/
|
||||
class DoxygenTranslator {
|
||||
public:
|
||||
/*
|
||||
* Bit flags for the translator ctor.
|
||||
*
|
||||
* Derived classes may define additional flags.
|
||||
*/
|
||||
enum {
|
||||
// Use DoxygenParser in "noisy" mode.
|
||||
debug_parser = 1,
|
||||
|
||||
// Output results of translating Doxygen comments.
|
||||
debug_translator = 2
|
||||
};
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
DoxygenTranslator(int flags = 0);
|
||||
|
||||
/*
|
||||
* Virtual destructor.
|
||||
*/
|
||||
virtual ~DoxygenTranslator();
|
||||
|
||||
/*
|
||||
* Return the documentation for a given node formated for the correct
|
||||
* documentation system.
|
||||
*/
|
||||
String *getDocumentation(Node *node);
|
||||
|
||||
/*
|
||||
* Returns truem is the specified node has comment attached.
|
||||
*/
|
||||
bool hasDocumentation(Node *node);
|
||||
|
||||
/*
|
||||
* Get original comment string in Doxygen-format.
|
||||
*/
|
||||
String *getDoxygenComment(Node *node);
|
||||
|
||||
protected:
|
||||
// The flags passed to the ctor.
|
||||
const int m_flags;
|
||||
|
||||
DoxygenParser parser;
|
||||
|
||||
/*
|
||||
* Returns the documentation formatted for a target language.
|
||||
*/
|
||||
virtual String *makeDocumentation(Node *node) = 0;
|
||||
|
||||
/*
|
||||
* Prints the details of a parsed entity list to stdout (for debugging).
|
||||
*/
|
||||
void printTree(const DoxygenEntityList &entityList);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
844
Source/Doxygen/javadoc.cxx
Normal file
844
Source/Doxygen/javadoc.cxx
Normal file
|
|
@ -0,0 +1,844 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* This file is part of SWIG, which is licensed as a whole under version 3
|
||||
* (or any later version) of the GNU General Public License. Some additional
|
||||
* terms also apply to certain portions of SWIG. The full details of the SWIG
|
||||
* license and copyrights can be found in the LICENSE and COPYRIGHT files
|
||||
* included with the SWIG source code as distributed by the SWIG developers
|
||||
* and at http://www.swig.org/legal.html.
|
||||
*
|
||||
* javadoc.cxx
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#include "javadoc.h"
|
||||
#include "doxyparser.h"
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include "swigmod.h"
|
||||
#define APPROX_LINE_LENGTH 64 // characters per line allowed
|
||||
#define TAB_SIZE 8 // current tab size in spaces
|
||||
//TODO {@link} {@linkplain} {@docRoot}, and other useful doxy commands that are not a javadoc tag
|
||||
|
||||
// define static tables, they are filled in JavaDocConverter's constructor
|
||||
std::map<std::string, std::pair<JavaDocConverter::tagHandler, std::string> > JavaDocConverter::tagHandlers;
|
||||
|
||||
using std::string;
|
||||
using std::list;
|
||||
using std::vector;
|
||||
|
||||
void JavaDocConverter::fillStaticTables() {
|
||||
if (tagHandlers.size()) // fill only once
|
||||
return;
|
||||
|
||||
/*
|
||||
* Some translation rules:
|
||||
*
|
||||
* @ and \ must be escaped for both Java and Python to appear on output: \@, \\,
|
||||
* while Doxygen produces output in both cases.
|
||||
* Rule: @ and \ with space on the right should get to output.
|
||||
*
|
||||
* :: remains intact, even in class::method(). But you can use class#method also
|
||||
* in C++ comment and it is properly translated to C++ output (changed by doxygen to ::)
|
||||
* and Java output (remains #).
|
||||
* Rule: SWIG type system can't be used to convert C::m to C#m, because in Java it is C.m
|
||||
* Use string replacement :: --> # in tag see and links.
|
||||
*
|
||||
* HTML tags must be translated - remain in Java, to markdown in Python
|
||||
*
|
||||
* Unknown HTML tags, for example <x> is translated to <x> by doxygen, while
|
||||
* Java src is <x> and therefore invisible on output - browser ignores unknown command.
|
||||
* This is handy in syntax descriptions, for example: more <fileName>.
|
||||
*
|
||||
* Standalone < and > need not be translated, they are rendered properly in
|
||||
* all three outputs.
|
||||
*
|
||||
* ., %, and " need not to be translated
|
||||
*
|
||||
* entities must be translated - remain in Java, something meaningful in Python (<, ...)
|
||||
*
|
||||
* - Python
|
||||
* - add comments also to auto-generated methods like equals(), delete() in Java,
|
||||
* and methods for std::vector(), ...
|
||||
* Commenting methods of std types is simple - add comment to std_*.i file.
|
||||
*/
|
||||
|
||||
// these commands insert HTML tags
|
||||
tagHandlers["a"] = make_pair(&JavaDocConverter::handleTagHtml, "i");
|
||||
tagHandlers["arg"] = make_pair(&JavaDocConverter::handleTagHtml, "li");
|
||||
tagHandlers["b"] = make_pair(&JavaDocConverter::handleTagHtml, "b");
|
||||
tagHandlers["c"] = make_pair(&JavaDocConverter::handleTagHtml, "code");
|
||||
tagHandlers["cite"] = make_pair(&JavaDocConverter::handleTagHtml, "i");
|
||||
tagHandlers["e"] = make_pair(&JavaDocConverter::handleTagHtml, "i");
|
||||
tagHandlers["em"] = make_pair(&JavaDocConverter::handleTagHtml, "i");
|
||||
tagHandlers["li"] = make_pair(&JavaDocConverter::handleTagHtml, "li");
|
||||
tagHandlers["p"] = make_pair(&JavaDocConverter::handleTagHtml, "code");
|
||||
// these commands insert just a single char, some of them need to be escaped
|
||||
tagHandlers["$"] = make_pair(&JavaDocConverter::handleTagChar, "");
|
||||
tagHandlers["@"] = make_pair(&JavaDocConverter::handleTagChar, "");
|
||||
tagHandlers["\\"] = make_pair(&JavaDocConverter::handleTagChar, "");
|
||||
tagHandlers["<"] = make_pair(&JavaDocConverter::handleTagChar, "<");
|
||||
tagHandlers[">"] = make_pair(&JavaDocConverter::handleTagChar, ">");
|
||||
tagHandlers["&"] = make_pair(&JavaDocConverter::handleTagChar, "&");
|
||||
tagHandlers["#"] = make_pair(&JavaDocConverter::handleTagChar, "");
|
||||
tagHandlers["%"] = make_pair(&JavaDocConverter::handleTagChar, "");
|
||||
tagHandlers["~"] = make_pair(&JavaDocConverter::handleTagChar, "");
|
||||
tagHandlers["\""] = make_pair(&JavaDocConverter::handleTagChar, """);
|
||||
tagHandlers["."] = make_pair(&JavaDocConverter::handleTagChar, "");
|
||||
tagHandlers["::"] = make_pair(&JavaDocConverter::handleTagChar, "");
|
||||
// these commands are stripped out
|
||||
tagHandlers["attention"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
tagHandlers["anchor"] = make_pair(&JavaDocConverter::handleTagAnchor, "");
|
||||
tagHandlers["brief"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
tagHandlers["bug"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
tagHandlers["date"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
tagHandlers["details"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
// this command is inserts text accumulated after cmd htmlonly -
|
||||
// see DoxygenParser - CMD_HTML_ONLY.
|
||||
tagHandlers["htmlonly"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
tagHandlers["invariant"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
tagHandlers["latexonly"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
tagHandlers["manonly"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
tagHandlers["partofdescription"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
tagHandlers["rtfonly"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
tagHandlers["short"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
tagHandlers["xmlonly"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
// these commands are kept as-is, they are supported by JavaDoc
|
||||
tagHandlers["author"] = make_pair(&JavaDocConverter::handleTagSame, "");
|
||||
tagHandlers["authors"] = make_pair(&JavaDocConverter::handleTagSame, "author");
|
||||
tagHandlers["deprecated"] = make_pair(&JavaDocConverter::handleTagSame, "");
|
||||
tagHandlers["exception"] = make_pair(&JavaDocConverter::handleTagSame, "");
|
||||
tagHandlers["package"] = make_pair(&JavaDocConverter::handleTagSame, "");
|
||||
tagHandlers["param"] = make_pair(&JavaDocConverter::handleTagParam, "");
|
||||
tagHandlers["tparam"] = make_pair(&JavaDocConverter::handleTagParam, "");
|
||||
tagHandlers["ref"] = make_pair(&JavaDocConverter::handleTagRef, "");
|
||||
tagHandlers["result"] = make_pair(&JavaDocConverter::handleTagSame, "return");
|
||||
tagHandlers["return"] = make_pair(&JavaDocConverter::handleTagSame, "");
|
||||
tagHandlers["returns"] = make_pair(&JavaDocConverter::handleTagSame, "return");
|
||||
//tagHandlers["see"] = make_pair(&JavaDocConverter::handleTagSame, "");
|
||||
//tagHandlers["sa"] = make_pair(&JavaDocConverter::handleTagSame, "see");
|
||||
tagHandlers["since"] = make_pair(&JavaDocConverter::handleTagSame, "");
|
||||
tagHandlers["throws"] = make_pair(&JavaDocConverter::handleTagSame, "");
|
||||
tagHandlers["throw"] = make_pair(&JavaDocConverter::handleTagSame, "throws");
|
||||
tagHandlers["version"] = make_pair(&JavaDocConverter::handleTagSame, "");
|
||||
// these commands have special handlers
|
||||
tagHandlers["code"] = make_pair(&JavaDocConverter::handleTagExtended, "code");
|
||||
tagHandlers["cond"] = make_pair(&JavaDocConverter::handleTagMessage, "Conditional comment: ");
|
||||
tagHandlers["copyright"] = make_pair(&JavaDocConverter::handleTagMessage, "Copyright: ");
|
||||
tagHandlers["else"] = make_pair(&JavaDocConverter::handleTagIf, "Else: ");
|
||||
tagHandlers["elseif"] = make_pair(&JavaDocConverter::handleTagIf, "Else if: ");
|
||||
tagHandlers["endcond"] = make_pair(&JavaDocConverter::handleTagMessage, "End of conditional comment.");
|
||||
// space in second arg prevents Javadoc to treat '@ example' as command. File name of
|
||||
// example is still informative to user.
|
||||
tagHandlers["example"] = make_pair(&JavaDocConverter::handleTagSame, " example");
|
||||
tagHandlers["if"] = make_pair(&JavaDocConverter::handleTagIf, "If: ");
|
||||
tagHandlers["ifnot"] = make_pair(&JavaDocConverter::handleTagIf, "If not: ");
|
||||
tagHandlers["image"] = make_pair(&JavaDocConverter::handleTagImage, "");
|
||||
tagHandlers["link"] = make_pair(&JavaDocConverter::handleTagLink, "");
|
||||
tagHandlers["see"] = make_pair(&JavaDocConverter::handleTagSee, "");
|
||||
tagHandlers["sa"] = make_pair(&JavaDocConverter::handleTagSee, "");
|
||||
tagHandlers["note"] = make_pair(&JavaDocConverter::handleTagMessage, "Note: ");
|
||||
tagHandlers["overload"] = make_pair(&JavaDocConverter::handleTagMessage,
|
||||
"This is an overloaded member function, provided for"
|
||||
" convenience. It differs from the above function only in what" " argument(s) it accepts.");
|
||||
tagHandlers["par"] = make_pair(&JavaDocConverter::handleTagPar, "");
|
||||
tagHandlers["remark"] = make_pair(&JavaDocConverter::handleTagMessage, "Remarks: ");
|
||||
tagHandlers["remarks"] = make_pair(&JavaDocConverter::handleTagMessage, "Remarks: ");
|
||||
tagHandlers["todo"] = make_pair(&JavaDocConverter::handleTagMessage, "TODO: ");
|
||||
tagHandlers["verbatim"] = make_pair(&JavaDocConverter::handleTagExtended, "literal");
|
||||
|
||||
// \f commands output literal Latex formula, which is still better than nothing.
|
||||
tagHandlers["f$"] = make_pair(&JavaDocConverter::handleTagVerbatim, "");
|
||||
tagHandlers["f["] = make_pair(&JavaDocConverter::handleTagVerbatim, "");
|
||||
tagHandlers["f{"] = make_pair(&JavaDocConverter::handleTagVerbatim, "");
|
||||
|
||||
tagHandlers["warning"] = make_pair(&JavaDocConverter::handleTagMessage, "Warning: ");
|
||||
// this command just prints it's contents
|
||||
// (it is internal command of swig's parser, contains plain text)
|
||||
tagHandlers["plainstd::string"] = make_pair(&JavaDocConverter::handlePlainString, "");
|
||||
tagHandlers["plainstd::endl"] = make_pair(&JavaDocConverter::handleNewLine, "");
|
||||
tagHandlers["n"] = make_pair(&JavaDocConverter::handleNewLine, "");
|
||||
|
||||
// HTML tags
|
||||
tagHandlers["<a"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<a");
|
||||
tagHandlers["<b"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<b");
|
||||
tagHandlers["<blockquote"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<blockquote");
|
||||
tagHandlers["<body"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<body");
|
||||
tagHandlers["<br"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<br");
|
||||
tagHandlers["<center"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<center");
|
||||
tagHandlers["<caption"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<caption");
|
||||
tagHandlers["<code"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<code");
|
||||
tagHandlers["<dd"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<dd");
|
||||
tagHandlers["<dfn"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<dfn");
|
||||
tagHandlers["<div"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<div");
|
||||
tagHandlers["<dl"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<dl");
|
||||
tagHandlers["<dt"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<dt");
|
||||
tagHandlers["<em"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<em");
|
||||
tagHandlers["<form"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<form");
|
||||
tagHandlers["<hr"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<hr");
|
||||
tagHandlers["<h1"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<h1");
|
||||
tagHandlers["<h2"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<h2");
|
||||
tagHandlers["<h3"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<h3");
|
||||
tagHandlers["<i"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<i");
|
||||
tagHandlers["<input"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<input");
|
||||
tagHandlers["<img"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<img");
|
||||
tagHandlers["<li"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<li");
|
||||
tagHandlers["<meta"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<meta");
|
||||
tagHandlers["<multicol"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<multicol");
|
||||
tagHandlers["<ol"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<ol");
|
||||
tagHandlers["<p"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<p");
|
||||
tagHandlers["<pre"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<pre");
|
||||
tagHandlers["<small"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<small");
|
||||
tagHandlers["<span"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<span");
|
||||
tagHandlers["<strong"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<strong");
|
||||
tagHandlers["<sub"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<sub");
|
||||
tagHandlers["<sup"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<sup");
|
||||
tagHandlers["<table"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<table");
|
||||
tagHandlers["<td"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<td");
|
||||
tagHandlers["<th"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<th");
|
||||
tagHandlers["<tr"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<tr");
|
||||
tagHandlers["<tt"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<tt");
|
||||
tagHandlers["<kbd"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<kbd");
|
||||
tagHandlers["<ul"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<ul");
|
||||
tagHandlers["<var"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<var");
|
||||
|
||||
// HTML entities
|
||||
tagHandlers["©"] = make_pair(&JavaDocConverter::handleHtmlEntity, "©");
|
||||
tagHandlers["&trade"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&trade");
|
||||
tagHandlers["®"] = make_pair(&JavaDocConverter::handleHtmlEntity, "®");
|
||||
tagHandlers["<"] = make_pair(&JavaDocConverter::handleHtmlEntity, "<");
|
||||
tagHandlers[">"] = make_pair(&JavaDocConverter::handleHtmlEntity, ">");
|
||||
tagHandlers["&"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&");
|
||||
tagHandlers["&apos"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&apos");
|
||||
tagHandlers["""] = make_pair(&JavaDocConverter::handleHtmlEntity, """);
|
||||
tagHandlers["&lsquo"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&lsquo");
|
||||
tagHandlers["&rsquo"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&rsquo");
|
||||
tagHandlers["&ldquo"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&ldquo");
|
||||
tagHandlers["&rdquo"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&rdquo");
|
||||
tagHandlers["&ndash"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&ndash");
|
||||
tagHandlers["&mdash"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&mdash");
|
||||
tagHandlers[" "] = make_pair(&JavaDocConverter::handleHtmlEntity, " ");
|
||||
tagHandlers["×"] = make_pair(&JavaDocConverter::handleHtmlEntity, "×");
|
||||
tagHandlers["&minus"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&minus");
|
||||
tagHandlers["&sdot"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&sdot");
|
||||
tagHandlers["&sim"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&sim");
|
||||
tagHandlers["&le"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&le");
|
||||
tagHandlers["&ge"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&ge");
|
||||
tagHandlers["&larr"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&larr");
|
||||
tagHandlers["&rarr"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&rarr");
|
||||
}
|
||||
|
||||
JavaDocConverter::JavaDocConverter(int flags) :
|
||||
DoxygenTranslator(flags) {
|
||||
fillStaticTables();
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats comment lines by inserting '\n *' at to long lines and tabs for
|
||||
* indent. Currently it is disabled, which means original comment format is
|
||||
* preserved. Experience shows, that this is usually better than breaking
|
||||
* lines automatically, especially because original line endings are not removed,
|
||||
* which results in short lines. To be useful, this function should have much
|
||||
* better algorithm.
|
||||
*/
|
||||
std::string JavaDocConverter::formatCommand(std::string unformattedLine, int indent) {
|
||||
std::string formattedLines;
|
||||
return unformattedLine; // currently disabled
|
||||
int lastPosition = 0;
|
||||
int i = 0;
|
||||
int isFirstLine = 1;
|
||||
while (i != -1 && i < (int) unformattedLine.length()) {
|
||||
lastPosition = i;
|
||||
if (isFirstLine) {
|
||||
i += APPROX_LINE_LENGTH;
|
||||
} else {
|
||||
i += APPROX_LINE_LENGTH - indent * TAB_SIZE;
|
||||
}
|
||||
|
||||
i = unformattedLine.find(" ", i);
|
||||
|
||||
if (i > 0 && i + 1 < (int) unformattedLine.length()) {
|
||||
if (!isFirstLine)
|
||||
for (int j = 0; j < indent; j++) {
|
||||
formattedLines.append("\t");
|
||||
} else {
|
||||
isFirstLine = 0;
|
||||
}
|
||||
formattedLines.append(unformattedLine.substr(lastPosition, i - lastPosition + 1));
|
||||
formattedLines.append("\n *");
|
||||
|
||||
}
|
||||
}
|
||||
if (lastPosition < (int) unformattedLine.length()) {
|
||||
if (!isFirstLine) {
|
||||
for (int j = 0; j < indent; j++) {
|
||||
formattedLines.append("\t");
|
||||
}
|
||||
}
|
||||
formattedLines.append(unformattedLine.substr(lastPosition, unformattedLine.length() - lastPosition));
|
||||
}
|
||||
|
||||
return formattedLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true, if the given parameter exists in the current node
|
||||
* (for example param is a name of function parameter). If feature
|
||||
* 'doxygen:nostripparams' is set, then this method always returns
|
||||
* true - parameters are copied to output regardless of presence in
|
||||
* function params list.
|
||||
*/
|
||||
bool JavaDocConverter::paramExists(std::string param) {
|
||||
|
||||
if (GetFlag(currentNode, "feature:doxygen:nostripparams")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ParmList *plist = CopyParmList(Getattr(currentNode, "parms"));
|
||||
|
||||
for (Parm *p = plist; p;) {
|
||||
|
||||
if (Getattr(p, "name") && Char(Getattr(p, "name")) == param) {
|
||||
return true;
|
||||
}
|
||||
/* doesn't seem to work always: in some cases (especially for 'self' parameters)
|
||||
* tmap:in is present, but tmap:in:next is not and so this code skips all the parameters
|
||||
*/
|
||||
//p = Getattr(p, "tmap:in") ? Getattr(p, "tmap:in:next") : nextSibling(p);
|
||||
p = nextSibling(p);
|
||||
}
|
||||
|
||||
Delete(plist);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string JavaDocConverter::translateSubtree(DoxygenEntity &doxygenEntity) {
|
||||
std::string translatedComment;
|
||||
|
||||
if (doxygenEntity.isLeaf) {
|
||||
return translatedComment;
|
||||
}
|
||||
|
||||
for (DoxygenEntityListIt p = doxygenEntity.entityList.begin(); p != doxygenEntity.entityList.end(); p++) {
|
||||
|
||||
translateEntity(*p, translatedComment);
|
||||
translateSubtree(*p);
|
||||
}
|
||||
|
||||
return translatedComment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a handler for the given tag exists, and calls it.
|
||||
*/
|
||||
void JavaDocConverter::translateEntity(DoxygenEntity &tag, std::string &translatedComment) {
|
||||
|
||||
std::map<std::string, std::pair<tagHandler, std::string> >::iterator it;
|
||||
it = tagHandlers.find(tag.typeOfEntity);
|
||||
|
||||
if (it != tagHandlers.end()) {
|
||||
(this->*(it->second.first))(tag, translatedComment, it->second.second);
|
||||
} else {
|
||||
// do NOT print warning, since there are many tags, which are not
|
||||
// translatable - many warnings hide important ones
|
||||
// addError(WARN_DOXYGEN_COMMAND_ERROR, "Unknown doxygen or HTML tag: " + tag.typeOfEntity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void JavaDocConverter::handleTagAnchor(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
|
||||
translatedComment += "<a id=\"" + translateSubtree(tag) + "\"></a>";
|
||||
}
|
||||
|
||||
|
||||
void JavaDocConverter::handleTagHtml(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
|
||||
if (tag.entityList.size()) { // do not include empty tags
|
||||
std::string tagData = translateSubtree(tag);
|
||||
// wrap the thing, ignoring whitespace
|
||||
size_t wsPos = tagData.find_last_not_of("\n\t ");
|
||||
if (wsPos != std::string::npos)
|
||||
translatedComment += "<" + arg + ">" + tagData.substr(0, wsPos + 1) + "</" + arg + ">" + tagData.substr(wsPos + 1);
|
||||
else
|
||||
translatedComment += "<" + arg + ">" + translateSubtree(tag) + "</" + arg + "> ";
|
||||
}
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleDoxyHtmlTag(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
if (htmlTagArgs == "/") {
|
||||
// end html tag, for example "</ul>
|
||||
translatedComment += "</" + arg.substr(1) + ">";
|
||||
} else {
|
||||
translatedComment += arg + htmlTagArgs + ">";
|
||||
}
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleHtmlEntity(DoxygenEntity &, std::string &translatedComment, std::string &arg) {
|
||||
// html entities can be preserved for Java
|
||||
translatedComment += arg + ';';
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleNewLine(DoxygenEntity &, std::string &translatedComment, std::string &) {
|
||||
// <br> tag is added, because otherwise to much text is joined
|
||||
// into same paragraph by javadoc. For example, doxy list:
|
||||
// - item one
|
||||
// - item two
|
||||
// becomes one paragraph with surrounding text without newlines.
|
||||
// This way we get to many empty lines in javadoc output, but this
|
||||
// is still better than joined lines. Possibility for improvements
|
||||
// exists.
|
||||
translatedComment += "<br>\n * ";
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleTagChar(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
|
||||
// escape it if we need to, else just print
|
||||
if (arg.size())
|
||||
translatedComment += arg;
|
||||
else
|
||||
translatedComment += tag.typeOfEntity;
|
||||
}
|
||||
|
||||
// handles tags which are the same in Doxygen and Javadoc.
|
||||
void JavaDocConverter::handleTagSame(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
|
||||
if (arg.size())
|
||||
tag.typeOfEntity = arg;
|
||||
translatedComment += formatCommand(std::string("@" + tag.typeOfEntity + " " + translateSubtree(tag)), 2);
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleParagraph(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
|
||||
translatedComment += formatCommand(translateSubtree(tag), 0);
|
||||
}
|
||||
|
||||
void JavaDocConverter::handlePlainString(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
|
||||
translatedComment += tag.data;
|
||||
// if (tag.data.size() && tag.data[tag.data.size()-1] != ' ')
|
||||
// translatedComment += " ";
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleTagVerbatim(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
|
||||
translatedComment += arg + " ";
|
||||
for (DoxygenEntityListCIt it = tag.entityList.begin(); it != tag.entityList.end(); it++) {
|
||||
translatedComment += it->data;
|
||||
}
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleTagExtended(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
|
||||
std::string dummy;
|
||||
translatedComment += "{@" + arg + " ";
|
||||
handleParagraph(tag, translatedComment, dummy);
|
||||
translatedComment += "}";
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleTagIf(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
|
||||
std::string dummy;
|
||||
translatedComment += arg;
|
||||
if (tag.entityList.size()) {
|
||||
translatedComment += tag.entityList.begin()->data;
|
||||
tag.entityList.pop_front();
|
||||
translatedComment += " {" + translateSubtree(tag) + "}";
|
||||
}
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleTagMessage(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
|
||||
std::string dummy;
|
||||
translatedComment += formatCommand(arg, 0);
|
||||
handleParagraph(tag, translatedComment, dummy);
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleTagImage(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
|
||||
if (tag.entityList.size() < 2)
|
||||
return;
|
||||
|
||||
std::string file;
|
||||
std::string title;
|
||||
|
||||
std::list<DoxygenEntity>::iterator it = tag.entityList.begin();
|
||||
if (it->data != "html")
|
||||
return;
|
||||
|
||||
it++;
|
||||
file = it->data;
|
||||
|
||||
it++;
|
||||
if (it != tag.entityList.end())
|
||||
title = it->data;
|
||||
|
||||
translatedComment += "<img src=" + file;
|
||||
if (title.size())
|
||||
translatedComment += " alt=" + title;
|
||||
|
||||
// the size indication is supported for Latex only in Doxygen, see manual
|
||||
|
||||
translatedComment += "/>";
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleTagPar(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
|
||||
std::string dummy;
|
||||
translatedComment += "<p";
|
||||
if (tag.entityList.size()) {
|
||||
translatedComment += " alt=\"" + tag.entityList.begin()->data + "\"";
|
||||
translatedComment += ">";
|
||||
tag.entityList.pop_front();
|
||||
handleParagraph(tag, translatedComment, dummy);
|
||||
}
|
||||
translatedComment += "</p>";
|
||||
}
|
||||
|
||||
|
||||
void JavaDocConverter::handleTagParam(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
|
||||
std::string dummy;
|
||||
|
||||
if (!tag.entityList.size())
|
||||
return;
|
||||
if (!paramExists(tag.entityList.begin()->data))
|
||||
return;
|
||||
|
||||
translatedComment += "@param ";
|
||||
translatedComment += tag.entityList.begin()->data;
|
||||
tag.entityList.pop_front();
|
||||
handleParagraph(tag, translatedComment, dummy);
|
||||
}
|
||||
|
||||
|
||||
void JavaDocConverter::handleTagRef(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
|
||||
std::string dummy;
|
||||
if (!tag.entityList.size())
|
||||
return;
|
||||
|
||||
// we translate to link, although \page is not supported in Java, but
|
||||
// reader at least knows what to look at. Also for \anchor tag on the same
|
||||
// page this link works.
|
||||
string anchor = tag.entityList.begin()->data;
|
||||
tag.entityList.pop_front();
|
||||
string anchorText = anchor;
|
||||
if (!tag.entityList.empty()) {
|
||||
anchorText = tag.entityList.begin()->data;
|
||||
}
|
||||
translatedComment += "<a href=\"#" + anchor + "\">" + anchorText + "</a>";
|
||||
}
|
||||
|
||||
|
||||
string JavaDocConverter::convertLink(string linkObject) {
|
||||
if (GetFlag(currentNode, "feature:doxygen:nolinktranslate"))
|
||||
return linkObject;
|
||||
// find the params in function in linkObject (if any)
|
||||
size_t lbracePos = linkObject.find('(', 0);
|
||||
size_t rbracePos = linkObject.find(')', 0);
|
||||
if (lbracePos == string::npos || rbracePos == string::npos || lbracePos >= rbracePos)
|
||||
return "";
|
||||
|
||||
string paramsStr = linkObject.substr(lbracePos + 1,
|
||||
rbracePos - lbracePos - 1);
|
||||
// strip the params, to fill them later
|
||||
string additionalObject = linkObject.substr(rbracePos + 1, string::npos);
|
||||
linkObject = linkObject.substr(0, lbracePos);
|
||||
|
||||
// find all the params
|
||||
vector<string> params;
|
||||
size_t lastPos = 0, commaPos = 0;
|
||||
while (true) {
|
||||
commaPos = paramsStr.find(',', lastPos);
|
||||
if (commaPos == string::npos)
|
||||
commaPos = paramsStr.size();
|
||||
string param = paramsStr.substr(lastPos, commaPos - lastPos);
|
||||
// if any param type is empty, we are failed
|
||||
if (!param.size())
|
||||
return "";
|
||||
params.push_back(param);
|
||||
lastPos = commaPos + 1;
|
||||
if (lastPos >= paramsStr.size())
|
||||
break;
|
||||
}
|
||||
|
||||
linkObject += "(";
|
||||
for (size_t i = 0; i < params.size(); i++) {
|
||||
// translate c/c++ type string to swig's type
|
||||
// i e 'int **arr[100][10]' -> 'a(100).a(10).p.p.int'
|
||||
// also converting arrays to pointers
|
||||
string paramStr = params[i];
|
||||
String *swigType = NewString("");
|
||||
|
||||
// handle const qualifier
|
||||
if (paramStr.find("const") != string::npos)
|
||||
SwigType_add_qualifier(swigType, "const");
|
||||
|
||||
// handle pointers, references and arrays
|
||||
for (int j = (int)params[i].size() - 1; j >= 0; j--) {
|
||||
// skip all the [...] blocks, write 'p.' for every of it
|
||||
if (paramStr[j] == ']') {
|
||||
while (j >= 0 && paramStr[j] != '[')
|
||||
j--;
|
||||
// no closing brace
|
||||
if (j < 0)
|
||||
return "";
|
||||
SwigType_add_pointer(swigType);
|
||||
continue;
|
||||
} else if (paramStr[j] == '*')
|
||||
SwigType_add_pointer(swigType);
|
||||
else if (paramStr[j] == '&')
|
||||
SwigType_add_reference(swigType);
|
||||
else if (isalnum(paramStr[j])) {
|
||||
size_t typeNameStart = paramStr.find_last_of(' ', j + 1);
|
||||
if (typeNameStart == string::npos)
|
||||
typeNameStart = 0;
|
||||
else
|
||||
typeNameStart++;
|
||||
Append(swigType, paramStr.substr(typeNameStart, j - typeNameStart + 1).c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// make dummy param list, to lookup typemaps for it
|
||||
Parm *dummyParam = NewParm(swigType, "", 0);
|
||||
Swig_typemap_attach_parms("jstype", dummyParam, NULL);
|
||||
Language::instance()->replaceSpecialVariables(0, Getattr(dummyParam, "tmap:jstype"), dummyParam);
|
||||
|
||||
//Swig_print(dummyParam, 1);
|
||||
linkObject += Char(Getattr(dummyParam, "tmap:jstype"));
|
||||
if (i != params.size() - 1)
|
||||
linkObject += ",";
|
||||
|
||||
Delete(dummyParam);
|
||||
Delete(swigType);
|
||||
}
|
||||
linkObject += ")";
|
||||
|
||||
return linkObject + additionalObject;
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleTagLink(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
|
||||
std::string dummy;
|
||||
if (!tag.entityList.size())
|
||||
return;
|
||||
|
||||
string linkObject = convertLink(tag.entityList.begin()->data);
|
||||
if (!linkObject.size())
|
||||
linkObject = tag.entityList.begin()->data;
|
||||
tag.entityList.pop_front();
|
||||
|
||||
translatedComment += "{@link ";
|
||||
translatedComment += linkObject + " ";
|
||||
handleParagraph(tag, translatedComment, dummy);
|
||||
translatedComment += "}";
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleTagSee(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
|
||||
std::string dummy;
|
||||
if (!tag.entityList.size())
|
||||
return;
|
||||
|
||||
// tag.entity list contains contents of the @see paragraph. It should contain
|
||||
// one link (references) to method with or without parameters. Doxygen supports
|
||||
// arbitrary text and types mixed, but this feature is not supported here.
|
||||
// :: or # may be used as a separator between class name and method name.
|
||||
list<DoxygenEntity>::iterator it;
|
||||
string methodRef;
|
||||
for (it = tag.entityList.begin(); it != tag.entityList.end(); it++) {
|
||||
if (it->typeOfEntity == "plainstd::endl") {
|
||||
// handleNewLine(*it, translatedComment, dummy);
|
||||
continue;
|
||||
}
|
||||
// restore entities which may be used in C++ type declaration
|
||||
if (it->typeOfEntity == "&") {
|
||||
methodRef += '&';
|
||||
} else if (it->typeOfEntity == "<") {
|
||||
methodRef += '<';
|
||||
} else if (it->typeOfEntity == ">") {
|
||||
methodRef += '>';
|
||||
} else {
|
||||
methodRef += it->data;
|
||||
}
|
||||
}
|
||||
|
||||
// replace :: with #, but only if it appears before left brace
|
||||
size_t lbrace = methodRef.find('(');
|
||||
size_t dblColon = methodRef.find("::");
|
||||
if (dblColon < lbrace) {
|
||||
methodRef = methodRef.substr(0, dblColon) + '#' + methodRef.substr(dblColon + 2);
|
||||
}
|
||||
|
||||
translatedComment += "@see ";
|
||||
string linkObject = convertLink(methodRef);
|
||||
if (!linkObject.size()) {
|
||||
linkObject = methodRef;
|
||||
}
|
||||
translatedComment += linkObject;
|
||||
}
|
||||
|
||||
/* This function moves all line endings at the end of child entities
|
||||
* out of the child entities to the parent.
|
||||
* For example, entity tree:
|
||||
|
||||
-root
|
||||
|-param
|
||||
|-paramText
|
||||
|-endline
|
||||
|
||||
should be turned to
|
||||
|
||||
-root
|
||||
|-param
|
||||
|-paramText
|
||||
|-endline
|
||||
*
|
||||
*/
|
||||
int JavaDocConverter::shiftEndlinesUpTree(DoxygenEntity &root, int level) {
|
||||
DoxygenEntityListIt it = root.entityList.begin();
|
||||
while (it != root.entityList.end()) {
|
||||
// remove line endings
|
||||
int ret = shiftEndlinesUpTree(*it, level + 1);
|
||||
// insert them after this element
|
||||
it++;
|
||||
for (int i = 0; i < ret; i++) {
|
||||
root.entityList.insert(it, DoxygenEntity("plainstd::endl"));
|
||||
}
|
||||
}
|
||||
|
||||
// continue only if we are not root
|
||||
if (!level) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int removedCount = 0;
|
||||
while (!root.entityList.empty()
|
||||
&& root.entityList.rbegin()->typeOfEntity == "plainstd::endl") {
|
||||
root.entityList.pop_back();
|
||||
removedCount++;
|
||||
}
|
||||
return removedCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* This makes sure that all comment lines contain '*'. It is not mandatory in doxygen,
|
||||
* but highly recommended for Javadoc. '*' in empty lines are indented according
|
||||
* to indentation of the first line. Indentation of non-empty lines is not
|
||||
* changed - garbage in garbage out.
|
||||
*/
|
||||
std::string JavaDocConverter::indentAndInsertAsterisks(const string &doc) {
|
||||
|
||||
size_t idx = doc.find('\n');
|
||||
size_t indent = 0;
|
||||
// Detect indentation.
|
||||
// The first line in comment is the one after '/**', which may be
|
||||
// spaces and '\n' or the text. In any case it is not suitable to detect
|
||||
// indentation, so we have to skip the first '\n'.
|
||||
if (idx != string::npos) {
|
||||
size_t nonspaceIdx = doc.find_first_not_of(" \t", idx + 1);
|
||||
if (nonspaceIdx != string::npos) {
|
||||
indent = nonspaceIdx - idx;
|
||||
}
|
||||
}
|
||||
|
||||
if (indent == 0) {
|
||||
// we can't indent the first line less than 0
|
||||
indent = 1;
|
||||
}
|
||||
// Create the first line of Javadoc comment.
|
||||
string indentStr(indent - 1, ' ');
|
||||
string translatedStr = indentStr + "/**";
|
||||
if (indent > 1) {
|
||||
// remove the first space, so that '*' will be aligned
|
||||
translatedStr = translatedStr.substr(1);
|
||||
}
|
||||
|
||||
translatedStr += doc;
|
||||
|
||||
// insert '*' before each comment line, if it does not have it
|
||||
idx = translatedStr.find('\n');
|
||||
|
||||
while (idx != string::npos) {
|
||||
|
||||
size_t nonspaceIdx = translatedStr.find_first_not_of(" \t", idx + 1);
|
||||
if (nonspaceIdx != string::npos && translatedStr[nonspaceIdx] != '*') {
|
||||
// line without '*' found - is it empty?
|
||||
if (translatedStr[nonspaceIdx] != '\n') {
|
||||
// add '* ' to each line without it
|
||||
translatedStr = translatedStr.substr(0, nonspaceIdx) + "* " + translatedStr.substr(nonspaceIdx);
|
||||
//printf(translatedStr.c_str());
|
||||
} else {
|
||||
// we found empty line, replace it with indented '*'
|
||||
translatedStr = translatedStr.substr(0, idx + 1) + indentStr + "* " + translatedStr.substr(nonspaceIdx);
|
||||
}
|
||||
}
|
||||
idx = translatedStr.find('\n', nonspaceIdx);
|
||||
}
|
||||
|
||||
// Add the last comment line properly indented
|
||||
size_t nonspaceEndIdx = translatedStr.find_last_not_of(" \t");
|
||||
if (nonspaceEndIdx != string::npos) {
|
||||
if (translatedStr[nonspaceEndIdx] != '\n') {
|
||||
translatedStr += '\n';
|
||||
} else {
|
||||
// remove trailing spaces
|
||||
translatedStr = translatedStr.substr(0, nonspaceEndIdx + 1);
|
||||
}
|
||||
}
|
||||
translatedStr += indentStr + "*/\n";
|
||||
|
||||
return translatedStr;
|
||||
}
|
||||
|
||||
String *JavaDocConverter::makeDocumentation(Node *node) {
|
||||
|
||||
String *documentation = getDoxygenComment(node);
|
||||
|
||||
if (documentation == NULL) {
|
||||
return NewString("");
|
||||
}
|
||||
|
||||
if (GetFlag(node, "feature:doxygen:notranslate")) {
|
||||
|
||||
string doc = Char(documentation);
|
||||
|
||||
string translatedStr = indentAndInsertAsterisks(doc);
|
||||
|
||||
String *comment = NewString(translatedStr.c_str());
|
||||
// Append(comment, documentation); Replaceall(comment, "\n", "\n * ");
|
||||
return comment;
|
||||
}
|
||||
|
||||
DoxygenEntityList entityList = parser.createTree(node, documentation);
|
||||
|
||||
// entityList.sort(CompareDoxygenEntities()); sorting currently not used,
|
||||
|
||||
if (m_flags & debug_translator) {
|
||||
std::cout << "---RESORTED LIST---" << std::endl;
|
||||
printTree(entityList);
|
||||
}
|
||||
// store the current node
|
||||
// (currently just to handle params)
|
||||
currentNode = node;
|
||||
|
||||
std::string javaDocString = "/**\n * ";
|
||||
|
||||
DoxygenEntity root("root", entityList);
|
||||
|
||||
shiftEndlinesUpTree(root);
|
||||
|
||||
// strip line endings at the beginning
|
||||
while (!root.entityList.empty()
|
||||
&& root.entityList.begin()->typeOfEntity == "plainstd::endl") {
|
||||
root.entityList.pop_front();
|
||||
}
|
||||
|
||||
// and at the end
|
||||
while (!root.entityList.empty()
|
||||
&& root.entityList.rbegin()->typeOfEntity == "plainstd::endl") {
|
||||
root.entityList.pop_back();
|
||||
}
|
||||
|
||||
javaDocString += translateSubtree(root);
|
||||
|
||||
javaDocString += "\n */\n";
|
||||
|
||||
if (m_flags & debug_translator) {
|
||||
std::cout << "\n---RESULT IN JAVADOC---" << std::endl;
|
||||
std::cout << javaDocString;
|
||||
}
|
||||
|
||||
return NewString(javaDocString.c_str());
|
||||
}
|
||||
|
||||
void JavaDocConverter::addError(int warningType, const std::string &message) {
|
||||
Swig_warning(warningType, "", 0, "Doxygen parser warning: %s. \n", message.c_str());
|
||||
}
|
||||
169
Source/Doxygen/javadoc.h
Normal file
169
Source/Doxygen/javadoc.h
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* This file is part of SWIG, which is licensed as a whole under version 3
|
||||
* (or any later version) of the GNU General Public License. Some additional
|
||||
* terms also apply to certain portions of SWIG. The full details of the SWIG
|
||||
* license and copyrights can be found in the LICENSE and COPYRIGHT files
|
||||
* included with the SWIG source code as distributed by the SWIG developers
|
||||
* and at http://www.swig.org/legal.html.
|
||||
*
|
||||
* javadoc.h
|
||||
*
|
||||
* Module to return documentation for nodes formatted for JavaDoc
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef JAVADOCCONVERTER_H_
|
||||
#define JAVADOCCONVERTER_H_
|
||||
|
||||
#include "doxytranslator.h"
|
||||
#include <map>
|
||||
|
||||
/*
|
||||
* A class to translate doxygen comments into JavaDoc style comments.
|
||||
*/
|
||||
class JavaDocConverter : public DoxygenTranslator {
|
||||
public:
|
||||
JavaDocConverter(int flags = 0);
|
||||
String *makeDocumentation(Node *node);
|
||||
|
||||
protected:
|
||||
/*
|
||||
* Used to properly format JavaDoc-style command
|
||||
*/
|
||||
std::string formatCommand(std::string unformattedLine, int indent);
|
||||
|
||||
/*
|
||||
* Translate every entity in a tree.
|
||||
*/
|
||||
std::string translateSubtree(DoxygenEntity &doxygenEntity);
|
||||
|
||||
/*
|
||||
* Translate one entity with the appropriate handler, according
|
||||
* to the tagHandlers
|
||||
*/
|
||||
void translateEntity(DoxygenEntity &tag, std::string &translatedComment);
|
||||
|
||||
/*
|
||||
* Fix all endlines location, etc
|
||||
*/
|
||||
int shiftEndlinesUpTree(DoxygenEntity &root, int level = 0);
|
||||
|
||||
/*
|
||||
* Convert params in link-objects and references
|
||||
*/
|
||||
std::string convertLink(std::string linkObject);
|
||||
|
||||
/*
|
||||
* Typedef for the function that handles one tag
|
||||
* arg - some string argument to easily pass it through lookup table
|
||||
*/
|
||||
typedef void (JavaDocConverter::*tagHandler) (DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/**
|
||||
* Copies verbatim args of the tag to output, used for commands like \f$, ...
|
||||
*/
|
||||
void handleTagVerbatim(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/** Creates anchor link. */
|
||||
void handleTagAnchor(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Wrap the command data with the html tag
|
||||
* arg - html tag, with no braces
|
||||
*/
|
||||
void handleTagHtml(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/* Handles HTML tags recognized by Doxygen, like <A ...>, <ul>, <table>, ... */
|
||||
void handleDoxyHtmlTag(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/* Handles HTML entities recognized by Doxygen, like <, ©, ... */
|
||||
void handleHtmlEntity(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Just prints new line
|
||||
*/
|
||||
void handleNewLine(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Print the name of tag to the output, used for escape-commands
|
||||
* arg - html-escaped variant, if not provided the command data is used
|
||||
*/
|
||||
void handleTagChar(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Do not translate and print as-is
|
||||
* arg - the new tag name, if it needs to be renamed
|
||||
*/
|
||||
void handleTagSame(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Print only the content and strip original tag
|
||||
*/
|
||||
void handleParagraph(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Print only data part of code
|
||||
*/
|
||||
void handlePlainString(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Print extended Javadoc command, like {@code ...} or {@literal ...}
|
||||
* arg - command name
|
||||
*/
|
||||
void handleTagExtended(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Print the if-elseif-else-endif section
|
||||
*/
|
||||
void handleTagIf(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Prints the specified message, than the contents of the tag
|
||||
* arg - message
|
||||
*/
|
||||
void handleTagMessage(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Insert <img src=... /> tag if the 'format' field is specified as 'html'
|
||||
*/
|
||||
void handleTagImage(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Insert <p alt='title'>...</p>
|
||||
*/
|
||||
void handleTagPar(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Insert \@param command, if it is really a function param
|
||||
*/
|
||||
void handleTagParam(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Writes link for \ref tag.
|
||||
*/
|
||||
void handleTagRef(DoxygenEntity &tag, std::string &translatedComment, std::string &);
|
||||
|
||||
/*
|
||||
* Insert {@link...} command, and handle all the <link-object>s correctly
|
||||
* (like converting types of params, etc)
|
||||
*/
|
||||
void handleTagLink(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Insert @see command, and handle all the <link-object>s correctly
|
||||
* (like converting types of params, etc)
|
||||
*/
|
||||
void handleTagSee(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
private:
|
||||
Node *currentNode;
|
||||
// this contains the handler pointer and one string argument
|
||||
static std::map<std::string, std::pair<tagHandler, std::string> > tagHandlers;
|
||||
void fillStaticTables();
|
||||
|
||||
bool paramExists(std::string param);
|
||||
std::string indentAndInsertAsterisks(const std::string &doc);
|
||||
|
||||
void addError(int warningType, const std::string &message);
|
||||
};
|
||||
|
||||
#endif
|
||||
843
Source/Doxygen/pydoc.cxx
Normal file
843
Source/Doxygen/pydoc.cxx
Normal file
|
|
@ -0,0 +1,843 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* This file is part of SWIG, which is licensed as a whole under version 3
|
||||
* (or any later version) of the GNU General Public License. Some additional
|
||||
* terms also apply to certain portions of SWIG. The full details of the SWIG
|
||||
* license and copyrights can be found in the LICENSE and COPYRIGHT files
|
||||
* included with the SWIG source code as distributed by the SWIG developers
|
||||
* and at http://www.swig.org/legal.html.
|
||||
*
|
||||
* pydoc.cxx
|
||||
*
|
||||
* Module to return documentation for nodes formatted for PyDoc
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#include "pydoc.h"
|
||||
#include "doxyparser.h"
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#include "swigmod.h"
|
||||
|
||||
// define static tables, they are filled in PyDocConverter's constructor
|
||||
PyDocConverter::TagHandlersMap PyDocConverter::tagHandlers;
|
||||
std::map<std::string, std::string> PyDocConverter::sectionTitles;
|
||||
|
||||
using std::string;
|
||||
|
||||
// Helper class increasing the provided indent string in its ctor and decreasing
|
||||
// it in its dtor.
|
||||
class IndentGuard {
|
||||
public:
|
||||
// One indent level.
|
||||
static const char *Level() {
|
||||
return " ";
|
||||
}
|
||||
// Default ctor doesn't do anything and prevents the dtor from doing anything// too and should only be used when the guard needs to be initialized// conditionally as Init() can then be called after checking some condition.// Otherwise, prefer to use the non default ctor below.
|
||||
IndentGuard() {
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
// Ctor takes the output to determine the current indent and to remove the
|
||||
// extra indent added to it in the dtor and the variable containing the indent
|
||||
// to use, which must be used after every new line by the code actually
|
||||
// updating the output.
|
||||
IndentGuard(string &output, string &indent) {
|
||||
Init(output, indent);
|
||||
}
|
||||
|
||||
// Really initializes the object created using the default ctor.
|
||||
void Init(string &output, string &indent) {
|
||||
m_output = &output;
|
||||
m_indent = &indent;
|
||||
|
||||
const size_t lastNonSpace = m_output->find_last_not_of(' ');
|
||||
if (lastNonSpace == string::npos) {
|
||||
m_firstLineIndent = m_output->length();
|
||||
} else if ((*m_output)[lastNonSpace] == '\n') {
|
||||
m_firstLineIndent = m_output->length() - (lastNonSpace + 1);
|
||||
} else {
|
||||
m_firstLineIndent = 0;
|
||||
}
|
||||
|
||||
// Notice that the indent doesn't include the first line indent because it's
|
||||
// implicit, i.e. it is present in the input and so is copied into the
|
||||
// output anyhow.
|
||||
*m_indent = Level();
|
||||
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
// Get the indent for the first line of the paragraph, which is smaller than
|
||||
// the indent for the subsequent lines.
|
||||
string getFirstLineIndent() const {
|
||||
return string(m_firstLineIndent, ' ');
|
||||
}
|
||||
|
||||
~IndentGuard() {
|
||||
if (!m_initialized)
|
||||
return;
|
||||
|
||||
m_indent->clear();
|
||||
|
||||
// Get rid of possible remaining extra indent, e.g. if there were any trailing
|
||||
// new lines: we shouldn't add the extra indent level to whatever follows
|
||||
// this paragraph.
|
||||
static const size_t lenIndentLevel = strlen(Level());
|
||||
if (m_output->length() > lenIndentLevel) {
|
||||
const size_t start = m_output->length() - lenIndentLevel;
|
||||
if (m_output->compare(start, string::npos, Level()) == 0)
|
||||
m_output->erase(start);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
string *m_output;
|
||||
string *m_indent;
|
||||
unsigned m_firstLineIndent;
|
||||
bool m_initialized;
|
||||
|
||||
IndentGuard(const IndentGuard &);
|
||||
IndentGuard &operator=(const IndentGuard &);
|
||||
};
|
||||
|
||||
// Return the indent of the given multiline string, i.e. the maximal number of
|
||||
// spaces present in the beginning of all its non-empty lines.
|
||||
static size_t determineIndent(const string &s) {
|
||||
size_t minIndent = static_cast<size_t>(-1);
|
||||
|
||||
for (size_t lineStart = 0; lineStart < s.length();) {
|
||||
const size_t lineEnd = s.find('\n', lineStart);
|
||||
const size_t firstNonSpace = s.find_first_not_of(' ', lineStart);
|
||||
|
||||
// If inequality doesn't hold, it means that this line contains only spaces
|
||||
// (notice that this works whether lineEnd is valid or string::npos), in
|
||||
// which case it doesn't matter when determining the indent.
|
||||
if (firstNonSpace < lineEnd) {
|
||||
// Here we can be sure firstNonSpace != string::npos.
|
||||
const size_t lineIndent = firstNonSpace - lineStart;
|
||||
if (lineIndent < minIndent)
|
||||
minIndent = lineIndent;
|
||||
}
|
||||
|
||||
if (lineEnd == string::npos)
|
||||
break;
|
||||
|
||||
lineStart = lineEnd + 1;
|
||||
}
|
||||
|
||||
return minIndent;
|
||||
}
|
||||
|
||||
static void trimWhitespace(string &s) {
|
||||
const size_t lastNonSpace = s.find_last_not_of(' ');
|
||||
if (lastNonSpace == string::npos)
|
||||
s.clear();
|
||||
else
|
||||
s.erase(lastNonSpace + 1);
|
||||
}
|
||||
|
||||
/* static */
|
||||
PyDocConverter::TagHandlersMap::mapped_type PyDocConverter::make_handler(tagHandler handler) {
|
||||
return make_pair(handler, std::string());
|
||||
}
|
||||
|
||||
/* static */
|
||||
PyDocConverter::TagHandlersMap::mapped_type PyDocConverter::make_handler(tagHandler handler, const char *arg) {
|
||||
return make_pair(handler, arg);
|
||||
}
|
||||
|
||||
void PyDocConverter::fillStaticTables() {
|
||||
if (tagHandlers.size()) // fill only once
|
||||
return;
|
||||
|
||||
// table of section titles, they are printed only once
|
||||
// for each group of specified doxygen commands
|
||||
sectionTitles["author"] = "Author: ";
|
||||
sectionTitles["authors"] = "Authors: ";
|
||||
sectionTitles["copyright"] = "Copyright: ";
|
||||
sectionTitles["deprecated"] = "Deprecated: ";
|
||||
sectionTitles["example"] = "Example: ";
|
||||
sectionTitles["note"] = "Notes: ";
|
||||
sectionTitles["remark"] = "Remarks: ";
|
||||
sectionTitles["remarks"] = "Remarks: ";
|
||||
sectionTitles["warning"] = "Warning: ";
|
||||
// sectionTitles["sa"] = "See also: ";
|
||||
// sectionTitles["see"] = "See also: ";
|
||||
sectionTitles["since"] = "Since: ";
|
||||
sectionTitles["todo"] = "TODO: ";
|
||||
sectionTitles["version"] = "Version: ";
|
||||
|
||||
tagHandlers["a"] = make_handler(&PyDocConverter::handleTagWrap, "*");
|
||||
tagHandlers["b"] = make_handler(&PyDocConverter::handleTagWrap, "**");
|
||||
// \c command is translated as single quotes around next word
|
||||
tagHandlers["c"] = make_handler(&PyDocConverter::handleTagWrap, "``");
|
||||
tagHandlers["cite"] = make_handler(&PyDocConverter::handleTagWrap, "'");
|
||||
tagHandlers["e"] = make_handler(&PyDocConverter::handleTagWrap, "*");
|
||||
// these commands insert just a single char, some of them need to be escaped
|
||||
tagHandlers["$"] = make_handler(&PyDocConverter::handleTagChar);
|
||||
tagHandlers["@"] = make_handler(&PyDocConverter::handleTagChar);
|
||||
tagHandlers["\\"] = make_handler(&PyDocConverter::handleTagChar);
|
||||
tagHandlers["<"] = make_handler(&PyDocConverter::handleTagChar);
|
||||
tagHandlers[">"] = make_handler(&PyDocConverter::handleTagChar);
|
||||
tagHandlers["&"] = make_handler(&PyDocConverter::handleTagChar);
|
||||
tagHandlers["#"] = make_handler(&PyDocConverter::handleTagChar);
|
||||
tagHandlers["%"] = make_handler(&PyDocConverter::handleTagChar);
|
||||
tagHandlers["~"] = make_handler(&PyDocConverter::handleTagChar);
|
||||
tagHandlers["\""] = make_handler(&PyDocConverter::handleTagChar);
|
||||
tagHandlers["."] = make_handler(&PyDocConverter::handleTagChar);
|
||||
tagHandlers["::"] = make_handler(&PyDocConverter::handleTagChar);
|
||||
// these commands are stripped out, and only their content is printed
|
||||
tagHandlers["attention"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["author"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["authors"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["brief"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["bug"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["code"] = make_handler(&PyDocConverter::handleCode);
|
||||
tagHandlers["copyright"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["date"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["deprecated"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["details"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["em"] = make_handler(&PyDocConverter::handleParagraph, " ");
|
||||
tagHandlers["example"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["exception"] = tagHandlers["throw"] = tagHandlers["throws"] = make_handler(&PyDocConverter::handleTagException);
|
||||
tagHandlers["htmlonly"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["invariant"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["latexonly"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["link"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["manonly"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["note"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["p"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["partofdescription"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["rtfonly"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["remark"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["remarks"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["sa"] = make_handler(&PyDocConverter::handleTagMessage, "See also: ");
|
||||
tagHandlers["see"] = make_handler(&PyDocConverter::handleTagMessage, "See also: ");
|
||||
tagHandlers["since"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["short"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["todo"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["version"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["verbatim"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["warning"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["xmlonly"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
// these commands have special handlers
|
||||
tagHandlers["arg"] = make_handler(&PyDocConverter::handleTagMessage, "* ");
|
||||
tagHandlers["cond"] = make_handler(&PyDocConverter::handleTagMessage, "Conditional comment: ");
|
||||
tagHandlers["else"] = make_handler(&PyDocConverter::handleTagIf, "Else: ");
|
||||
tagHandlers["elseif"] = make_handler(&PyDocConverter::handleTagIf, "Else if: ");
|
||||
tagHandlers["endcond"] = make_handler(&PyDocConverter::handleTagMessage, "End of conditional comment.");
|
||||
tagHandlers["if"] = make_handler(&PyDocConverter::handleTagIf, "If: ");
|
||||
tagHandlers["ifnot"] = make_handler(&PyDocConverter::handleTagIf, "If not: ");
|
||||
tagHandlers["image"] = make_handler(&PyDocConverter::handleTagImage);
|
||||
tagHandlers["li"] = make_handler(&PyDocConverter::handleTagMessage, "* ");
|
||||
tagHandlers["overload"] = make_handler(&PyDocConverter::handleTagMessage,
|
||||
"This is an overloaded member function, provided for"
|
||||
" convenience.\nIt differs from the above function only in what" " argument(s) it accepts.");
|
||||
tagHandlers["par"] = make_handler(&PyDocConverter::handleTagPar);
|
||||
tagHandlers["param"] = tagHandlers["tparam"] = make_handler(&PyDocConverter::handleTagParam);
|
||||
tagHandlers["ref"] = make_handler(&PyDocConverter::handleTagRef);
|
||||
tagHandlers["result"] = tagHandlers["return"] = tagHandlers["returns"] = make_handler(&PyDocConverter::handleTagReturn);
|
||||
|
||||
// this command just prints it's contents
|
||||
// (it is internal command of swig's parser, contains plain text)
|
||||
tagHandlers["plainstd::string"] = make_handler(&PyDocConverter::handlePlainString);
|
||||
tagHandlers["plainstd::endl"] = make_handler(&PyDocConverter::handleNewLine);
|
||||
tagHandlers["n"] = make_handler(&PyDocConverter::handleNewLine);
|
||||
|
||||
// \f commands output literal Latex formula, which is still better than nothing.
|
||||
tagHandlers["f$"] = tagHandlers["f["] = tagHandlers["f{"] = make_handler(&PyDocConverter::handleMath);
|
||||
|
||||
// HTML tags
|
||||
tagHandlers["<a"] = make_handler(&PyDocConverter::handleDoxyHtmlTag_A);
|
||||
tagHandlers["<b"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "**");
|
||||
tagHandlers["<blockquote"] = make_handler(&PyDocConverter::handleDoxyHtmlTag_A, "Quote: ");
|
||||
tagHandlers["<body"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<br"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "\n");
|
||||
|
||||
// there is no formatting for this tag as it was deprecated in HTML 4.01 and
|
||||
// not used in HTML 5
|
||||
tagHandlers["<center"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<caption"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<code"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "``");
|
||||
|
||||
tagHandlers["<dl"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<dd"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, " ");
|
||||
tagHandlers["<dt"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
|
||||
tagHandlers["<dfn"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<div"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<em"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "**");
|
||||
tagHandlers["<form"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<hr"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "--------------------------------------------------------------------\n");
|
||||
tagHandlers["<h1"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "# ");
|
||||
tagHandlers["<h2"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "## ");
|
||||
tagHandlers["<h3"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "### ");
|
||||
tagHandlers["<i"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "*");
|
||||
tagHandlers["<input"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<img"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "Image:");
|
||||
tagHandlers["<li"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "* ");
|
||||
tagHandlers["<meta"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<multicol"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<ol"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<p"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "\n");
|
||||
tagHandlers["<pre"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<small"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<span"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "'");
|
||||
tagHandlers["<strong"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "**");
|
||||
|
||||
// make a space between text and super/sub script.
|
||||
tagHandlers["<sub"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, " ");
|
||||
tagHandlers["<sup"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, " ");
|
||||
|
||||
tagHandlers["<table"] = make_handler(&PyDocConverter::handleDoxyHtmlTagNoParam);
|
||||
tagHandlers["<td"] = make_handler(&PyDocConverter::handleDoxyHtmlTag_td);
|
||||
tagHandlers["<th"] = make_handler(&PyDocConverter::handleDoxyHtmlTag_th);
|
||||
tagHandlers["<tr"] = make_handler(&PyDocConverter::handleDoxyHtmlTag_tr);
|
||||
tagHandlers["<tt"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<kbd"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<ul"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<var"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "*");
|
||||
|
||||
// HTML entities
|
||||
tagHandlers["©"] = make_handler(&PyDocConverter::handleHtmlEntity, "(C)");
|
||||
tagHandlers["&trade"] = make_handler(&PyDocConverter::handleHtmlEntity, " TM");
|
||||
tagHandlers["®"] = make_handler(&PyDocConverter::handleHtmlEntity, "(R)");
|
||||
tagHandlers["<"] = make_handler(&PyDocConverter::handleHtmlEntity, "<");
|
||||
tagHandlers[">"] = make_handler(&PyDocConverter::handleHtmlEntity, ">");
|
||||
tagHandlers["&"] = make_handler(&PyDocConverter::handleHtmlEntity, "&");
|
||||
tagHandlers["&apos"] = make_handler(&PyDocConverter::handleHtmlEntity, "'");
|
||||
tagHandlers["""] = make_handler(&PyDocConverter::handleHtmlEntity, "\"");
|
||||
tagHandlers["&lsquo"] = make_handler(&PyDocConverter::handleHtmlEntity, "`");
|
||||
tagHandlers["&rsquo"] = make_handler(&PyDocConverter::handleHtmlEntity, "'");
|
||||
tagHandlers["&ldquo"] = make_handler(&PyDocConverter::handleHtmlEntity, "\"");
|
||||
tagHandlers["&rdquo"] = make_handler(&PyDocConverter::handleHtmlEntity, "\"");
|
||||
tagHandlers["&ndash"] = make_handler(&PyDocConverter::handleHtmlEntity, "-");
|
||||
tagHandlers["&mdash"] = make_handler(&PyDocConverter::handleHtmlEntity, "--");
|
||||
tagHandlers[" "] = make_handler(&PyDocConverter::handleHtmlEntity, " ");
|
||||
tagHandlers["×"] = make_handler(&PyDocConverter::handleHtmlEntity, "x");
|
||||
tagHandlers["&minus"] = make_handler(&PyDocConverter::handleHtmlEntity, "-");
|
||||
tagHandlers["&sdot"] = make_handler(&PyDocConverter::handleHtmlEntity, ".");
|
||||
tagHandlers["&sim"] = make_handler(&PyDocConverter::handleHtmlEntity, "~");
|
||||
tagHandlers["&le"] = make_handler(&PyDocConverter::handleHtmlEntity, "<=");
|
||||
tagHandlers["&ge"] = make_handler(&PyDocConverter::handleHtmlEntity, ">=");
|
||||
tagHandlers["&larr"] = make_handler(&PyDocConverter::handleHtmlEntity, "<--");
|
||||
tagHandlers["&rarr"] = make_handler(&PyDocConverter::handleHtmlEntity, "-->");
|
||||
}
|
||||
|
||||
PyDocConverter::PyDocConverter(int flags):
|
||||
DoxygenTranslator(flags), m_tableLineLen(0), m_prevRowIsTH(false) {
|
||||
fillStaticTables();
|
||||
}
|
||||
|
||||
// Return the type as it should appear in the output documentation.
|
||||
static std::string getPyDocType(Node *n, const_String_or_char_ptr lname = "") {
|
||||
std::string type;
|
||||
|
||||
String *s = Swig_typemap_lookup("doctype", n, lname, 0);
|
||||
if (!s)
|
||||
s = SwigType_str(Getattr(n, "type"), "");
|
||||
|
||||
if (Language::classLookup(s)) {
|
||||
// In Python C++ namespaces are flattened, so remove all but last component
|
||||
// of the name.
|
||||
String *const last = Swig_scopename_last(s);
|
||||
|
||||
// We are not actually sure whether it's a documented class or not, but
|
||||
// there doesn't seem to be any harm in making it a reference if it isn't,
|
||||
// while there is a lot of benefit in having a hyperlink if it is.
|
||||
type = ":py:class:`";
|
||||
type += Char(last);
|
||||
type += "`";
|
||||
|
||||
Delete(last);
|
||||
} else {
|
||||
type = Char(s);
|
||||
}
|
||||
|
||||
Delete(s);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
std::string PyDocConverter::getParamType(std::string param) {
|
||||
std::string type;
|
||||
|
||||
ParmList *plist = CopyParmList(Getattr(currentNode, "parms"));
|
||||
for (Parm *p = plist; p; p = nextSibling(p)) {
|
||||
String *pname = Getattr(p, "name");
|
||||
if (Char(pname) != param)
|
||||
continue;
|
||||
|
||||
type = getPyDocType(p, pname);
|
||||
break;
|
||||
}
|
||||
Delete(plist);
|
||||
return type;
|
||||
}
|
||||
|
||||
std::string PyDocConverter::translateSubtree(DoxygenEntity &doxygenEntity) {
|
||||
std::string translatedComment;
|
||||
|
||||
if (doxygenEntity.isLeaf)
|
||||
return translatedComment;
|
||||
|
||||
std::string currentSection;
|
||||
std::list<DoxygenEntity>::iterator p = doxygenEntity.entityList.begin();
|
||||
while (p != doxygenEntity.entityList.end()) {
|
||||
std::map<std::string, std::string>::iterator it;
|
||||
it = sectionTitles.find(p->typeOfEntity);
|
||||
if (it != sectionTitles.end()) {
|
||||
if (it->second != currentSection) {
|
||||
currentSection = it->second;
|
||||
translatedComment += currentSection;
|
||||
}
|
||||
}
|
||||
translateEntity(*p, translatedComment);
|
||||
translateSubtree(*p);
|
||||
p++;
|
||||
}
|
||||
|
||||
return translatedComment;
|
||||
}
|
||||
|
||||
void PyDocConverter::translateEntity(DoxygenEntity &doxyEntity, std::string &translatedComment) {
|
||||
// check if we have needed handler and call it
|
||||
std::map<std::string, std::pair<tagHandler, std::string> >::iterator it;
|
||||
it = tagHandlers.find(doxyEntity.typeOfEntity);
|
||||
if (it != tagHandlers.end())
|
||||
(this->*(it->second.first)) (doxyEntity, translatedComment, it->second.second);
|
||||
}
|
||||
|
||||
void PyDocConverter::handleParagraph(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
translatedComment += translateSubtree(tag);
|
||||
}
|
||||
|
||||
void PyDocConverter::handleMath(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
IndentGuard indent;
|
||||
|
||||
// Only \f$ is translated to inline formulae, \f[ and \f{ are for the block ones.
|
||||
const bool inlineFormula = tag.typeOfEntity == "f$";
|
||||
|
||||
string formulaNL;
|
||||
|
||||
if (inlineFormula) {
|
||||
translatedComment += ":math:`";
|
||||
} else {
|
||||
indent.Init(translatedComment, m_indent);
|
||||
|
||||
trimWhitespace(translatedComment);
|
||||
translatedComment += '\n';
|
||||
|
||||
const string formulaIndent = indent.getFirstLineIndent();
|
||||
translatedComment += formulaIndent;
|
||||
translatedComment += ".. math::\n";
|
||||
|
||||
formulaNL = '\n';
|
||||
formulaNL += formulaIndent;
|
||||
formulaNL += m_indent;
|
||||
translatedComment += formulaNL;
|
||||
}
|
||||
|
||||
std::string formula;
|
||||
handleTagVerbatim(tag, formula, arg);
|
||||
|
||||
// It is important to ensure that we have no spaces around the inline math
|
||||
// contents, so strip them.
|
||||
const size_t start = formula.find_first_not_of(" \t\n");
|
||||
const size_t end = formula.find_last_not_of(" \t\n");
|
||||
if (start != std::string::npos) {
|
||||
for (size_t n = start; n <= end; n++) {
|
||||
if (formula[n] == '\n') {
|
||||
// New lines must be suppressed in inline maths and indented in the block ones.
|
||||
if (!inlineFormula)
|
||||
translatedComment += formulaNL;
|
||||
} else {
|
||||
// Just copy everything else.
|
||||
translatedComment += formula[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inlineFormula) {
|
||||
translatedComment += "`";
|
||||
} else {
|
||||
translatedComment += '\n';
|
||||
}
|
||||
}
|
||||
|
||||
void PyDocConverter::handleCode(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
IndentGuard indent(translatedComment, m_indent);
|
||||
|
||||
trimWhitespace(translatedComment);
|
||||
translatedComment += '\n';
|
||||
|
||||
// Use the current indent for the code-block line itself.
|
||||
string codeIndent = indent.getFirstLineIndent();
|
||||
translatedComment += codeIndent;
|
||||
|
||||
// Go out on a limb and assume that examples in the C or C++ sources use C++.
|
||||
// In the worst case, we'll highlight C code using C++ syntax which is not a
|
||||
// big deal (TODO: handle Doxygen code command language argument).
|
||||
translatedComment += ".. code-block:: c++\n\n";
|
||||
|
||||
// For now on, use extra indent level for all the subsequent lines.
|
||||
codeIndent += m_indent;
|
||||
|
||||
std::string code;
|
||||
handleTagVerbatim(tag, code, arg);
|
||||
|
||||
translatedComment += codeIndent;
|
||||
for (size_t n = 0; n < code.length(); n++) {
|
||||
if (code[n] == '\n') {
|
||||
// Don't leave trailing white space, this results in PEP8 validation
|
||||
// errors in Python code (which are performed by our own unit tests).
|
||||
trimWhitespace(translatedComment);
|
||||
translatedComment += '\n';
|
||||
|
||||
// Ensure that we indent all the lines by the code indent.
|
||||
translatedComment += codeIndent;
|
||||
} else {
|
||||
// Just copy everything else.
|
||||
translatedComment += code[n];
|
||||
}
|
||||
}
|
||||
|
||||
trimWhitespace(translatedComment);
|
||||
if (*translatedComment.rbegin() != '\n')
|
||||
translatedComment += '\n';
|
||||
}
|
||||
|
||||
void PyDocConverter::handlePlainString(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
translatedComment += tag.data;
|
||||
}
|
||||
|
||||
void PyDocConverter::handleTagVerbatim(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
translatedComment += arg + " ";
|
||||
for (DoxygenEntityListCIt it = tag.entityList.begin(); it != tag.entityList.end(); it++) {
|
||||
translatedComment += it->data;
|
||||
}
|
||||
}
|
||||
|
||||
void PyDocConverter::handleTagMessage(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
translatedComment += arg;
|
||||
handleParagraph(tag, translatedComment);
|
||||
}
|
||||
|
||||
void PyDocConverter::handleTagChar(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
translatedComment += tag.typeOfEntity;
|
||||
}
|
||||
|
||||
void PyDocConverter::handleTagIf(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
translatedComment += arg;
|
||||
if (tag.entityList.size()) {
|
||||
translatedComment += tag.entityList.begin()->data;
|
||||
tag.entityList.pop_front();
|
||||
translatedComment += " {" + translateSubtree(tag) + "}";
|
||||
}
|
||||
}
|
||||
|
||||
void PyDocConverter::handleTagPar(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
translatedComment += "Title: ";
|
||||
if (tag.entityList.size())
|
||||
translatedComment += tag.entityList.begin()->data;
|
||||
tag.entityList.pop_front();
|
||||
handleParagraph(tag, translatedComment);
|
||||
}
|
||||
|
||||
void PyDocConverter::handleTagImage(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
if (tag.entityList.size() < 2)
|
||||
return;
|
||||
tag.entityList.pop_front();
|
||||
translatedComment += "Image: ";
|
||||
translatedComment += tag.entityList.begin()->data;
|
||||
tag.entityList.pop_front();
|
||||
if (tag.entityList.size())
|
||||
translatedComment += "(" + tag.entityList.begin()->data + ")";
|
||||
}
|
||||
|
||||
void PyDocConverter::handleTagParam(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
if (tag.entityList.size() < 2)
|
||||
return;
|
||||
|
||||
IndentGuard indent(translatedComment, m_indent);
|
||||
|
||||
DoxygenEntity paramNameEntity = *tag.entityList.begin();
|
||||
tag.entityList.pop_front();
|
||||
|
||||
const std::string ¶mName = paramNameEntity.data;
|
||||
|
||||
const std::string paramType = getParamType(paramName);
|
||||
if (!paramType.empty()) {
|
||||
translatedComment += ":type " + paramName + ": " + paramType + "\n";
|
||||
translatedComment += indent.getFirstLineIndent();
|
||||
}
|
||||
|
||||
translatedComment += ":param " + paramName + ":";
|
||||
|
||||
handleParagraph(tag, translatedComment);
|
||||
}
|
||||
|
||||
|
||||
void PyDocConverter::handleTagReturn(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
IndentGuard indent(translatedComment, m_indent);
|
||||
|
||||
const std::string pytype = getPyDocType(currentNode);
|
||||
if (!pytype.empty()) {
|
||||
translatedComment += ":rtype: ";
|
||||
translatedComment += pytype;
|
||||
translatedComment += "\n";
|
||||
translatedComment += indent.getFirstLineIndent();
|
||||
}
|
||||
|
||||
translatedComment += ":return: ";
|
||||
handleParagraph(tag, translatedComment);
|
||||
}
|
||||
|
||||
|
||||
void PyDocConverter::handleTagException(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
IndentGuard indent(translatedComment, m_indent);
|
||||
|
||||
translatedComment += ":raises: ";
|
||||
handleParagraph(tag, translatedComment);
|
||||
}
|
||||
|
||||
|
||||
void PyDocConverter::handleTagRef(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
if (!tag.entityList.size())
|
||||
return;
|
||||
|
||||
string anchor = tag.entityList.begin()->data;
|
||||
tag.entityList.pop_front();
|
||||
string anchorText = anchor;
|
||||
if (!tag.entityList.empty()) {
|
||||
anchorText = tag.entityList.begin()->data;
|
||||
}
|
||||
translatedComment += "'" + anchorText + "'";
|
||||
}
|
||||
|
||||
|
||||
void PyDocConverter::handleTagWrap(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
if (tag.entityList.size()) { // do not include empty tags
|
||||
std::string tagData = translateSubtree(tag);
|
||||
// wrap the thing, ignoring whitespace
|
||||
size_t wsPos = tagData.find_last_not_of("\n\t ");
|
||||
if (wsPos != std::string::npos && wsPos != tagData.size() - 1)
|
||||
translatedComment += arg + tagData.substr(0, wsPos + 1) + arg + tagData.substr(wsPos + 1);
|
||||
else
|
||||
translatedComment += arg + tagData + arg;
|
||||
}
|
||||
}
|
||||
|
||||
void PyDocConverter::handleDoxyHtmlTag(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
if (htmlTagArgs == "/") {
|
||||
// end html tag, for example "</ul>
|
||||
// translatedComment += "</" + arg.substr(1) + ">";
|
||||
} else {
|
||||
translatedComment += arg + htmlTagArgs;
|
||||
}
|
||||
}
|
||||
|
||||
void PyDocConverter::handleDoxyHtmlTagNoParam(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
if (htmlTagArgs == "/") {
|
||||
// end html tag, for example "</ul>
|
||||
} else {
|
||||
translatedComment += arg;
|
||||
}
|
||||
}
|
||||
|
||||
void PyDocConverter::handleDoxyHtmlTag_A(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
if (htmlTagArgs == "/") {
|
||||
// end html tag, "</a>
|
||||
translatedComment += " (" + m_url + ')';
|
||||
m_url.clear();
|
||||
} else {
|
||||
m_url.clear();
|
||||
size_t pos = htmlTagArgs.find('=');
|
||||
if (pos != string::npos) {
|
||||
m_url = htmlTagArgs.substr(pos + 1);
|
||||
}
|
||||
translatedComment += arg;
|
||||
}
|
||||
}
|
||||
|
||||
void PyDocConverter::handleDoxyHtmlTag2(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
if (htmlTagArgs == "/") {
|
||||
// end html tag, for example "</em>
|
||||
translatedComment += arg;
|
||||
} else {
|
||||
translatedComment += arg;
|
||||
}
|
||||
}
|
||||
|
||||
void PyDocConverter::handleDoxyHtmlTag_tr(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
size_t nlPos = translatedComment.rfind('\n');
|
||||
if (htmlTagArgs == "/") {
|
||||
// end tag, </tr> appends vertical table line '|'
|
||||
translatedComment += '|';
|
||||
if (nlPos != string::npos) {
|
||||
size_t startOfTableLinePos = translatedComment.find_first_not_of(" \t", nlPos + 1);
|
||||
if (startOfTableLinePos != string::npos) {
|
||||
m_tableLineLen = translatedComment.size() - startOfTableLinePos;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (m_prevRowIsTH) {
|
||||
// if previous row contained <th> tag, add horizontal separator
|
||||
// but first get leading spaces, because they'll be needed for the next row
|
||||
size_t numLeadingSpaces = translatedComment.size() - nlPos - 1;
|
||||
|
||||
translatedComment += string(m_tableLineLen, '-') + '\n';
|
||||
|
||||
if (nlPos != string::npos) {
|
||||
translatedComment += string(numLeadingSpaces, ' ');
|
||||
}
|
||||
m_prevRowIsTH = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PyDocConverter::handleDoxyHtmlTag_th(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
if (htmlTagArgs == "/") {
|
||||
// end tag, </th> is ignored
|
||||
} else {
|
||||
translatedComment += '|';
|
||||
m_prevRowIsTH = true;
|
||||
}
|
||||
}
|
||||
|
||||
void PyDocConverter::handleDoxyHtmlTag_td(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
if (htmlTagArgs == "/") {
|
||||
// end tag, </td> is ignored
|
||||
} else {
|
||||
translatedComment += '|';
|
||||
}
|
||||
}
|
||||
|
||||
void PyDocConverter::handleHtmlEntity(DoxygenEntity &, std::string &translatedComment, const std::string &arg) {
|
||||
// html entities
|
||||
translatedComment += arg;
|
||||
}
|
||||
|
||||
void PyDocConverter::handleNewLine(DoxygenEntity &, std::string &translatedComment, const std::string &) {
|
||||
trimWhitespace(translatedComment);
|
||||
|
||||
translatedComment += "\n";
|
||||
if (!m_indent.empty())
|
||||
translatedComment += m_indent;
|
||||
}
|
||||
|
||||
String *PyDocConverter::makeDocumentation(Node *n) {
|
||||
String *documentation;
|
||||
std::string pyDocString;
|
||||
|
||||
// store the node, we may need it later
|
||||
currentNode = n;
|
||||
|
||||
// for overloaded functions we must concat documentation for underlying overloads
|
||||
if (Getattr(n, "sym:overloaded")) {
|
||||
// rewind to the first overload
|
||||
while (Getattr(n, "sym:previousSibling"))
|
||||
n = Getattr(n, "sym:previousSibling");
|
||||
|
||||
std::vector<std::string> allDocumentation;
|
||||
|
||||
// minimal indent of any documentation comments, not initialized yet
|
||||
size_t minIndent = static_cast<size_t>(-1);
|
||||
|
||||
// for each real method (not a generated overload) append the documentation
|
||||
string oneDoc;
|
||||
while (n) {
|
||||
documentation = getDoxygenComment(n);
|
||||
if (!Swig_is_generated_overload(n) && documentation) {
|
||||
currentNode = n;
|
||||
if (GetFlag(n, "feature:doxygen:notranslate")) {
|
||||
String *comment = NewString("");
|
||||
Append(comment, documentation);
|
||||
Replaceall(comment, "\n *", "\n");
|
||||
oneDoc = Char(comment);
|
||||
Delete(comment);
|
||||
} else {
|
||||
std::list<DoxygenEntity> entityList = parser.createTree(n, documentation);
|
||||
DoxygenEntity root("root", entityList);
|
||||
|
||||
oneDoc = translateSubtree(root);
|
||||
}
|
||||
|
||||
// find the minimal indent of this documentation comment, we need to
|
||||
// ensure that the entire comment is indented by it to avoid the leading
|
||||
// parts of the other lines being simply discarded later
|
||||
const size_t oneIndent = determineIndent(oneDoc);
|
||||
if (oneIndent < minIndent)
|
||||
minIndent = oneIndent;
|
||||
|
||||
allDocumentation.push_back(oneDoc);
|
||||
}
|
||||
n = Getattr(n, "sym:nextSibling");
|
||||
}
|
||||
|
||||
// construct final documentation string
|
||||
if (allDocumentation.size() > 1) {
|
||||
string indentStr;
|
||||
if (minIndent != static_cast<size_t>(-1))
|
||||
indentStr.assign(minIndent, ' ');
|
||||
|
||||
std::ostringstream concatDocString;
|
||||
for (size_t realOverloadCount = 0; realOverloadCount < allDocumentation.size(); realOverloadCount++) {
|
||||
if (realOverloadCount != 0) {
|
||||
// separate it from the preceding one.
|
||||
concatDocString << "\n" << indentStr << "|\n\n";
|
||||
}
|
||||
|
||||
oneDoc = allDocumentation[realOverloadCount];
|
||||
trimWhitespace(oneDoc);
|
||||
concatDocString << indentStr << "*Overload " << (realOverloadCount + 1) << ":*\n" << oneDoc;
|
||||
}
|
||||
pyDocString = concatDocString.str();
|
||||
} else if (allDocumentation.size() == 1) {
|
||||
pyDocString = *(allDocumentation.begin());
|
||||
}
|
||||
}
|
||||
// for other nodes just process as normal
|
||||
else {
|
||||
documentation = getDoxygenComment(n);
|
||||
if (documentation != NULL) {
|
||||
if (GetFlag(n, "feature:doxygen:notranslate")) {
|
||||
String *comment = NewString("");
|
||||
Append(comment, documentation);
|
||||
Replaceall(comment, "\n *", "\n");
|
||||
pyDocString = Char(comment);
|
||||
Delete(comment);
|
||||
} else {
|
||||
std::list<DoxygenEntity> entityList = parser.createTree(n, documentation);
|
||||
DoxygenEntity root("root", entityList);
|
||||
pyDocString = translateSubtree(root);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we got something log the result
|
||||
if (!pyDocString.empty()) {
|
||||
|
||||
// remove the last '\n' since additional one is added during writing to file
|
||||
if (pyDocString[pyDocString.size() - 1] == '\n') {
|
||||
pyDocString.erase(pyDocString.size() - 1);
|
||||
}
|
||||
|
||||
if (m_flags & debug_translator) {
|
||||
std::cout << "\n---RESULT IN PYDOC---" << std::endl;
|
||||
std::cout << pyDocString;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return NewString(pyDocString.c_str());
|
||||
}
|
||||
198
Source/Doxygen/pydoc.h
Normal file
198
Source/Doxygen/pydoc.h
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* This file is part of SWIG, which is licensed as a whole under version 3
|
||||
* (or any later version) of the GNU General Public License. Some additional
|
||||
* terms also apply to certain portions of SWIG. The full details of the SWIG
|
||||
* license and copyrights can be found in the LICENSE and COPYRIGHT files
|
||||
* included with the SWIG source code as distributed by the SWIG developers
|
||||
* and at http://www.swig.org/legal.html.
|
||||
*
|
||||
* pydoc.h
|
||||
*
|
||||
* Module to return documentation for nodes formatted for PyDoc
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef PYDOCCONVERTER_H_
|
||||
#define PYDOCCONVERTER_H_
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include "swig.h"
|
||||
#include "doxyentity.h"
|
||||
#include "doxytranslator.h"
|
||||
|
||||
#define DOC_STRING_LENGTH 64 // characters per line allowed
|
||||
#define DOC_PARAM_STRING_LENGTH 30 // characters reserved for param name / type
|
||||
|
||||
class PyDocConverter : public DoxygenTranslator {
|
||||
public:
|
||||
PyDocConverter(int flags = 0);
|
||||
String *makeDocumentation(Node *node);
|
||||
|
||||
protected:
|
||||
|
||||
size_t m_tableLineLen;
|
||||
bool m_prevRowIsTH;
|
||||
std::string m_url;
|
||||
|
||||
/*
|
||||
* Translate every entity in a tree, also manages sections
|
||||
* display. Prints title for every group of tags that have
|
||||
* a section title associated with them
|
||||
*/
|
||||
std::string translateSubtree(DoxygenEntity &doxygenEntity);
|
||||
|
||||
/*
|
||||
* Translate one entity with the appropriate handler, according
|
||||
* to the tagHandlers
|
||||
*/
|
||||
void translateEntity(DoxygenEntity &doxyEntity, std::string &translatedComment);
|
||||
|
||||
/*
|
||||
* Typedef for the function that handles one tag
|
||||
* arg - some string argument to easily pass it through lookup table
|
||||
*/
|
||||
typedef void (PyDocConverter::*tagHandler) (DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Wrap the command data with the some string
|
||||
* arg - string to wrap with, like '_' or '*'
|
||||
*/
|
||||
void handleTagWrap(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Just prints new line
|
||||
*/
|
||||
void handleNewLine(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Print the name of tag to the output, used for escape-commands
|
||||
*/
|
||||
void handleTagChar(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Format the contents of the \exception tag or its synonyms.
|
||||
*/
|
||||
void handleTagException(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Print only the content and strip original tag
|
||||
*/
|
||||
void handleParagraph(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg = std::string());
|
||||
|
||||
/*
|
||||
* Handle one of the Doxygen formula-related tags.
|
||||
*/
|
||||
void handleMath(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Handle a code snippet.
|
||||
*/
|
||||
void handleCode(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Print only data part of code
|
||||
*/
|
||||
void handlePlainString(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/**
|
||||
* Copies verbatim args of the tag to output, used for commands like \f$, ...
|
||||
*/
|
||||
void handleTagVerbatim(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Print the if-elseif-else-endif section
|
||||
*/
|
||||
void handleTagIf(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Prints the specified message, than the contents of the tag
|
||||
* arg - message
|
||||
*/
|
||||
void handleTagMessage(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Insert 'Title: ...'
|
||||
*/
|
||||
void handleTagPar(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Insert 'Image: ...'
|
||||
*/
|
||||
void handleTagImage(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Format nice param description with type information
|
||||
*/
|
||||
void handleTagParam(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Format the contents of the \return tag or its synonyms.
|
||||
*/
|
||||
void handleTagReturn(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Writes text for \ref tag.
|
||||
*/
|
||||
void handleTagRef(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/* Handles HTML tags recognized by Doxygen, like <A ...>, <ul>, <table>, ... */
|
||||
|
||||
void handleDoxyHtmlTag(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/** Does not output params of HTML tag, for example in <table border='1'>
|
||||
* 'border=1' is not written to output.
|
||||
*/
|
||||
void handleDoxyHtmlTagNoParam(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/** Translates tag <a href = "url">text</a> to: text ("url"). */
|
||||
void handleDoxyHtmlTag_A(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Handles HTML tags, which are translated to markdown-like syntax, for example
|
||||
* <i>text</i> --> _text_. Appends arg for start HTML tag and end HTML tag.
|
||||
*/
|
||||
void handleDoxyHtmlTag2(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/* Handles HTML table, tag <tr> */
|
||||
void handleDoxyHtmlTag_tr(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/* Handles HTML table, tag <th> */
|
||||
void handleDoxyHtmlTag_th(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/* Handles HTML table, tag <td> */
|
||||
void handleDoxyHtmlTag_td(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/* Handles HTML entities recognized by Doxygen, like <, ©, ... */
|
||||
void handleHtmlEntity(DoxygenEntity &, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
|
||||
/*
|
||||
* Simple helper function that calculates correct parameter type
|
||||
* of the node stored in 'currentNode'
|
||||
* If param with specified name is not found, empty string is returned
|
||||
*/
|
||||
std::string getParamType(std::string name);
|
||||
|
||||
private:
|
||||
// temporary thing, should be refactored somehow
|
||||
Node *currentNode;
|
||||
|
||||
// Extra indent for the current paragraph, must be output after each new line.
|
||||
std::string m_indent;
|
||||
|
||||
|
||||
// this contains the handler pointer and one string argument
|
||||
typedef std::map<std::string, std::pair<tagHandler, std::string> >TagHandlersMap;
|
||||
static TagHandlersMap tagHandlers;
|
||||
|
||||
// this contains the sections tittles, like 'Arguments:' or 'Notes:', that are printed only once
|
||||
static std::map<std::string, std::string> sectionTitles;
|
||||
|
||||
// Helper functions for fillStaticTables(): make a new tag handler object.
|
||||
TagHandlersMap::mapped_type make_handler(tagHandler handler);
|
||||
TagHandlersMap::mapped_type make_handler(tagHandler handler, const char *arg);
|
||||
|
||||
void fillStaticTables();
|
||||
};
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue