Refactored PyDocConverter class, implemented some commands
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2012-doxygen@13331 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
3d5d66dbd3
commit
d9e8d140e7
2 changed files with 183 additions and 80 deletions
|
|
@ -17,9 +17,74 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
//TODO {@link} {@linkplain} {@docRoot}, and other useful doxy commands that are not a pydoc tag
|
// define static tables, they are filled in PyDocConverter's constructor
|
||||||
PyDocConverter::PyDocConverter() {
|
std::map<std::string, std::pair<PyDocConverter::tagHandler, std::string > > PyDocConverter::tagHandlers;
|
||||||
debug = 0;
|
std::map<std::string, std::string> PyDocConverter::sectionTitles;
|
||||||
|
|
||||||
|
void PyDocConverter::fillStaticTables() {
|
||||||
|
if (tagHandlers.size()) // fill only once
|
||||||
|
return;
|
||||||
|
|
||||||
|
sectionTitles["author"] = "Authors:";
|
||||||
|
sectionTitles["authors"] = "Authors:";
|
||||||
|
sectionTitles["copyright"] = "Copyright:";
|
||||||
|
sectionTitles["deprecated"] = "Deprecated:";
|
||||||
|
sectionTitles["param"] = "Arguments:";
|
||||||
|
sectionTitles["tparam"] = "Arguments:";
|
||||||
|
sectionTitles["note"] = "Notes:";
|
||||||
|
sectionTitles["remark"] = "Remarks:";
|
||||||
|
sectionTitles["remarks"] = "Remarks:";
|
||||||
|
sectionTitles["warning"] = "Warning:";
|
||||||
|
sectionTitles["result"] = "Return:";
|
||||||
|
sectionTitles["return"] = "Return:";
|
||||||
|
sectionTitles["returns"] = "Return:";
|
||||||
|
|
||||||
|
// these commands insert HTML tags
|
||||||
|
tagHandlers["a"] = make_pair(&PyDocConverter::handleTagWrap, "_");
|
||||||
|
tagHandlers["b"] = make_pair(&PyDocConverter::handleTagWrap, "__");
|
||||||
|
tagHandlers["cite"] = make_pair(&PyDocConverter::handleTagWrap, "'");
|
||||||
|
tagHandlers["e"] = make_pair(&PyDocConverter::handleTagWrap, "_");
|
||||||
|
// these commands insert just a single char, some of them need to be escaped
|
||||||
|
tagHandlers["$"] = make_pair(&PyDocConverter::handleTagChar, "");
|
||||||
|
tagHandlers["@"] = make_pair(&PyDocConverter::handleTagChar, "");
|
||||||
|
tagHandlers["\\"] = make_pair(&PyDocConverter::handleTagChar, "");
|
||||||
|
tagHandlers["<"] = make_pair(&PyDocConverter::handleTagChar, "");
|
||||||
|
tagHandlers[">"] = make_pair(&PyDocConverter::handleTagChar, "");
|
||||||
|
tagHandlers["&"] = make_pair(&PyDocConverter::handleTagChar, "");
|
||||||
|
tagHandlers["#"] = make_pair(&PyDocConverter::handleTagChar, "");
|
||||||
|
tagHandlers["%"] = make_pair(&PyDocConverter::handleTagChar, "");
|
||||||
|
tagHandlers["~"] = make_pair(&PyDocConverter::handleTagChar, "");
|
||||||
|
tagHandlers["\""] = make_pair(&PyDocConverter::handleTagChar, "");
|
||||||
|
tagHandlers["."] = make_pair(&PyDocConverter::handleTagChar, "");
|
||||||
|
tagHandlers["::"] = make_pair(&PyDocConverter::handleTagChar, "");
|
||||||
|
// these commands are stripped out
|
||||||
|
tagHandlers["attention"] = make_pair(&PyDocConverter::handleParagraph, "");
|
||||||
|
tagHandlers["author"] = make_pair(&PyDocConverter::handleParagraph, "");
|
||||||
|
tagHandlers["authors"] = make_pair(&PyDocConverter::handleParagraph, "");
|
||||||
|
tagHandlers["brief"] = make_pair(&PyDocConverter::handleParagraph, "");
|
||||||
|
tagHandlers["c"] = make_pair(&PyDocConverter::handleParagraph, "");
|
||||||
|
tagHandlers["code"] = make_pair(&PyDocConverter::handleParagraph, "");
|
||||||
|
tagHandlers["copyright"] = make_pair(&PyDocConverter::handleParagraph, "");
|
||||||
|
tagHandlers["date"] = make_pair(&PyDocConverter::handleParagraph, "");
|
||||||
|
tagHandlers["deprecated"] = make_pair(&PyDocConverter::handleParagraph, "");
|
||||||
|
tagHandlers["details"] = make_pair(&PyDocConverter::handleParagraph, "");
|
||||||
|
tagHandlers["note"] = make_pair(&PyDocConverter::handleParagraph, "");
|
||||||
|
tagHandlers["partofdescription"] = make_pair(&PyDocConverter::handleParagraph, "");
|
||||||
|
tagHandlers["remark"] = make_pair(&PyDocConverter::handleParagraph, "");
|
||||||
|
tagHandlers["remarks"] = make_pair(&PyDocConverter::handleParagraph, "");
|
||||||
|
tagHandlers["warning"] = make_pair(&PyDocConverter::handleParagraph, "");
|
||||||
|
// these commands have special handlers
|
||||||
|
tagHandlers["cond"] = make_pair(&PyDocConverter::handleTagMessage, "Conditional comment: ");
|
||||||
|
tagHandlers["endcond"] = make_pair(&PyDocConverter::handleTagMessage, "End of conditional comment.");
|
||||||
|
// this command just prints it's contents
|
||||||
|
// (it is internal command of swig's parser, contains plain text)
|
||||||
|
tagHandlers["plainstd::string"] = make_pair(&PyDocConverter::handlePlainString, "");
|
||||||
|
tagHandlers["plainstd::endl"] = make_pair(&PyDocConverter::handleNewLine, "");
|
||||||
|
tagHandlers["n"] = make_pair(&PyDocConverter::handleNewLine, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDocConverter::PyDocConverter() : debug(false) {
|
||||||
|
fillStaticTables();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string PyDocConverter::formatParam(Node *n, DoxygenEntity & doxygenEntity) {
|
std::string PyDocConverter::formatParam(Node *n, DoxygenEntity & doxygenEntity) {
|
||||||
|
|
@ -27,6 +92,7 @@ std::string PyDocConverter::formatParam(Node *n, DoxygenEntity & doxygenEntity)
|
||||||
if (doxygenEntity.entityList.size() < 2) {
|
if (doxygenEntity.entityList.size() < 2) {
|
||||||
/* if 'paramDescriptionEntity' is not there, ignore param. Better than crash!
|
/* if 'paramDescriptionEntity' is not there, ignore param. Better than crash!
|
||||||
TODO: log error! */
|
TODO: log error! */
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,67 +157,60 @@ std::string PyDocConverter::justifyString(std::string documentString, int indent
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string PyDocConverter::translateSubtree(DoxygenEntity & doxygenEntity) {
|
std::string PyDocConverter::translateSubtree(DoxygenEntity & doxygenEntity) {
|
||||||
std::string returnedString;
|
std::string translatedComment;
|
||||||
|
|
||||||
if (doxygenEntity.isLeaf)
|
if (doxygenEntity.isLeaf)
|
||||||
return doxygenEntity.data + " ";
|
return translatedComment;
|
||||||
else {
|
|
||||||
returnedString += doxygenEntity.data;
|
std::string currentSection;
|
||||||
std::list < DoxygenEntity >::iterator p = doxygenEntity.entityList.begin();
|
std::list < DoxygenEntity >::iterator p = doxygenEntity.entityList.begin();
|
||||||
while (p != doxygenEntity.entityList.end()) {
|
while (p != doxygenEntity.entityList.end()) {
|
||||||
returnedString += translateSubtree(*p);
|
std::map<std::string, std::string>::iterator it;
|
||||||
p++;
|
it = sectionTitles.find(p->typeOfEntity);
|
||||||
|
if (it != sectionTitles.end()) {
|
||||||
|
if (it->second != currentSection) {
|
||||||
|
currentSection = it->second;
|
||||||
|
translatedComment += currentSection + "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
translateEntity(*p, translatedComment);
|
||||||
return returnedString;
|
translateSubtree(*p);
|
||||||
}
|
p++;
|
||||||
|
|
||||||
std::string PyDocConverter::translateEntity(Node *n, DoxygenEntity & doxyEntity) {
|
|
||||||
if (doxyEntity.typeOfEntity.compare("partofdescription") == 0)
|
|
||||||
return justifyString(std::string(translateSubtree(doxyEntity)), 0);
|
|
||||||
|
|
||||||
if ((doxyEntity.typeOfEntity.compare("brief") == 0)
|
|
||||||
|| (doxyEntity.typeOfEntity.compare("details") == 0))
|
|
||||||
return justifyString(std::string(translateSubtree(doxyEntity)), 0) + "\n";
|
|
||||||
|
|
||||||
if (doxyEntity.typeOfEntity.compare("plainstd::string") == 0
|
|
||||||
|| doxyEntity.typeOfEntity.compare("deprecated") == 0
|
|
||||||
|| doxyEntity.typeOfEntity.compare("brief") == 0)
|
|
||||||
return justifyString(doxyEntity.data, 0) + "\n";
|
|
||||||
|
|
||||||
if (doxyEntity.typeOfEntity.compare("param") == 0)
|
|
||||||
return formatParam(n, doxyEntity);
|
|
||||||
|
|
||||||
if (doxyEntity.typeOfEntity.compare("return") == 0)
|
|
||||||
return formatReturnDescription(n, doxyEntity);
|
|
||||||
|
|
||||||
if (doxyEntity.typeOfEntity.compare("author") == 0
|
|
||||||
|| doxyEntity.typeOfEntity.compare("param") == 0
|
|
||||||
|| doxyEntity.typeOfEntity.compare("since") == 0
|
|
||||||
|| doxyEntity.typeOfEntity.compare("version") == 0
|
|
||||||
|| doxyEntity.typeOfEntity.compare("exception") == 0
|
|
||||||
|| doxyEntity.typeOfEntity.compare("deprecated") == 0
|
|
||||||
|| doxyEntity.typeOfEntity.compare("sa") == 0)
|
|
||||||
return "";
|
|
||||||
|
|
||||||
return justifyString(doxyEntity.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string PyDocConverter::processEntityList(Node *n, std::list < DoxygenEntity > &entityList) {
|
|
||||||
std::string result;
|
|
||||||
bool inParamsSection = false;
|
|
||||||
|
|
||||||
for (std::list < DoxygenEntity >::iterator entityIterator = entityList.begin(); entityIterator != entityList.end();) {
|
|
||||||
if (entityIterator->typeOfEntity.compare("param") == 0 && !inParamsSection) {
|
|
||||||
inParamsSection = true;
|
|
||||||
result += "\nArguments:\n";
|
|
||||||
} else if (entityIterator->typeOfEntity.compare("param") != 0 && inParamsSection)
|
|
||||||
inParamsSection = false;
|
|
||||||
|
|
||||||
result += translateEntity(n, *entityIterator);
|
|
||||||
entityIterator++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
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, std::string &arg) {
|
||||||
|
translatedComment += translateSubtree(tag);
|
||||||
|
}
|
||||||
|
void PyDocConverter::handlePlainString(DoxygenEntity& tag, std::string& translatedComment, std::string &arg) {
|
||||||
|
translatedComment += tag.data;
|
||||||
|
if (tag.data.size() && tag.data[tag.data.size()-1] != ' ')
|
||||||
|
translatedComment += "";
|
||||||
|
}
|
||||||
|
void PyDocConverter::handleTagMessage(DoxygenEntity& tag, std::string& translatedComment, std::string &arg) {
|
||||||
|
std::string dummy;
|
||||||
|
translatedComment += arg;
|
||||||
|
handleParagraph(tag, translatedComment, dummy);
|
||||||
|
}
|
||||||
|
void PyDocConverter::handleTagChar(DoxygenEntity& tag, std::string& translatedComment, std::string &arg) {
|
||||||
|
translatedComment += tag.typeOfEntity;
|
||||||
|
}
|
||||||
|
void PyDocConverter::handleTagWrap(DoxygenEntity& tag, std::string& translatedComment, std::string &arg) {
|
||||||
|
if (tag.entityList.size()) // do not include empty tags
|
||||||
|
translatedComment += arg + translateSubtree(tag) + arg;
|
||||||
|
}
|
||||||
|
void PyDocConverter::handleNewLine(DoxygenEntity& tag, std::string& translatedComment, std::string &arg) {
|
||||||
|
translatedComment += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
String *PyDocConverter::makeDocumentation(Node *n) {
|
String *PyDocConverter::makeDocumentation(Node *n) {
|
||||||
|
|
@ -171,7 +230,8 @@ String *PyDocConverter::makeDocumentation(Node *n) {
|
||||||
documentation = getDoxygenComment(n);
|
documentation = getDoxygenComment(n);
|
||||||
if (!Swig_is_generated_overload(n) && documentation) {
|
if (!Swig_is_generated_overload(n) && documentation) {
|
||||||
std::list < DoxygenEntity > entityList = parser.createTree(Char(documentation), Char(Getfile(documentation)), Getline(documentation));
|
std::list < DoxygenEntity > entityList = parser.createTree(Char(documentation), Char(Getfile(documentation)), Getline(documentation));
|
||||||
allDocumentation.push_back(processEntityList(n, entityList));
|
DoxygenEntity root("root", entityList);
|
||||||
|
allDocumentation.push_back(translateSubtree(root));
|
||||||
}
|
}
|
||||||
n = Getattr(n, "sym:nextSibling");
|
n = Getattr(n, "sym:nextSibling");
|
||||||
}
|
}
|
||||||
|
|
@ -180,10 +240,10 @@ String *PyDocConverter::makeDocumentation(Node *n) {
|
||||||
if (allDocumentation.size() > 1) {
|
if (allDocumentation.size() > 1) {
|
||||||
std::ostringstream concatDocString;
|
std::ostringstream concatDocString;
|
||||||
for (int realOverloadCount = 0; realOverloadCount < (int) allDocumentation.size(); realOverloadCount++) {
|
for (int realOverloadCount = 0; realOverloadCount < (int) allDocumentation.size(); realOverloadCount++) {
|
||||||
concatDocString << generateDivider();
|
concatDocString << generateDivider();
|
||||||
concatDocString << "Overload " << (realOverloadCount + 1) << ":" << std::endl;
|
concatDocString << "Overload " << (realOverloadCount + 1) << ":" << std::endl;
|
||||||
concatDocString << generateDivider();
|
concatDocString << generateDivider();
|
||||||
concatDocString << allDocumentation[realOverloadCount] << std::endl;
|
concatDocString << allDocumentation[realOverloadCount] << std::endl;
|
||||||
}
|
}
|
||||||
pyDocString = concatDocString.str();
|
pyDocString = concatDocString.str();
|
||||||
} else if (allDocumentation.size() == 1) {
|
} else if (allDocumentation.size() == 1) {
|
||||||
|
|
@ -195,7 +255,8 @@ String *PyDocConverter::makeDocumentation(Node *n) {
|
||||||
documentation = getDoxygenComment(n);
|
documentation = getDoxygenComment(n);
|
||||||
if (documentation != NULL) {
|
if (documentation != NULL) {
|
||||||
std::list < DoxygenEntity > entityList = parser.createTree(Char(documentation), Char(Getfile(documentation)), Getline(documentation));
|
std::list < DoxygenEntity > entityList = parser.createTree(Char(documentation), Char(Getfile(documentation)), Getline(documentation));
|
||||||
pyDocString = processEntityList(n, entityList);
|
DoxygenEntity root("root", entityList);
|
||||||
|
pyDocString = translateSubtree(root);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -216,9 +277,6 @@ String *PyDocConverter::makeDocumentation(Node *n) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string PyDocConverter::generateDivider() {
|
std::string PyDocConverter::generateDivider() {
|
||||||
std::ostringstream dividerString;
|
static string dividerString('-', DOC_STRING_LENGTH);
|
||||||
for (int i = 0; i < DOC_STRING_LENGTH; i++)
|
return dividerString;
|
||||||
dividerString << '-';
|
|
||||||
dividerString << std::endl;
|
|
||||||
return dividerString.str();
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,14 +29,6 @@ public:
|
||||||
String *makeDocumentation(Node *node);
|
String *makeDocumentation(Node *node);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/*
|
|
||||||
* Process the contents of the entity list producing a documentation string.
|
|
||||||
* @param node The parse tree node that the entity list relates to.
|
|
||||||
* @param entityList The entity list to process
|
|
||||||
*/
|
|
||||||
std::string processEntityList(Node *node, std::list < DoxygenEntity > &entityList);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Format the doxygen comment relating to a function or method parameter
|
* Format the doxygen comment relating to a function or method parameter
|
||||||
* @param node The parse tree node that the parameter relates to.
|
* @param node The parse tree node that the parameter relates to.
|
||||||
|
|
@ -61,7 +53,53 @@ protected:
|
||||||
std::string justifyString(std::string unformattedLine, int indent = 0, int maxWidth = DOC_STRING_LENGTH);
|
std::string justifyString(std::string unformattedLine, int indent = 0, int maxWidth = DOC_STRING_LENGTH);
|
||||||
|
|
||||||
std::string translateSubtree(DoxygenEntity & doxygenEntity);
|
std::string translateSubtree(DoxygenEntity & doxygenEntity);
|
||||||
std::string translateEntity(Node *n, DoxygenEntity & doxyEntity);
|
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, 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, 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
|
||||||
|
*/
|
||||||
|
void handleTagChar(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 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 'Image: ...'
|
||||||
|
*/
|
||||||
|
void handleTagImage(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||||
|
/*
|
||||||
|
* Insert 'Title: ...'
|
||||||
|
*/
|
||||||
|
void handleTagPar(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utility method to generate a diving line for a documentation string.
|
* Utility method to generate a diving line for a documentation string.
|
||||||
|
|
@ -70,6 +108,13 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool debug;
|
bool debug;
|
||||||
|
// temporary thing, should be refactored somehow
|
||||||
|
Node *currentNode;
|
||||||
|
// this contains the handler pointer and one string argument
|
||||||
|
static std::map<std::string, std::pair<tagHandler, std::string> > tagHandlers;
|
||||||
|
// this cointains the sectins titiles, like 'Arguments:' or 'Notes:', that are printed only once
|
||||||
|
static std::map<std::string, std::string> sectionTitles;
|
||||||
|
void fillStaticTables();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue