diff options
author | Dimitri van Heesch <dimitri@stack.nl> | 2012-01-22 19:51:13 (GMT) |
---|---|---|
committer | Dimitri van Heesch <dimitri@stack.nl> | 2012-01-22 19:51:13 (GMT) |
commit | c22d77a7a9c0f26a060a58047f514869a9e0a067 (patch) | |
tree | 082a1fab748f7d6917c9728b6f302bb4757de12d /src | |
parent | fd8b446f8ae60e7d1dc259c6f5fe38c287377d19 (diff) | |
download | Doxygen-c22d77a7a9c0f26a060a58047f514869a9e0a067.zip Doxygen-c22d77a7a9c0f26a060a58047f514869a9e0a067.tar.gz Doxygen-c22d77a7a9c0f26a060a58047f514869a9e0a067.tar.bz2 |
Release-1.7.6.1-20120122
Diffstat (limited to 'src')
-rw-r--r-- | src/code.l | 2 | ||||
-rw-r--r-- | src/commentcnv.l | 102 | ||||
-rw-r--r-- | src/commentscan.l | 127 | ||||
-rw-r--r-- | src/definition.cpp | 69 | ||||
-rw-r--r-- | src/definition.h | 3 | ||||
-rw-r--r-- | src/docparser.cpp | 27 | ||||
-rw-r--r-- | src/docparser.h | 11 | ||||
-rw-r--r-- | src/docsets.cpp | 3 | ||||
-rw-r--r-- | src/doctokenizer.l | 15 | ||||
-rw-r--r-- | src/doxygen.cpp | 11 | ||||
-rw-r--r-- | src/doxygen.css | 1 | ||||
-rw-r--r-- | src/doxygen_css.h | 1 | ||||
-rw-r--r-- | src/fortrancode.l | 4 | ||||
-rw-r--r-- | src/fortranscanner.l | 17 | ||||
-rw-r--r-- | src/ftvhelp.cpp | 14 | ||||
-rw-r--r-- | src/htmldocvisitor.cpp | 7 | ||||
-rw-r--r-- | src/index.cpp | 28 | ||||
-rw-r--r-- | src/latexdocvisitor.cpp | 89 | ||||
-rw-r--r-- | src/latexgen.cpp | 75 | ||||
-rw-r--r-- | src/markdown.cpp | 539 | ||||
-rw-r--r-- | src/markdown.h | 4 | ||||
-rw-r--r-- | src/marshal.cpp | 8 | ||||
-rw-r--r-- | src/navtree.js | 37 | ||||
-rw-r--r-- | src/navtree_js.h | 37 | ||||
-rw-r--r-- | src/parserintf.h | 4 | ||||
-rw-r--r-- | src/rtfdocvisitor.cpp | 7 | ||||
-rw-r--r-- | src/scanner.l | 60 | ||||
-rw-r--r-- | src/section.h | 17 | ||||
-rw-r--r-- | src/tagreader.cpp | 4 | ||||
-rw-r--r-- | src/util.cpp | 34 |
30 files changed, 985 insertions, 372 deletions
@@ -3031,7 +3031,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} <FuncCall,MemberCall2>("("{B}*("*"{B}*)+{ID}*{B}*")"{B}*)/("."|"->") { g_code->codify(yytext); int s=0;while (!isId(yytext[s])) s++; - int e=yyleng-1;while (!isId(yytext[e])) e--; + int e=(int)yyleng-1;while (!isId(yytext[e])) e--; g_name=((QCString)yytext).mid(s,e-s+1); BEGIN( MemberCall2 ); } diff --git a/src/commentcnv.l b/src/commentcnv.l index 5408f68..fa392bf 100644 --- a/src/commentcnv.l +++ b/src/commentcnv.l @@ -285,7 +285,7 @@ void replaceComment(int offset); %% <Scan>[^"'!\/\n\\#\\-]* { /* eat anything that is not " / or \n */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <Scan>"\"\"\""! { /* start of python long comment */ if (g_lang!=SrcLangExt_Python) @@ -295,7 +295,7 @@ void replaceComment(int offset); else { g_pythonDocString = TRUE; - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(CComment); } } @@ -306,22 +306,22 @@ void replaceComment(int offset); } else { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(CComment); } } <Scan>"\"" { /* start of a string */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); g_stringContext = YY_START; BEGIN(SkipString); } <Scan>' { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); g_charContext = YY_START; BEGIN(SkipChar); } <Scan>\n { /* new line */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <Scan>("//!"|"///").*/\n[ \t]*"//"[\/!][^\/] { /* start C++ style special comment block */ if (g_mlBrief) @@ -352,13 +352,13 @@ void replaceComment(int offset); BEGIN(SComment); } <Scan>"//"/.*\n { /* one line C++ comment */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); g_readLineCtx=YY_START; BEGIN(ReadLine); } <Scan>"/*"[*!]? { /* start of a C comment */ - g_specialComment=yyleng==3; - copyToOutput(yytext,yyleng); + g_specialComment=(int)yyleng==3; + copyToOutput(yytext,(int)yyleng); BEGIN(CComment); } <Scan>"#"("#")? { @@ -368,7 +368,7 @@ void replaceComment(int offset); } else { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(CComment); } } @@ -379,7 +379,7 @@ void replaceComment(int offset); } else { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(CComment); } } @@ -390,7 +390,7 @@ void replaceComment(int offset); } else { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(CComment); } } @@ -402,14 +402,14 @@ void replaceComment(int offset); BEGIN(VerbatimCode); } <CComment,ReadLine>[\\@]("dot"|"code"|"msc")/[^a-z_A-Z0-9] { /* start of a verbatim block */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); g_lastCommentContext = YY_START; g_javaBlock=0; g_blockName=&yytext[1]; BEGIN(VerbatimCode); } <CComment,ReadLine>[\\@]("f$"|"f["|"f{"[a-z]*) { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); g_blockName=&yytext[1]; if (g_blockName.at(1)=='[') { @@ -423,16 +423,16 @@ void replaceComment(int offset); BEGIN(Verbatim); } <CComment,ReadLine>[\\@]("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"rtfonly"|"manonly")/[^a-z_A-Z0-9] { /* start of a verbatim block */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); g_blockName=&yytext[1]; g_lastCommentContext = YY_START; BEGIN(Verbatim); } <Scan>. { /* any other character */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <Verbatim>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"endrtfonly"|"endmanonly"|"f$"|"f]"|"f}") { /* end of verbatim block */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); if (yytext[1]=='f') // end of formula { BEGIN(g_lastCommentContext); @@ -450,7 +450,7 @@ void replaceComment(int offset); else { g_javaBlock++; - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } } <VerbatimCode>"}" { @@ -468,12 +468,12 @@ void replaceComment(int offset); } else { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } } } <VerbatimCode>[\\@]("enddot"|"endcode"|"endmsc") { /* end of verbatim block */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); if (&yytext[4]==g_blockName) { BEGIN(g_lastCommentContext); @@ -482,14 +482,14 @@ void replaceComment(int offset); <VerbatimCode>^[ \t]*"//"[\!\/]? { /* skip leading comments */ if (!g_inSpecialComment) { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } } <Verbatim,VerbatimCode>[^@\/\\\n{}]* { /* any character not a backslash or new line or } */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <Verbatim,VerbatimCode>\n { /* new line in verbatim block */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <Verbatim,VerbatimCode>^[ \t]*"///" { if (g_blockName=="dot" || g_blockName=="msc" || g_blockName.at(0)=='f') @@ -503,40 +503,40 @@ void replaceComment(int offset); } } <Verbatim,VerbatimCode>. { /* any other character */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <SkipString>\\. { /* escaped character in string */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <SkipString>"\"" { /* end of string */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(g_stringContext); } <SkipString>. { /* any other string character */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <SkipString>\n { /* new line inside string (illegal for some compilers) */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <SkipChar>\\. { /* escaped character */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <SkipChar>' { /* end of character literal */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(g_charContext); } <SkipChar>. { /* any other string character */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <SkipChar>\n { /* new line character */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <CComment>[^\\!@*\n{\"]* { /* anything that is not a '*' or command */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <CComment>"*"+[^*/\\@\n{\"]* { /* stars without slashes */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <CComment>"\"\"\"" { /* end of Python docstring */ if (g_lang!=SrcLangExt_Python) @@ -546,12 +546,12 @@ void replaceComment(int offset); else { g_pythonDocString = FALSE; - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(Scan); } } <CComment>\n { /* new line in comment */ - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <CComment>"*"+"/" { /* end of C comment */ if (g_lang==SrcLangExt_Python) @@ -560,7 +560,7 @@ void replaceComment(int offset); } else { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(Scan); } } @@ -571,7 +571,7 @@ void replaceComment(int offset); } else { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(Scan); } } @@ -582,7 +582,7 @@ void replaceComment(int offset); } else { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(Scan); } } @@ -593,22 +593,22 @@ void replaceComment(int offset); } else { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(Scan); } } <CComment>"'" { g_charContext = YY_START; - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(SkipChar); } <CComment>"\"" { g_stringContext = YY_START; - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(SkipString); } <CComment>. { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <SComment>^[ \t]*"///"[\/]*/\n { replaceComment(0); @@ -666,17 +666,17 @@ void replaceComment(int offset); } <SComment>\n { /* end of special comment */ copyToOutput(" */",3); - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); g_inSpecialComment=FALSE; g_inRoseComment=FALSE; BEGIN(Scan); } <ReadLine>[^\\@\n]*/\n { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(g_readLineCtx); } <CComment,ReadLine>[\\@][\\@][~a-z_A-Z][a-z_A-Z0-9]*[ \t]* { // escaped command - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } <CComment,ReadLine>[\\@]"cond"[ \t]+ { // conditional section g_condCtx = YY_START; @@ -756,7 +756,7 @@ void replaceComment(int offset); else // abort the alias, restart scanning { copyToOutput(g_aliasString,g_aliasString.length()); - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); BEGIN(Scan); } } @@ -794,7 +794,7 @@ void replaceComment(int offset); g_lastEscaped=FALSE; } <ReadLine>. { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } %% @@ -803,7 +803,7 @@ void replaceComment(int offset) { if (g_mlBrief) { - copyToOutput(yytext,yyleng); + copyToOutput(yytext,(int)yyleng); } else { @@ -811,12 +811,12 @@ void replaceComment(int offset) int i=computeIndent(&yytext[offset]); if (i==g_blockHeadCol) { - replaceCommentMarker(yytext,yyleng); + replaceCommentMarker(yytext,(int)yyleng); } else { copyToOutput(" */",3); - int i;for (i=yyleng-1;i>=0;i--) unput(yytext[i]); + int i;for (i=(int)yyleng-1;i>=0;i--) unput(yytext[i]); g_inSpecialComment=FALSE; BEGIN(Scan); } diff --git a/src/commentscan.l b/src/commentscan.l index 4f4408f..85b378a 100644 --- a/src/commentscan.l +++ b/src/commentscan.l @@ -387,8 +387,9 @@ static Entry* current = 0 ; // working entry //static Entry* previous = 0 ; // TODO: remove need for this static bool needNewEntry; -static QCString sectionLabel; -static QCString sectionTitle; +static QCString g_sectionLabel; +static QCString g_sectionTitle; +static int g_sectionLevel; static QCString xrefItemKey; static QCString newXRefItemKey; static QCString xrefItemTitle; @@ -401,7 +402,6 @@ static int braceCount; static bool insidePre; static bool parseMore; static int g_condCount; -static int g_sectionLevel; static int g_commentCount; static bool g_spaceBeforeCmd; @@ -421,38 +421,40 @@ static QCString g_compoundName; static void initParser() { - sectionLabel.resize(0); - sectionTitle.resize(0); + g_sectionLabel.resize(0); + g_sectionTitle.resize(0); g_memberGroupHeader.resize(0); } //----------------------------------------------------------------------------- -static QCString getDocSectionName(int s) +static bool getDocSectionName(int s) { switch(s) { - case Entry::CLASSDOC_SEC: return "\\class"; - case Entry::STRUCTDOC_SEC: return "\\struct"; - case Entry::UNIONDOC_SEC: return "\\union"; - case Entry::EXCEPTIONDOC_SEC: return "\\exception"; - case Entry::NAMESPACEDOC_SEC: return "\\namespace"; - case Entry::PROTOCOLDOC_SEC: return "\\protocol"; - case Entry::CATEGORYDOC_SEC: return "\\category"; - case Entry::ENUMDOC_SEC: return "\\enum"; - case Entry::PAGEDOC_SEC: return "\\page"; - case Entry::VARIABLEDOC_SEC: return "\\var"; - case Entry::MEMBERDOC_SEC: return "\\fn"; - case Entry::OVERLOADDOC_SEC: return "\\overload"; - case Entry::FILEDOC_SEC: return "\\file"; - case Entry::DEFINEDOC_SEC: return "\\def"; - case Entry::GROUPDOC_SEC: return "\\defgroup"; - case Entry::MAINPAGEDOC_SEC: return "\\mainpage"; - case Entry::PACKAGEDOC_SEC: return "\\package"; - case Entry::DIRDOC_SEC: return "\\dir"; - case Entry::EXAMPLE_SEC: return "\\example"; - case Entry::MEMBERGRP_SEC: return "\\name"; - default: return ""; + case Entry::CLASSDOC_SEC: + case Entry::STRUCTDOC_SEC: + case Entry::UNIONDOC_SEC: + case Entry::EXCEPTIONDOC_SEC: + case Entry::NAMESPACEDOC_SEC: + case Entry::PROTOCOLDOC_SEC: + case Entry::CATEGORYDOC_SEC: + case Entry::ENUMDOC_SEC: + case Entry::PAGEDOC_SEC: + case Entry::VARIABLEDOC_SEC: + case Entry::MEMBERDOC_SEC: + case Entry::OVERLOADDOC_SEC: + case Entry::FILEDOC_SEC: + case Entry::DEFINEDOC_SEC: + case Entry::GROUPDOC_SEC: + case Entry::MAINPAGEDOC_SEC: + case Entry::PACKAGEDOC_SEC: + case Entry::DIRDOC_SEC: + case Entry::EXAMPLE_SEC: + case Entry::MEMBERGRP_SEC: + return TRUE; + default: + return FALSE; } } @@ -461,7 +463,7 @@ static QCString getDocSectionName(int s) static bool makeStructuralIndicator(Entry::Sections s) { //printf("current->section=%x\n",current->section); - if (!getDocSectionName(current->section).isEmpty()) + if (getDocSectionName(current->section)) { return TRUE; } @@ -558,8 +560,9 @@ static void addXRefItem(const char *listName,const char *itemTitle, docEntry->doc += cmdString; } SectionInfo *si=new SectionInfo(listName,anchorLabel, - sectionTitle,SectionInfo::Anchor); - Doxygen::sectionDict.insert(anchorLabel,si); + g_sectionTitle,SectionInfo::Anchor, + g_sectionLevel); + Doxygen::sectionDict.append(anchorLabel,si); docEntry->anchors->append(si); } outputXRef.resize(0); @@ -598,14 +601,26 @@ static QCString addFormula() static void checkFormula(); //----------------------------------------------------------------------------- +static SectionInfo::SectionType sectionLevelToType(int level) +{ + if (level>=0 && level<5) return (SectionInfo::SectionType)level; + return SectionInfo::Anchor; +} + static void addSection() { - sectionTitle+=yytext; - sectionTitle=sectionTitle.stripWhiteSpace(); - //printf("Adding new section file=%s label=%s title=%s\n",yyFileName,sectionLabel.data(),sectionTitle.data()); - SectionInfo *si = new SectionInfo(yyFileName,sectionLabel,sectionTitle,SectionInfo::Anchor); + // create a new section element + g_sectionTitle+=yytext; + g_sectionTitle=g_sectionTitle.stripWhiteSpace(); + SectionInfo *si = new SectionInfo(yyFileName,g_sectionLabel, + g_sectionTitle,sectionLevelToType(g_sectionLevel),g_sectionLevel); + + // add section to this entry current->anchors->append(si); - Doxygen::sectionDict.insert(yytext,si); + + // add section to the global dictionary + Doxygen::sectionDict.append(g_sectionLabel,si); + } //----------------------------------------------------------------------------- @@ -1061,7 +1076,22 @@ RCSTAG "$"{ID}":"[^\n$]+"$" addOutput(yytext); } <Comment>^{B}*[1-9][0-9]*"."{B}+ | -<Comment>^{B}*[*+-]{B}+ { // start of autolist +<Comment>^{B}*[*+]{B}+ { // start of autolist + if (!Doxygen::markdownSupport) + { + REJECT; + } + else + { + if (inContext!=OutputXRef) + { + briefEndsAtDot=FALSE; + setOutput(OutputDoc); + } + addOutput(yytext); + } + } +<Comment>^{B}*"-"{B}+ { // start of autolist if (inContext!=OutputXRef) { briefEndsAtDot=FALSE; @@ -1492,9 +1522,9 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ----- handle arguments of the section/subsection/.. commands ------- */ <SectionLabel>{LABELID} { // first argyment - sectionLabel=yytext; + g_sectionLabel=yytext; addOutput(yytext); - sectionTitle.resize(0); + g_sectionTitle.resize(0); BEGIN(SectionTitle); } <SectionLabel>{DOCNL} { // missing argument @@ -1511,8 +1541,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" ); BEGIN(Comment); } - -<SectionTitle>[^\n@\\*]*/"\n" { // end of section title +<SectionTitle>[^\n@\\*]*/"\n" { // end of section title addSection(); addOutput(yytext); BEGIN( Comment ); @@ -1527,19 +1556,19 @@ RCSTAG "$"{ID}":"[^\n$]+"$" addOutput('\n'); } <SectionTitle>[^\n@\\]* { // any character without special meaning - sectionTitle+=yytext; + g_sectionTitle+=yytext; addOutput(yytext); } <SectionTitle>("\\\\"|"@@"){ID} { // unescape escaped command - sectionTitle+=&yytext[1]; + g_sectionTitle+=&yytext[1]; addOutput(yytext); } <SectionTitle>{CMD}[$@\\&~<>#%] { // unescape escaped character - sectionTitle+=yytext[1]; + g_sectionTitle+=yytext[1]; addOutput(yytext); } <SectionTitle>. { // anything else - sectionTitle+=yytext; + g_sectionTitle+=yytext; addOutput(*yytext); } @@ -1576,8 +1605,8 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ----- handle arguments of the anchor command ------- */ <AnchorLabel>{LABELID} { // found argument - SectionInfo *si = new SectionInfo(yyFileName,yytext,0,SectionInfo::Anchor); - Doxygen::sectionDict.insert(yytext,si); + SectionInfo *si = new SectionInfo(yyFileName,yytext,0,SectionInfo::Anchor,0); + Doxygen::sectionDict.append(yytext,si); current->anchors->append(si); addOutput(yytext); BEGIN( Comment ); @@ -2646,9 +2675,9 @@ bool parseCommentBlock(/* in */ ParserInterface *parser, if (Doxygen::markdownSupport) { - current->brief = processMarkdown(current->brief); - current->doc = processMarkdown(current->doc); - current->inbodyDocs = processMarkdown(current->inbodyDocs); + current->brief = processMarkdown(fileName,current,current->brief); + current->doc = processMarkdown(fileName,current,current->doc); + current->inbodyDocs = processMarkdown(fileName,current,current->inbodyDocs); } Debug::print(Debug::CommentScan,0, diff --git a/src/definition.cpp b/src/definition.cpp index e04c767..4bca129 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -320,10 +320,11 @@ void Definition::addSectionsToDefinition(QList<SectionInfo> *anchorList) //printf("Add section `%s' to definition `%s'\n", // si->label.data(),name().data()); SectionInfo *gsi=Doxygen::sectionDict.find(si->label); + //printf("===== label=%s gsi=%p\n",si->label.data(),gsi); if (gsi==0) { gsi = new SectionInfo(*si); - Doxygen::sectionDict.insert(si->label,gsi); + Doxygen::sectionDict.append(si->label,gsi); } if (m_impl->sectionDict==0) { @@ -331,20 +332,82 @@ void Definition::addSectionsToDefinition(QList<SectionInfo> *anchorList) } if (m_impl->sectionDict->find(gsi->label)==0) { - m_impl->sectionDict->insert(gsi->label,gsi); + m_impl->sectionDict->append(gsi->label,gsi); gsi->definition = this; } si=anchorList->next(); } } +bool Definition::hasSections() const +{ + makeResident(); + //printf("Definition::hasSections(%s) #sections=%d\n",name().data(), + // m_impl->sectionDict ? m_impl->sectionDict->count() : 0); + if (m_impl->sectionDict==0) return FALSE; + SDict<SectionInfo>::Iterator li(*m_impl->sectionDict); + SectionInfo *si; + for (li.toFirst();(si=li.current());++li) + { + if (si->type==SectionInfo::Section || + si->type==SectionInfo::Subsection || + si->type==SectionInfo::Subsubsection || + si->type==SectionInfo::Paragraph) + { + return TRUE; + } + } + return FALSE; +} + +void Definition::addSectionsToIndex() +{ + makeResident(); + if (m_impl->sectionDict==0) return; + //printf("Definition::addSectionsToIndex()\n"); + SDict<SectionInfo>::Iterator li(*m_impl->sectionDict); + SectionInfo *si; + int level=0; + for (li.toFirst();(si=li.current());++li) + { + if (si->type==SectionInfo::Section || + si->type==SectionInfo::Subsection || + si->type==SectionInfo::Subsubsection || + si->type==SectionInfo::Paragraph) + { + //printf(" level=%d title=%s\n",level,si->title.data()); + int nextLevel = (int)si->type; + if (nextLevel>level) + { + Doxygen::indexList.incContentsDepth(); + } + else if (nextLevel<level) + { + Doxygen::indexList.decContentsDepth(); + } + Doxygen::indexList.addContentsItem(TRUE,si->title, + getReference(), + getOutputFileBase(), + si->label, + FALSE, + TRUE); + level = nextLevel; + } + } + while (level>0) + { + Doxygen::indexList.decContentsDepth(); + level--; + } +} + void Definition::writeDocAnchorsToTagFile() { makeResident(); if (!Config_getString("GENERATE_TAGFILE").isEmpty() && m_impl->sectionDict) { //printf("%s: writeDocAnchorsToTagFile(%d)\n",name().data(),m_sectionDict->count()); - QDictIterator<SectionInfo> sdi(*m_impl->sectionDict); + SDict<SectionInfo>::Iterator sdi(*m_impl->sectionDict); SectionInfo *si; for (;(si=sdi.current());++sdi) { diff --git a/src/definition.h b/src/definition.h index 1e51a1c..c07eb3e 100644 --- a/src/definition.h +++ b/src/definition.h @@ -260,6 +260,7 @@ class Definition : public DefinitionIntf, public LockableObj LockingPtr<MemberSDict> getReferencesMembers() const; LockingPtr<MemberSDict> getReferencedByMembers() const; + bool hasSections() const; //----------------------------------------------------------------------------------- // ---- setters ----- @@ -328,6 +329,8 @@ class Definition : public DefinitionIntf, public LockableObj void writeDocAnchorsToTagFile(); void setLocalName(const QCString name); + void addSectionsToIndex(); + protected: virtual void flushToDisk() const; diff --git a/src/docparser.cpp b/src/docparser.cpp index 3ec6631..526e349 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -1720,7 +1720,7 @@ DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor) if (g_sectionDict && g_sectionDict->find(id)==0) { //printf("Inserting in dictionary!\n"); - g_sectionDict->insert(id,sec); + g_sectionDict->append(id,sec); } } else @@ -1736,9 +1736,10 @@ DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor) DocVerbatim::DocVerbatim(DocNode *parent,const QCString &context, const QCString &text, Type t,bool isExample, - const QCString &exampleFile) + const QCString &exampleFile,const QCString &lang) : m_context(context), m_text(text), m_type(t), - m_isExample(isExample), m_exampleFile(exampleFile), m_relPath(g_relPath) + m_isExample(isExample), m_exampleFile(exampleFile), + m_relPath(g_relPath), m_lang(lang) { m_parent = parent; } @@ -2134,7 +2135,7 @@ void DocSecRefItem::parse() m_anchor = sec->label; if (g_sectionDict && g_sectionDict->find(m_target)==0) { - g_sectionDict->insert(m_target,sec); + g_sectionDict->append(m_target,sec); } } else @@ -2278,7 +2279,7 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) : m_parent = parent; Definition *compound = 0; QCString anchor; - //printf("DocRef::DocRef(target=%s,context=%s\n",target.data(),context.data()); + //printf("DocRef::DocRef(target=%s,context=%s)\n",target.data(),context.data()); ASSERT(!target.isEmpty()); m_relPath = g_relPath; SectionInfo *sec = Doxygen::sectionDict[target]; @@ -2299,7 +2300,8 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) : else if (resolveLink(context,target,TRUE,&compound,anchor)) { bool isFile = compound ? - (compound->definitionType()==Definition::TypeFile ? TRUE : FALSE) : + (compound->definitionType()==Definition::TypeFile || + compound->definitionType()==Definition::TypePage ? TRUE : FALSE) : FALSE; m_text = linkToText(compound?compound->getLanguage():SrcLangExt_Unknown,target,isFile); m_anchor = anchor; @@ -2323,6 +2325,8 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) : m_file = compound->getOutputFileBase(); m_ref = compound->getReference(); + //printf("isFile=%d compound=%s (%d)\n",isFile,compound->name().data(), + // compound->definitionType()); return; } else if (compound->definitionType()==Definition::TypeFile && @@ -2334,7 +2338,7 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) : return; } } - m_text = linkToText(SrcLangExt_Unknown,target,FALSE); + m_text = target; warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unable to resolve reference to `%s' for \\ref command", qPrint(target)); } @@ -4902,6 +4906,11 @@ bool DocPara::injectToken(int tok,const QCString &tokText) int DocPara::handleStartCode() { int retval = doctokenizerYYlex(); + QCString lang = g_token->name; + if (!lang.isEmpty() && lang.at(0)!='.') + { + lang="."+lang; + } // search for the first non-whitespace line, index is stored in li int i=0,li=0,l=g_token->verb.length(); while (i<l && (g_token->verb.at(i)==' ' || g_token->verb.at(i)=='\n')) @@ -4909,7 +4918,7 @@ int DocPara::handleStartCode() if (g_token->verb.at(i)=='\n') li=i+1; i++; } - m_children.append(new DocVerbatim(this,g_context,g_token->verb.mid(li),DocVerbatim::Code,g_isExample,g_exampleName)); + m_children.append(new DocVerbatim(this,g_context,g_token->verb.mid(li),DocVerbatim::Code,g_isExample,g_exampleName,lang)); if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: code section ended without end marker"); doctokenizerYYsetStatePara(); return retval; @@ -6264,7 +6273,7 @@ int DocSection::parse() if (m_title.isEmpty()) m_title = sec->label; if (g_sectionDict && g_sectionDict->find(m_id)==0) { - g_sectionDict->insert(m_id,sec); + g_sectionDict->append(m_id,sec); } } } diff --git a/src/docparser.h b/src/docparser.h index 4e8587c..1e7f7d8 100644 --- a/src/docparser.h +++ b/src/docparser.h @@ -375,7 +375,7 @@ class DocVerbatim : public DocNode enum Type { Code, HtmlOnly, ManOnly, LatexOnly, XmlOnly, Verbatim, Dot, Msc }; DocVerbatim(DocNode *parent,const QCString &context, const QCString &text, Type t,bool isExample, - const QCString &exampleFile); + const QCString &exampleFile,const QCString &lang=QCString()); Kind kind() const { return Kind_Verbatim; } Type type() const { return m_type; } QCString text() const { return m_text; } @@ -384,14 +384,16 @@ class DocVerbatim : public DocNode bool isExample() const { return m_isExample; } QCString exampleFile() const { return m_exampleFile; } QCString relPath() const { return m_relPath; } + QCString language() const { return m_lang; } private: QCString m_context; QCString m_text; - Type m_type; - bool m_isExample; + Type m_type; + bool m_isExample; QCString m_exampleFile; QCString m_relPath; + QCString m_lang; }; @@ -1190,6 +1192,9 @@ class DocHtmlRow : public CompAccept<DocHtmlRow>, public DocNode const HtmlAttribList &attribs() const { return m_attribs; } int parse(); int parseXml(bool header); + bool isHeading() const { return m_children.count()>0 && + ((DocHtmlCell*)m_children.getFirst())->isHeading(); + } private: HtmlAttribList m_attribs; diff --git a/src/docsets.cpp b/src/docsets.cpp index fa86dc8..7a6ff9d 100644 --- a/src/docsets.cpp +++ b/src/docsets.cpp @@ -290,7 +290,8 @@ void DocSets::addIndexItem(Definition *context,MemberDef *md,const char *) case SrcLangExt_VHDL: lang="vhdl"; break; // VHDL case SrcLangExt_XML: lang="xml"; break; // DBUS XML case SrcLangExt_Tcl: lang="tcl"; break; // Tcl - case SrcLangExt_Unknown: lang="unknown"; break; // should not happen! + case SrcLangExt_Markdown:lang="markdown"; break; // Markdown + case SrcLangExt_Unknown: lang="unknown"; break; // should not happen! } if (md) diff --git a/src/doctokenizer.l b/src/doctokenizer.l index 765e6c8..c9e5756 100644 --- a/src/doctokenizer.l +++ b/src/doctokenizer.l @@ -389,6 +389,7 @@ REFWORD {LABELID}|{REFWORD2}|{REFWORD3} %x St_TitleA %x St_TitleV %x St_Code +%x St_CodeOpt %x St_XmlCode %x St_HtmlOnly %x St_ManOnly @@ -696,6 +697,16 @@ REFWORD {LABELID}|{REFWORD2}|{REFWORD3} return TK_NEWPARA; } } +<St_CodeOpt>"{"{LABELID}"}" { + g_token->name = yytext; + g_token->name = g_token->name.mid(1,g_token->name.length()-2); + BEGIN(St_Code); + } +<St_CodeOpt>\n | +<St_CodeOpt>. { + unput(*yytext); + BEGIN(St_Code); + } <St_Code>{WS}*{CMD}"endcode" { return RetVal_OK; } @@ -1154,12 +1165,14 @@ void doctokenizerYYsetStateTitleAttrValue() void doctokenizerYYsetStateCode() { g_token->verb=""; - BEGIN(St_Code); + g_token->name=""; + BEGIN(St_CodeOpt); } void doctokenizerYYsetStateXmlCode() { g_token->verb=""; + g_token->name=""; BEGIN(St_XmlCode); } diff --git a/src/doxygen.cpp b/src/doxygen.cpp index aa61647..34fe2d1 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -163,8 +163,6 @@ static bool g_successfulRun = FALSE; static bool g_dumpSymbolMap = FALSE; static bool g_dumpConfigAsXML = FALSE; - - void clearAll() { g_inputFiles.clear(); @@ -8233,8 +8231,9 @@ static void findMainPage(EntryNav *rootNav) indexName, Doxygen::mainPage->name(), Doxygen::mainPage->title(), - SectionInfo::Page); - Doxygen::sectionDict.insert(indexName,si); + SectionInfo::Page, + 0); // level 0 + Doxygen::sectionDict.append(indexName,si); Doxygen::mainPage->addSectionsToDefinition(root->anchors); } else @@ -8310,7 +8309,7 @@ static void checkPageRelations() static void resolveUserReferences() { - QDictIterator<SectionInfo> sdi(Doxygen::sectionDict); + SDict<SectionInfo>::Iterator sdi(Doxygen::sectionDict); SectionInfo *si; for (;(si=sdi.current());++sdi) { @@ -9380,7 +9379,7 @@ void initDoxygen() Doxygen::memGrpInfoDict.setAutoDelete(TRUE); Doxygen::tagDestinationDict.setAutoDelete(TRUE); Doxygen::dirRelations.setAutoDelete(TRUE); - Doxygen::citeDict = new CiteDict(256); + Doxygen::citeDict = new CiteDict(257); } void cleanUpDoxygen() diff --git a/src/doxygen.css b/src/doxygen.css index 613a3d3..b146398 100644 --- a/src/doxygen.css +++ b/src/doxygen.css @@ -638,7 +638,6 @@ table.doxtable th { font-size: 110%; padding-bottom: 4px; padding-top: 5px; - text-align:left; } table.fieldtable { diff --git a/src/doxygen_css.h b/src/doxygen_css.h index 1e4f161..15c68da 100644 --- a/src/doxygen_css.h +++ b/src/doxygen_css.h @@ -638,7 +638,6 @@ " font-size: 110%;\n" " padding-bottom: 4px;\n" " padding-top: 5px;\n" -" text-align:left;\n" "}\n" "\n" "table.fieldtable {\n" diff --git a/src/fortrancode.l b/src/fortrancode.l index a9bfd8b..f111e58 100644 --- a/src/fortrancode.l +++ b/src/fortrancode.l @@ -661,7 +661,7 @@ ATTR_SPEC (ALLOCATABLE|DIMENSION{ARGS}|EXTERNAL|{INTENT_SPEC}|INTRINSIC|OPTIONAL ACCESS_SPEC (PRIVATE|PUBLIC) /* Assume that attribute statements are almost the same as attributes. */ ATTR_STMT {ATTR_SPEC}|DIMENSION -COMMANDS (BLOCK{BS}DATA|DO|SELECT|CASE|WHERE|IF|THEN|ELSE|MODULE{BS_}PROCEDURE|CONTAINS|IMPLICIT{BS}NONE|CONTAINS|WRITE|READ|ALLOCATE|ALLOCATED|ASSOCIATED|DEALLOCATE|SIZE|END{BS}IF|END{BS}DO|WHILE|INQUIRE|OPEN|CLOSE|DATA) +COMMANDS (DO|SELECT|CASE|WHERE|IF|THEN|ELSE|MODULE{BS_}PROCEDURE|CONTAINS|IMPLICIT{BS}NONE|CONTAINS|WRITE|READ|ALLOCATE|ALLOCATED|ASSOCIATED|DEALLOCATE|SIZE|END{BS}IF|END{BS}DO|WHILE|INQUIRE|OPEN|CLOSE|DATA) IGNORE (CALL) /* | */ @@ -741,7 +741,7 @@ IGNORE (CALL) } /*-------- fortran module -----------------------------------------*/ -<Start>("program"|"module"|"type"|"interface")/{BS_}|({COMMA}{ACCESS_SPEC})|\n { // +<Start>("block"{BS}"data"|"program"|"module"|"type"|"interface")/{BS_}|({COMMA}{ACCESS_SPEC})|\n { // startScope(); startFontClass("keyword"); codifyLines(yytext); diff --git a/src/fortranscanner.l b/src/fortranscanner.l index 16d17f8..a512647 100644 --- a/src/fortranscanner.l +++ b/src/fortranscanner.l @@ -230,6 +230,7 @@ IDSYM [a-z_A-Z0-9] NOTIDSYM [^a-z_A-Z0-9] SEPARATE [:, \t] ID [a-z_A-Z%]+{IDSYM}* +ID_ [a-z_A-Z%]*{IDSYM}* PP_ID {ID} LABELID [a-z_A-Z]+[a-z_A-Z0-9\-]* SUBPROG (subroutine|function) @@ -299,6 +300,7 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA %x DocBackLine %x EndDoc +%x BlockData %% /*-----------------------------------------------------------------------------------*/ @@ -505,6 +507,11 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA <TypedefBody>^{BS}{CONTAINS}/({BS}|\n|!) { BEGIN(TypedefBodyContains); } /*------ module handling ------------------------------------------------------------*/ +<Start>block{BS}data{BS}{ID_} { // + v_type = V_IGNORE; + yy_push_state(BlockData); + defaultProtection = Public; + } <Start>module|program{BS_} { // v_type = V_IGNORE; if(yytext[0]=='m' || yytext[0]=='M') @@ -513,6 +520,12 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA yy_push_state(Program); defaultProtection = Public; } +<BlockData>^{BS}"end"({BS}(block{BS}data)({BS_}{ID})?)?{BS}/(\n|!) { // end block data + //if (!endScope(current_root)) + // yyterminate(); + defaultProtection = Public; + yy_pop_state(); + } <Start,ModuleBody,ModuleBodyContains>^{BS}"end"({BS}(module|program)({BS_}{ID})?)?{BS}/(\n|!) { // end module resolveModuleProcedures(moduleProcedures, current_root); if (!endScope(current_root)) @@ -660,6 +673,10 @@ private { subrCurrent.remove(0u); yy_pop_state() ; } +<BlockData>{ +{ID} { + } +} <Start,ModuleBody,TypedefBody,SubprogBody>{ ^{BS}{TYPE_SPEC}/{SEPARATE} { /* variable declaration starts */ diff --git a/src/ftvhelp.cpp b/src/ftvhelp.cpp index 5d1061c..a8f9de3 100644 --- a/src/ftvhelp.cpp +++ b/src/ftvhelp.cpp @@ -31,6 +31,7 @@ #include "language.h" #include "htmlgen.h" #include "layout.h" +#include "pagedef.h" #define MAX_INDENT 1024 @@ -849,10 +850,17 @@ void FTVHelp::generateTreeViewScripts() QCString &projName = Config_getString("PROJECT_NAME"); if (projName.isEmpty()) { - LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::MainPage); - t << "\"" << convertToJSString(lne->title()) << "\", "; + if (Doxygen::mainPage && !Doxygen::mainPage->title().isEmpty()) // Use title of main page as root + { + t << "\"" << convertToJSString(Doxygen::mainPage->title()) << "\", "; + } + else // Use default section title as root + { + LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::MainPage); + t << "\"" << convertToJSString(lne->title()) << "\", "; + } } - else + else // use PROJECT_NAME as root tree element { t << "\"" << convertToJSString(projName) << "\", "; } diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp index 5ecb124..70fa3f8 100644 --- a/src/htmldocvisitor.cpp +++ b/src/htmldocvisitor.cpp @@ -330,12 +330,17 @@ void HtmlDocVisitor::visit(DocStyleChange *s) void HtmlDocVisitor::visit(DocVerbatim *s) { if (m_hide) return; + QCString lang = m_langExt; + if (!s->language().isEmpty()) // explicit language setting + { + lang = s->language(); + } switch(s->type()) { case DocVerbatim::Code: forceEndParagraph(s); m_t << PREFRAG_START; - Doxygen::parserManager->getParser(m_langExt) + Doxygen::parserManager->getParser(lang) ->parseCode(m_ci,s->context(),s->text(), s->isExample(),s->exampleFile()); m_t << PREFRAG_END; diff --git a/src/index.cpp b/src/index.cpp index 09e152c..68725aa 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -2765,7 +2765,7 @@ static void writePageIndex(OutputList &ol) ol.startContents(); ol.startTextBlock(); bool addToIndex = lne==0 || lne->visible(); - if (addToIndex) + if (0 /*addToIndex*/) // skip Related Pages section in navigation index { Doxygen::indexList.addContentsItem(TRUE,title,0,"pages",0,TRUE,TRUE); Doxygen::indexList.incContentsDepth(); @@ -2777,7 +2777,7 @@ static void writePageIndex(OutputList &ol) PageDef *pd=0; for (pdi.toFirst();(pd=pdi.current());++pdi) { - if ( pd->visibleInIndex()) + if (pd->visibleInIndex()) { QCString pageTitle; @@ -2787,6 +2787,7 @@ static void writePageIndex(OutputList &ol) pageTitle=pd->title(); bool hasSubPages = pd->hasSubPages(); + bool hasSections = pd->hasSections(); ol.startIndexListItem(); ol.startIndexItem(pd->getReference(),pd->getOutputFileBase()); @@ -2801,14 +2802,25 @@ static void writePageIndex(OutputList &ol) ol.writeString("\n"); if (addToIndex) { - Doxygen::indexList.addContentsItem(hasSubPages,filterTitle(pageTitle),pd->getReference(),pd->getOutputFileBase(),0,hasSubPages,TRUE); + Doxygen::indexList.addContentsItem( + hasSubPages || hasSections, // isDir + filterTitle(pageTitle), // name + pd->getReference(), // ref + pd->getOutputFileBase(), // file + 0, // anchor + hasSubPages || hasSections, // separateIndex + TRUE); // addToNavIndex + if (hasSections) + { + pd->addSectionsToIndex(); + } } writeSubPages(pd); ol.endIndexListItem(); } } endIndexHierarchy(ol,0); - if (addToIndex) + if (0 /*addToIndex*/) // skip Related Pages section in navigation index { Doxygen::indexList.decContentsDepth(); } @@ -3445,8 +3457,12 @@ static void writeIndex(OutputList &ol) if (Doxygen::mainPage) { - Doxygen::indexList.addContentsItem(Doxygen::mainPage->hasSubPages(),title,0,indexName,0,Doxygen::mainPage->hasSubPages(),TRUE); - + if (Doxygen::mainPage->hasSubPages() || + (!Config_getString("PROJECT_NAME").isEmpty() && mainPageHasTitle()) + ) // to avoid duplicate entries in the treeview + { + Doxygen::indexList.addContentsItem(Doxygen::mainPage->hasSubPages(),title,0,indexName,0,Doxygen::mainPage->hasSubPages(),TRUE); + } if (Doxygen::mainPage->hasSubPages()) { writeSubPages(Doxygen::mainPage); diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp index dc3b4e7..3dab3ce 100644 --- a/src/latexdocvisitor.cpp +++ b/src/latexdocvisitor.cpp @@ -53,8 +53,9 @@ static const char *secLabels[maxLevels] = static const char *getSectionName(int level) { + static bool compactLatex = Config_getBool("COMPACT_LATEX"); int l = level; - if (Config_getBool("COMPACT_LATEX")) l++; + if (compactLatex) l++; if (Doxygen::insideMainPage) l--; return secLabels[QMIN(maxLevels-1,l)]; } @@ -62,10 +63,11 @@ static const char *getSectionName(int level) static int rowspan(DocHtmlCell *cell) { int retval = 0; - HtmlAttribList attrs = cell->attribs (); - for (unsigned int i = 0; i < attrs.count(); ++i) + HtmlAttribList attrs = cell->attribs(); + uint i; + for (i=0; i<attrs.count(); ++i) { - if ("rowspan" == attrs.at(i)->name.lower()) + if (attrs.at(i)->name.lower()=="rowspan") { retval = attrs.at(i)->value.toInt(); break; @@ -74,6 +76,24 @@ static int rowspan(DocHtmlCell *cell) return retval; } +static int align(DocHtmlCell *cell) +{ + HtmlAttribList attrs = cell->attribs(); + uint i; + for (i=0; i<attrs.count(); ++i) + { + if (attrs.at(i)->name.lower()=="align") + { + if (attrs.at(i)->value.lower()=="center") + return 1; + else if (attrs.at(i)->value.lower()=="right") + return 2; + else return 0; + } + } + return 0; +} + QCString LatexDocVisitor::escapeMakeIndexChars(const char *s) { QCString result; @@ -277,26 +297,19 @@ void LatexDocVisitor::visit(DocVerbatim *s) { //static bool latexSourceCode = Config_getBool("LATEX_SOURCE_CODE"); if (m_hide) return; + QCString lang = m_langExt; + if (!s->language().isEmpty()) // explicit language setting + { + lang = s->language(); + } switch(s->type()) { case DocVerbatim::Code: - //if (latexSourceCode) - //{ - // m_t << "\n\n\\begin{footnotesize}\\begin{alltt}" << endl; - //} - //else { m_t << "\n\\begin{DoxyCode}\n"; - } - Doxygen::parserManager->getParser(m_langExt) - ->parseCode(m_ci,s->context(),s->text(), - s->isExample(),s->exampleFile()); - //if (latexSourceCode) - //{ - // m_t << "\\end{alltt}\\end{footnotesize}" << endl; - //} - //else - { + Doxygen::parserManager->getParser(lang) + ->parseCode(m_ci,s->context(),s->text(), + s->isExample(),s->exampleFile()); m_t << "\\end{DoxyCode}\n"; } break; @@ -883,9 +896,10 @@ void LatexDocVisitor::visitPost(DocHtmlCaption *) m_t << "}\n"; } -void LatexDocVisitor::visitPre(DocHtmlRow *) +void LatexDocVisitor::visitPre(DocHtmlRow *r) { m_currentColumn = 0; + if (r->isHeading()) m_t << "\\rowcolor{lightgray}"; } void LatexDocVisitor::visitPost(DocHtmlRow *) @@ -896,24 +910,30 @@ void LatexDocVisitor::visitPost(DocHtmlRow *) QMap<int, int>::Iterator it; int col = 1; - for (it = m_rowspanIndices.begin(); it != m_rowspanIndices.end(); ++it) + for (it = m_rowspanIndices.begin(); it != m_rowspanIndices.end(); ++it) { it.data()--; if (it.data () <= 0) + { m_rowspanIndices.remove (it); + } else if (0 < it.data() - col) + { m_t << "\\cline{" << col << "-" << it.data() - col << "}"; - - col = 1 + it.data (); } + + col = 1 + it.data(); + } if (col <= m_currentColumn) + { m_t << "\\cline{" << col << "-" << m_currentColumn << "}"; + } m_t << "\n"; } -void LatexDocVisitor::visitPre(DocHtmlCell *cell) +void LatexDocVisitor::visitPre(DocHtmlCell *c) { if (m_hide) return; @@ -927,18 +947,35 @@ void LatexDocVisitor::visitPre(DocHtmlCell *cell) it++; } - int rs = rowspan(cell); - if (0 < rs) + int rs = rowspan(c); + if (rs>0) { m_inRowspan = TRUE; m_rowspanIndices[m_currentColumn] = rs; m_t << "\\multirow{" << rs << "}{\\linewidth}{"; } + int a = align(c); + if (a==1) + { + m_t << "\\PBS\\centering "; + } + else if (a==2) + { + m_t << "\\PBS\\raggedleft "; + } + if (c->isHeading()) + { + m_t << "{\\bf "; + } } void LatexDocVisitor::visitPost(DocHtmlCell *c) { if (m_hide) return; + if (c->isHeading()) + { + m_t << "}"; + } if (m_inRowspan) { m_inRowspan = FALSE; diff --git a/src/latexgen.cpp b/src/latexgen.cpp index 6f92f79..65ed16b 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -72,18 +72,10 @@ LatexGenerator::~LatexGenerator() { } -void LatexGenerator::init() +static void writeLatexMakefile() { bool generateBib = !Doxygen::citeDict->isEmpty(); - QCString dir=Config_getString("LATEX_OUTPUT"); - QDir d(dir); - if (!d.exists() && !d.mkdir(dir)) - { - err("Could not create output directory %s\n",dir.data()); - exit(1); - } - QCString fileName=dir+"/Makefile"; QFile file(fileName); if (!file.open(IO_WriteOnly)) @@ -182,6 +174,66 @@ void LatexGenerator::init() << "\trm -f " #endif << "*.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf" << endl; +} + +static void writeMakePdfBat() +{ +#if defined(_MSC_VER) + if (Config_getBool("USE_PDFLATEX")) // use plain old latex + { + bool generateBib = !Doxygen::citeDict->isEmpty(); + QCString mkidx_command = Config_getString("MAKEINDEX_CMD_NAME"); + QCString dir=Config_getString("LATEX_OUTPUT"); + QCString fileName=dir+"/makepdf.bat"; + QFile file(fileName); + if (!file.open(IO_WriteOnly)) + { + err("Could not open file %s for writing\n",fileName.data()); + exit(1); + } + FTextStream t(&file); + t << "del /s /f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf\n\n"; + t << "pdflatex refman\n"; + t << "echo ----\n"; + t << mkidx_command << " refman.idx\n"; + if (generateBib) + { + t << "\tbibtex refman" << endl; + t << "\tpdflatex refman" << endl; + } + t << "echo ----\n"; + t << "pdflatex refman\n\n"; + t << "setlocal enabledelayedexpansion\n"; + t << "set count=5\n"; + t << ":repeat\n"; + t << "set content=X\n"; + t << "for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun LaTeX\" refman.log' ) do set content=\"%%~T\"\n"; + t << "if !content! == X for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun to get cross-references right\" refman.log' ) do set content=\"%%~T\"\n"; + t << "if !content! == X goto :skip\n"; + t << "set /a count-=1\n"; + t << "if !count! EQU 0 goto :skip\n\n"; + t << "echo ----\n"; + t << "pdflatex refman\n"; + t << "goto :repeat\n"; + t << ":skip\n"; + t << "endlocal\n"; + } +#endif +} + +void LatexGenerator::init() +{ + + QCString dir=Config_getString("LATEX_OUTPUT"); + QDir d(dir); + if (!d.exists() && !d.mkdir(dir)) + { + err("Could not create output directory %s\n",dir.data()); + exit(1); + } + + writeLatexMakefile(); + writeMakePdfBat(); createSubDirs(d); } @@ -345,6 +397,7 @@ static void writeDefaultStyleSheetPart1(FTextStream &t) "\\RequirePackage{longtable}\n" "\\RequirePackage{verbatim}\n" "\\RequirePackage{ifthen}\n" + "\\RequirePackage{xtab}\n" "\\RequirePackage[table]{xcolor}\n\n"; t << "% Use helvetica font instead of times roman\n" @@ -788,10 +841,10 @@ static void writeDefaultStyleSheetPart3(FTextStream &t) t << "{\n"; t << "\\setlength{\\tmplength}\n"; t << " {\\linewidth/(#1)-\\tabcolsep*2-\\arrayrulewidth*(#1+1)/(#1)}\n"; - t << " \\par\\begin{tabular*}{\\linewidth}\n"; + t << " \\par\\begin{xtabular*}{\\linewidth}\n"; t << " {*{#1}{|>{\\PBS\\raggedright\\hspace{0pt}}p{\\the\\tmplength}}|}\n"; t << "}\n"; - t << "{\\end{tabular*}\\par}\n"; + t << "{\\end{xtabular*}\\par}\n"; t << "\\newcommand{\\entrylabel}[1]{\n"; t << " {\\parbox[b]{\\labelwidth-4pt}{\\makebox[0pt][l]{%\n"; t << " \\usefont{OT1}{phv}{bc}{n}\\color{darkgray}#1}\\vspace{1.5\\baselineskip}}}}\n"; diff --git a/src/markdown.cpp b/src/markdown.cpp index 42b5bee..95cf3c1 100644 --- a/src/markdown.cpp +++ b/src/markdown.cpp @@ -43,6 +43,14 @@ #include "util.h" #include "doxygen.h" #include "commentscan.h" +#include "entry.h" + +//----------- + +#define isIdChar(i) \ + ((data[(i)]>='a' && data[(i)]<='z') || \ + (data[(i)]>='A' && data[(i)]<='Z') || \ + (data[(i)]>='0' && data[(i)]<='9')) \ //---------- @@ -62,6 +70,8 @@ enum Alignment { AlignNone, AlignLeft, AlignCenter, AlignRight }; static QDict<LinkRef> g_linkRefs(257); static action_t g_actions[256]; +static Entry *g_current; +static QCString g_fileName; //static QDict<void> g_htmlBlockTags(17); //---------- @@ -206,11 +216,7 @@ static int findEmphasisChar(const char *data, int size, char c) if (data[i] == c) { - if (i<size-1 && ((data[i+1]>='a' && data[i+1]<='z') || - (data[i+1]>='A' && data[i+1]<='Z') || - (data[i+1]>='0' && data[i+1]<='9') - ) - ) // to prevent touching some_underscore_identifier + if (i<size-1 && isIdChar(i+1)) // to prevent touching some_underscore_identifier { i++; continue; @@ -397,11 +403,110 @@ static int processEmphasis3(GrowBuf &out, const char *data, int size, char c) return 0; } -static int processEmphasis(GrowBuf &out,const char *data,int,int size) +static int processHtmlTag(GrowBuf &out,const char *data,int offset,int size) { + if (offset>0 && data[-1]=='\\') return 0; // escaped < + + // find the end of the html tag + int i=1; + int l=0; + // compute length of the tag name + while (i<size && isIdChar(i)) i++,l++; + QCString tagName; + convertStringFragment(tagName,data+1,i-1); + if (tagName.lower()=="pre") // found <pre> tag + { + bool insideStr=FALSE; + while (i<size-6) + { + char c=data[i]; + if (!insideStr && c=='<') // potential start of html tag + { + if (data[i+1]=='/' && + tolower(data[i+2])=='p' && tolower(data[i+3])=='r' && + tolower(data[i+4])=='e' && tolower(data[i+5])=='>') + { // found </pre> tag, copy from start to end of tag + out.addStr(data,i+6); + //printf("found <pre>..</pre> [%d..%d]\n",0,i+6); + return i+6; + } + } + else if (insideStr && c=='"') + { + if (data[i-1]!='\\') insideStr=FALSE; + } + else if (c=='"') + { + insideStr=TRUE; + } + i++; + } + } + else // some other html tag + { + if (l>0 && i<size) + { + if (data[i]=='/' && i<size-1 && data[i+1]=='>') // <bla/> + { + //printf("Found htmlTag={%s}\n",QCString(data).left(i+2).data()); + out.addStr(data,i+2); + return i+2; + } + else if (data[i]=='>') // <bla> + { + //printf("Found htmlTag={%s}\n",QCString(data).left(i+1).data()); + out.addStr(data,i+1); + return i+1; + } + else if (data[i]==' ') // <bla attr=... + { + i++; + bool insideAttr=FALSE; + while (i<size) + { + if (!insideAttr && data[i]=='"') + { + insideAttr=TRUE; + } + else if (data[i]=='"' && data[i-1]!='\\') + { + insideAttr=FALSE; + } + else if (!insideAttr && data[i]=='>') // found end of tag + { + //printf("Found htmlTag={%s}\n",QCString(data).left(i+1).data()); + out.addStr(data,i+1); + return i+1; + } + i++; + } + } + } + } + //printf("Not a valid html tag\n"); + return 0; +} + +static int processEmphasis(GrowBuf &out,const char *data,int offset,int size) +{ + if (offset>0 && size>1 && (isIdChar(-1) || data[-1]==data[0])) + { + if (isIdChar(1) || data[-1]==data[0]) + { + // avoid processing interal * and _ as cmd_id, or 4*10 as emphasis, + // also x**2,y*2 should not be processed + return 0; + } + else if (size>2 && data[0]==data[1] && isIdChar(2)) + { + // avoid processing interal ** and __ such as cmd__id__bla, + // or 4**10,5**10 as emphasis + return 0; + } + } char c = data[0]; - size_t ret; - if (size>2 && data[1]!=c) + int ret; + if (size>2 && data[1]!=c) // _bla or *bla { // whitespace cannot follow an opening emphasis if (data[1]==' ' || data[1]=='\n' || @@ -411,7 +516,7 @@ static int processEmphasis(GrowBuf &out,const char *data,int,int size) } return ret+1; } - if (size>3 && data[1]==c && data[2]!=c) + if (size>3 && data[1]==c && data[2]!=c) // __bla or **bla { if (data[2]==' ' || data[2]=='\n' || (ret = processEmphasis2(out, data+2, size-2, c)) == 0) @@ -420,7 +525,7 @@ static int processEmphasis(GrowBuf &out,const char *data,int,int size) } return ret+2; } - if (size>4 && data[1]==c && data[2]==c && data[3]!=c) + if (size>4 && data[1]==c && data[2]==c && data[3]!=c) // ___bla or ***bla { if (data[3]==' ' || data[3]=='\n' || (ret = processEmphasis3(out, data+3, size-3, c)) == 0) @@ -478,7 +583,7 @@ static int processLink(GrowBuf &out,const char *data,int,int size) contentEnd=i; convertStringFragment(content,data+contentStart,contentEnd-contentStart); //printf("processLink: content={%s}\n",content.data()); - if (content.isEmpty()) return 0; // no link text + if (!isImageLink && content.isEmpty()) return 0; // no link text i++; // skip over ] // skip whitespace @@ -588,7 +693,7 @@ static int processLink(GrowBuf &out,const char *data,int,int size) } i++; } - else if (i<size && data[i]!=':') // minimal link ref notation [some id] + else if (i<size && data[i]!=':' && !content.isEmpty()) // minimal link ref notation [some id] { LinkRef *lr = g_linkRefs.find(content.lower()); //printf("processLink: minimal link {%s} lr=%p",content.data(),lr); @@ -609,28 +714,33 @@ static int processLink(GrowBuf &out,const char *data,int,int size) { return 0; } - if (isImageLink) // TODO: use @image? + static QRegExp re("^[@\\]ref "); + if (isImageLink) { - out.addStr("<img src=\""); - out.addStr(link); - out.addStr("\" alt=\""); - out.addStr(content); - out.addStr("\""); - if (!title.isEmpty()) + if (link.find("@ref ")!=-1 || link.find("\\ref ")!=-1) + // assume doxygen symbol link { - out.addStr(" title=\""); - out.addStr(substitute(title.simplifyWhiteSpace(),"\"",""")); - out.addStr("\""); + out.addStr("@image html "); + out.addStr(link.mid(5)); + if (!explicitTitle && !content.isEmpty()) + { + out.addStr(" \""); + out.addStr(content); + out.addStr("\""); + } + else if ((content.isEmpty() || explicitTitle) && !title.isEmpty()) + { + out.addStr(" \""); + out.addStr(title); + out.addStr("\""); + } } - out.addStr("/>"); - } - else - { - static QRegExp re("^[@\\]ref "); - if (link.find('/')!=-1) // file/url link + else { - out.addStr("<a href=\""); + out.addStr("<img src=\""); out.addStr(link); + out.addStr("\" alt=\""); + out.addStr(content); out.addStr("\""); if (!title.isEmpty()) { @@ -638,11 +748,12 @@ static int processLink(GrowBuf &out,const char *data,int,int size) out.addStr(substitute(title.simplifyWhiteSpace(),"\"",""")); out.addStr("\""); } - out.addStr(">"); - out.addStr(content.simplifyWhiteSpace()); - out.addStr("</a>"); + out.addStr("/>"); } - else if (link.find("@ref ")!=-1 || link.find("\\ref ")!=-1) + } + else + { + if (link.find("@ref ")!=-1 || link.find("\\ref ")!=-1) // assume doxygen symbol link { out.addStr(link); @@ -657,7 +768,22 @@ static int processLink(GrowBuf &out,const char *data,int,int size) } out.addStr("\""); } - else // avoid link to F[x](y) + else if (link.find('/')!=-1 || link.find('.')!=-1 || link.find('#')!=-1) + { // file/url link + out.addStr("<a href=\""); + out.addStr(link); + out.addStr("\""); + if (!title.isEmpty()) + { + out.addStr(" title=\""); + out.addStr(substitute(title.simplifyWhiteSpace(),"\"",""")); + out.addStr("\""); + } + out.addStr(">"); + out.addStr(content.simplifyWhiteSpace()); + out.addStr("</a>"); + } + else // avoid link to e.g. F[x](y) { //printf("no link for '%s'\n",link.data()); return 0; @@ -722,17 +848,14 @@ static int processCodeSpan(GrowBuf &out, const char *data, int /*offset*/, int s i=f_begin; while (i<f_end-1) { - if (data[i]=='\'' && !((data[i+1]>='a' && data[i+1]<='z') || - (data[i+1]>='A' && data[i+1]<='Z') || - (data[i+1]>='0' && data[i+1]<='9') - )) // reject `some word' and not `it's cool` + if (data[i]=='\'' && !isIdChar(i+1)) // reject `some word' and not `it's cool` { return 0; } i++; } } - printf("found code span '%s'\n",QCString(data+f_begin).left(f_end-f_begin).data()); + //printf("found code span '%s'\n",QCString(data+f_begin).left(f_end-f_begin).data()); /* real code span */ if (f_begin < f_end) @@ -783,28 +906,6 @@ static int processSpecialCommand(GrowBuf &out, const char *data, int offset, int return 0; } -#if 0 -static int processHtmlBlock(GrowBuf &out, const char *data, int offset, int size) -{ - if (size<2 || data[0]!='<') return 0; - int i=1; - while (i<size && ((data[i]>='0' && data[i]<='9') || - (data[i]>='A' && data[i]<='Z') || - (data[i]>='a' && data[i]<='z'))) i++; - if (i<=1 || i>=size) return 0; - QCString tagName; - convertStringFragment(tagName,data+1,i-1); - printf("found html tag '%s'\n",tagName.data()); - if (g_htmlBlockTags.find(tagName)!=0) - { - printf("found block tag\n"); - - // search for end of the block... - } - return 0; -} -#endif - static void processInline(GrowBuf &out,const char *data,int size) { int i=0, end=0; @@ -856,7 +957,24 @@ static bool isBlockQuote(const char *data,int size,int indent) { int i = 0; while (i<size && data[i]==' ') i++; - return i<size && data[i]=='>' && i<indent+codeBlockIndent; + if (i<indent+codeBlockIndent) // could be a quotation + { + // count >'s and skip spaces + int level=0; + while (i<size && (data[i]=='>' || data[i]==' ')) + { + if (data[i]=='>') level++; + i++; + } + // last characters should be a space or newline, + // so a line starting with >= does not match + return level>0 && i<size && ((data[i-1]==' ') || data[i]=='\n'); + } + else // too much indentation -> code block + { + return FALSE; + } + //return i<size && data[i]=='>' && i<indent+codeBlockIndent; } /** returns end of the link ref if this is indeed a link reference. */ @@ -979,7 +1097,7 @@ static int isHRuler(const char *data,int size) static QCString extractTitleId(QCString &title) { - static QRegExp r1("^[a-z_A-Z][a-z_A-Z0-9\\-]*:"); + //static QRegExp r1("^[a-z_A-Z][a-z_A-Z0-9\\-]*:"); static QRegExp r2("\\{#[a-z_A-Z][a-z_A-Z0-9\\-]*\\}$"); int l=0; int i = r2.match(title,0,&l); @@ -990,20 +1108,21 @@ static QCString extractTitleId(QCString &title) //printf("found id='%s' title='%s'\n",id.data(),title.data()); return id; } - i = r1.match(title,0,&l); - if (i!=-1) // found id: style id - { - QCString id = title.mid(i,l-1); - title = title.left(i)+title.mid(i+l); - //printf("found id='%s' title='%s'\n",id.data(),title.data()); - return id; - } + //i = r1.match(title,0,&l); + //if (i!=-1) // found id: style id + //{ + // QCString id = title.mid(i,l-1); + // title = title.left(i)+title.mid(i+l); + // //printf("found id='%s' title='%s'\n",id.data(),title.data()); + // return id; + //} //printf("no id found in title '%s'\n",title.data()); return ""; } -static int isAtxHeader(const char *data,int size,QCString &header) +static int isAtxHeader(const char *data,int size, + QCString &header,QCString &id) { int i = 0, end; int level = 0; @@ -1021,6 +1140,13 @@ static int isAtxHeader(const char *data,int size,QCString &header) // store result convertStringFragment(header,data+i,end-i); + id = extractTitleId(header); + if (!id.isEmpty()) // strip #'s between title and id + { + i=header.length()-1; + while (i>=0 && header.at(i)=='#' || header.at(i)==' ') i--; + header=header.left(i+1); + } return level; } @@ -1037,19 +1163,29 @@ static int isEmptyLine(const char *data,int size) return TRUE; } +#define isLiTag(i) \ + (data[(i)]=='<' && \ + (data[(i)+1]=='l' || data[(i)+1]=='L') && \ + (data[(i)+2]=='i' || data[(i)+2]=='I') && \ + (data[(i)+3]=='>')) + // compute the indent from the start of the input, excluding list markers -// such as -, *, +, and 1. +// such as -, -#, *, +, 1., and <li> static int computeIndentExcludingListMarkers(const char *data,int size) { int i=0; int indent=0; bool isDigit=FALSE; + bool isLi=FALSE; bool listMarkerSkipped=FALSE; while (i<size && (data[i]==' ' || // space (!listMarkerSkipped && // first list marker (data[i]=='+' || data[i]=='-' || data[i]=='*' || // unordered list char - (isDigit=(data[i]>='1' && data[i]<='9'))) // ordered list marker? + (data[i]=='#' && i>0 && data[i-1]=='-') || // -# item + (isDigit=(data[i]>='1' && data[i]<='9')) || // ordered list marker? + (isLi=(i<size-3 && isLiTag(i))) // <li> tag + ) ) ) ) @@ -1076,12 +1212,24 @@ static int computeIndentExcludingListMarkers(const char *data,int size) j++; } } - else if (data[i]!=' ' && i<size-1 && data[i+1]==' ') + else if (isLi) { + i+=3; // skip over <li> + indent+=3; + listMarkerSkipped=TRUE; + } + else if (data[i]=='-' && i<size-2 && data[i+1]=='#' && data[i+2]==' ') + { // case "-# " + listMarkerSkipped=TRUE; // only a single list marker is accepted + i++; // skip over # + indent++; + } + else if (data[i]!=' ' && i<size-1 && data[i+1]==' ') + { // case "- " or "+ " or "* " listMarkerSkipped=TRUE; // only a single list marker is accepted } if (data[i]!=' ' && !listMarkerSkipped) - { + { // end of indent break; } indent++,i++; @@ -1090,6 +1238,44 @@ static int computeIndentExcludingListMarkers(const char *data,int size) return indent; } +static bool isFencedCodeBlock(const char *data,int size,int refIndent, + QCString &lang,int &start,int &end,int &offset) +{ + // TODO: implement me... + // rules: at least 3 ~~~, end of the block same amount of ~~~'s, otherwise + // return FALSE + int i=0; + int indent=0; + int startTildes=0; + while (i<size && data[i]==' ') indent++,i++; + if (indent>=refIndent+4) return FALSE; // part of code block + while (i<size && data[i]=='~') startTildes++,i++; + if (startTildes<3) return FALSE; // not enough tildes + if (i<size && data[i]=='{') i++; // skip over optional { + int startLang=i; + while (i<size && (data[i]!='\n' && data[i]!='}' && data[i]!=' ')) i++; + convertStringFragment(lang,data+startLang,i-startLang); + while (i<size && data[i]!='\n') i++; // proceed to the end of the line + start=i; + while (i<size) + { + if (data[i]=='~') + { + end=i-1; + int endTildes=0; + while (i<size && data[i]=='~') endTildes++,i++; + while (i<size && data[i]==' ') i++; + if (i==size || data[i]=='\n') + { + offset=i; + return endTildes==startTildes; + } + } + i++; + } + return FALSE; +} + static bool isCodeBlock(const char *data,int offset,int size,int &indent) { //printf("<isCodeBlock(offset=%d,size=%d,indent=%d)\n",offset,size,indent); @@ -1244,16 +1430,9 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size) // write table header, in range [start..end] out.addStr("<tr>"); - j=start; - for (k=0;k<columns;k++) - { - out.addStr("<th>"); - while (j<=end && (data[j]!='|' || (j>0 && data[j-1]=='\\'))) - { - out.addChar(data[j++]); - } - j++; - } + + int headerStart = start; + int headerEnd = end; // read cell alignments int ret = findTableColumns(data+i,size-i,start,end,cc); @@ -1295,6 +1474,25 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size) // proceed to next line i+=ret; + int m=headerStart; + for (k=0;k<columns;k++) + { + out.addStr("<th"); + switch (columnAlignment[k]) + { + case AlignLeft: out.addStr(" align=left"); break; + case AlignRight: out.addStr(" align=right"); break; + case AlignCenter: out.addStr(" align=center"); break; + case AlignNone: break; + } + out.addStr(">"); + while (m<=headerEnd && (data[m]!='|' || (m>0 && data[m-1]=='\\'))) + { + out.addChar(data[m++]); + } + m++; + } + // write table cells while (i<size) { @@ -1348,17 +1546,44 @@ void writeOneLineHeaderOrRuler(GrowBuf &out,const char *data,int size) { int level; QCString header; + QCString id; if (isHRuler(data,size)) { out.addStr("<hr>\n"); } - else if ((level=isAtxHeader(data,size,header))) + else if ((level=isAtxHeader(data,size,header,id))) { QCString hTag; - hTag.sprintf("h%d",level); - out.addStr("<"+hTag+">"); - out.addStr(header); - out.addStr("</"+hTag+">\n"); + if (level<5 && !id.isEmpty()) + { + switch(level) + { + case 1: out.addStr("@section "); break; + case 2: out.addStr("@subsection "); break; + case 3: out.addStr("@subsubsection "); break; + default: out.addStr("@paragraph "); break; + } + out.addStr(id); + out.addStr(" "); + out.addStr(header); + SectionInfo *si = new SectionInfo(g_fileName,id,header,SectionInfo::Anchor,level); + if (g_current) + { + g_current->anchors->append(si); + } + Doxygen::sectionDict.append(header,si); + } + else + { + if (!id.isEmpty()) + { + out.addStr("\\anchor "+id+"\n"); + } + hTag.sprintf("h%d",level); + out.addStr("<"+hTag+">"); + out.addStr(header); + out.addStr("</"+hTag+">\n"); + } } else // nothing interesting -> just output the line { @@ -1387,6 +1612,11 @@ static int writeBlockQuote(GrowBuf &out,const char *data,int size) else if (j>0 && data[j-1]=='>') indent=j+1; j++; } + if (j>0 && data[j-1]=='>') // disqualify last > if not followed by space + { + indent--; + j--; + } if (level>curLevel) // quote level increased => add start markers { for (l=curLevel;l<level;l++) @@ -1458,11 +1688,12 @@ static void findEndOfLine(GrowBuf &out,const char *data,int size, int &pi,int&i,int &end) { // find end of the line + int nb=0; for (end=i+1; end<size && data[end-1]!='\n'; end++) { // while looking for the end of the line we might encounter a block // that needs to be passed unprocessed. - if ((data[end-1]=='\\' || data[end-1]=='@') && // command + if ((data[end-1]=='\\' || data[end-1]=='@') && // command (end<=1 || (data[end-2]!='\\' && data[end-2]!='@')) // not escaped ) { @@ -1493,6 +1724,36 @@ static void findEndOfLine(GrowBuf &out,const char *data,int size, } } } + else if (nb==0 && data[end-1]=='<' && end<size-6 && + (end<=1 || (data[end-2]!='\\' && data[end-2]!='@')) + ) + { + if (tolower(data[end])=='p' && tolower(data[end+1])=='r' && + tolower(data[end+2])=='e' && data[end+3]=='>') // <pre> tag + { + if (pi!=-1) // output previous line if available + { + out.addStr(data+pi,i-pi); + } + // output part until <pre> + out.addStr(data+i,end-1-i); + // output part until </pre> + i = end-1 + processHtmlTag(out,data+end-1,end-1,size-end+1); + pi=-1; + end = i+1; + break; + } + } + else if (nb==0 && data[end-1]=='`') + { + while (end<size && data[end-1]=='`') end++,nb++; + } + else if (nb>0 && data[end-1]=='`') + { + int enb=0; + while (end<size && data[end-1]=='`') end++,enb++; + if (enb==nb) nb=0; + } } } @@ -1578,17 +1839,38 @@ static QCString processBlocks(const QCString &s,int indent) if (pi!=-1) { + int blockStart,blockEnd,blockOffset; + QCString lang; blockIndent = indent; //printf("isHeaderLine(%s)=%d\n",QCString(data+i).left(size-i).data(),level); if ((level=isHeaderline(data+i,size-i))>0) { //printf("Found header at %d-%d\n",i,end); while (pi<size && data[pi]==' ') pi++; - if (i-pi>1) + QCString header,id; + convertStringFragment(header,data+pi,i-pi-1); + id = extractTitleId(header); + if (!header.isEmpty()) { - out.addStr(level==1?"<h1>":"<h2>"); - out.addStr(data+pi,i-pi-1); - out.addStr(level==1?"</h1>\n":"</h2>\n"); + if (!id.isEmpty()) + { + out.addStr(level==1?"@section ":"@subsection "); + out.addStr(id); + out.addStr(" "); + out.addStr(header); + SectionInfo *si = new SectionInfo(g_fileName,id,header,SectionInfo::Anchor,level); + if (g_current) + { + g_current->anchors->append(si); + } + Doxygen::sectionDict.append(header,si); + } + else + { + out.addStr(level==1?"<h1>":"<h2>"); + out.addStr(header); + out.addStr(level==1?"</h1>\n":"</h2>\n"); + } } else { @@ -1608,6 +1890,23 @@ static QCString processBlocks(const QCString &s,int indent) pi=-1; end=i+1; } + else if (isFencedCodeBlock(data+pi,size-pi,indent,lang,blockStart,blockEnd,blockOffset)) + { + //printf("Found FencedCodeBlock lang='%s' start=%d end=%d code={%s}\n", + // lang.data(),blockStart,blockEnd,QCString(data+pi+blockStart).left(blockEnd-blockStart).data()); + out.addStr("@code"); + if (!lang.isEmpty() && lang.at(0)=='.') lang=lang.mid(1); + if (!lang.isEmpty()) + { + out.addStr("{"+lang+"}"); + } + out.addStr(data+pi+blockStart,blockEnd-blockStart); + out.addStr("\n@endcode"); + i=pi+blockOffset; + pi=-1; + end=i+1; + continue; + } else if (isCodeBlock(data+i,i,end-i,blockIndent)) //if (isCodeBlock(data+pi,pi,end-pi,blockIndent)) { @@ -1651,7 +1950,7 @@ static QCString processBlocks(const QCString &s,int indent) return out.get(); } -static QCString extractPageTitle(QCString &docs) +static QCString extractPageTitle(QCString &docs,QCString &id) { // first first non-empty line QCString title; @@ -1671,16 +1970,19 @@ static QCString extractPageTitle(QCString &docs) while (end2<size && data[end2-1]!='\n') end2++; if (isHeaderline(data+end1,size-end1)) { - convertStringFragment(title,data+i,end1-i); + convertStringFragment(title,data+i,end1-i-1); docs=docs.mid(end2); + id = extractTitleId(title); + //printf("extractPageTitle(title='%s' docs='%s' id='%s')\n",title.data(),docs.data(),id.data()); return title; } } - if (i<end1 && isAtxHeader(data+i,end1-i,title)>0) + if (i<end1 && isAtxHeader(data+i,end1-i,title,id)>0) { docs=docs.mid(end1); } - //printf("extractPageTitle(title='%s' docs='%s')\n",title.data(),docs.data()); + id = extractTitleId(title); + //printf("extractPageTitle(title='%s' docs='%s' id='%s')\n",title.data(),docs.data(),id.data()); return title; } @@ -1727,36 +2029,12 @@ static QCString detab(const QCString &s,int &refIndent) //--------------------------------------------------------------------------- -QCString processMarkdown(const QCString &input) +QCString processMarkdown(const QCString &fileName,Entry *e,const QCString &input) { -#if 0 - static bool g_init = FALSE; - if (!g_init) - { - g_htmlBlockTags.insert("p",(void*)0x8); - g_htmlBlockTags.insert("dl",(void*)0x8); - g_htmlBlockTags.insert("h1",(void*)0x8); - g_htmlBlockTags.insert("h2",(void*)0x8); - g_htmlBlockTags.insert("h3",(void*)0x8); - g_htmlBlockTags.insert("h4",(void*)0x8); - g_htmlBlockTags.insert("h5",(void*)0x8); - g_htmlBlockTags.insert("h6",(void*)0x8); - g_htmlBlockTags.insert("ol",(void*)0x8); - g_htmlBlockTags.insert("ul",(void*)0x8); - g_htmlBlockTags.insert("div",(void*)0x8); - g_htmlBlockTags.insert("pre",(void*)0x8); - g_htmlBlockTags.insert("form",(void*)0x8); - g_htmlBlockTags.insert("math",(void*)0x8); - g_htmlBlockTags.insert("table",(void*)0x8); - g_htmlBlockTags.insert("iframe",(void*)0x8); - g_htmlBlockTags.insert("script",(void*)0x8); - g_htmlBlockTags.insert("fieldset",(void*)0x8); - g_htmlBlockTags.insert("noscript",(void*)0x8); - g_init=TRUE; - } -#endif g_linkRefs.setAutoDelete(TRUE); g_linkRefs.clear(); + g_current = e; + g_fileName = fileName; static GrowBuf out; if (input.isEmpty()) return input; out.clear(); @@ -1777,7 +2055,7 @@ QCString processMarkdown(const QCString &input) g_actions['@']=processSpecialCommand; g_actions['[']=processLink; g_actions['!']=processLink; - //g_actions['<']=processHtmlBlock; + g_actions['<']=processHtmlTag; // finally process the inline markup (links, emphasis and code spans) processInline(out,s,size); out.addChar(0); @@ -1794,10 +2072,11 @@ void MarkdownFileParser::parseInput(const char *fileName, Entry *current = new Entry; current->lang = SrcLangExt_Markdown; QCString docs = fileBuf; - QCString title=extractPageTitle(docs).stripWhiteSpace(); - QCString id=extractTitleId(title); + QCString id; + QCString title=extractPageTitle(docs,id).stripWhiteSpace(); QCString baseName = substitute(QFileInfo(fileName).baseName().utf8()," ","_"); if (id.isEmpty()) id = "md_"+baseName; + if (title.isEmpty()) title = baseName; if (id=="mainpage" || id=="index") { docs.prepend("@mainpage "+title+"\n"); diff --git a/src/markdown.h b/src/markdown.h index 616c01e..885d659 100644 --- a/src/markdown.h +++ b/src/markdown.h @@ -19,8 +19,10 @@ #include <qcstring.h> #include "parserintf.h" +class Entry; + /** processes string \a s and converts markdown into doxygen/html commands. */ -QCString processMarkdown(const QCString &s); +QCString processMarkdown(const QCString &fileName,Entry *e,const QCString &s); class MarkdownFileParser : public ParserInterface { diff --git a/src/marshal.cpp b/src/marshal.cpp index 0675277..d366c57 100644 --- a/src/marshal.cpp +++ b/src/marshal.cpp @@ -157,6 +157,7 @@ void marshalSectionInfoList(StorageIntf *s, QList<SectionInfo> *anchors) marshalQCString(s,si->ref); marshalInt(s,(int)si->type); marshalQCString(s,si->fileName); + marshalInt(s,si->level); } } } @@ -195,7 +196,7 @@ void marshalSectionDict(StorageIntf *s,SectionDict *sections) else { marshalUInt(s,sections->count()); - QDictIterator<SectionInfo> sli(*sections); + SDict<SectionInfo>::IteratorDict sli(*sections); SectionInfo *si; for (sli.toFirst();(si=sli.current());++sli) { @@ -576,7 +577,8 @@ QList<SectionInfo> *unmarshalSectionInfoList(StorageIntf *s) QCString ref = unmarshalQCString(s); SectionInfo::SectionType type = (SectionInfo::SectionType)unmarshalInt(s); QCString fileName = unmarshalQCString(s); - result->append(new SectionInfo(fileName,label,title,type,ref)); + int level = unmarshalInt(s); + result->append(new SectionInfo(fileName,label,title,type,level,ref)); } return result; } @@ -619,7 +621,7 @@ SectionDict *unmarshalSectionDict(StorageIntf *s) QCString key = unmarshalQCString(s); SectionInfo *si = (SectionInfo *)unmarshalObjPointer(s); //printf(" unmarshalSectionDict i=%d key=%s si=%s\n",count,key.data(),si->label.data()); - result->insert(key,si); + result->append(key,si); } return result; } diff --git a/src/navtree.js b/src/navtree.js index b0c4936..eb18215 100644 --- a/src/navtree.js +++ b/src/navtree.js @@ -210,6 +210,21 @@ function expandNode(o, node, imm, showRoot) } } +function highlightAnchor() +{ + var anchor = $($(location).attr('hash')); + if (anchor.parent().attr('class')=='memItemLeft'){ + var rows = $('.memberdecls tr[class$=\""'+ + window.location.hash.substring(1)+'"\"]').children(); + rows.effect('highlight',{},1500); + } else if (anchor.parent().is(":header")) { + anchor.parent().effect('highlight',{},1500); + } else { + var targetDiv = anchor.next(); + $(targetDiv).children('.memproto,.memdoc').effect("highlight",{},1500); + } +} + function showNode(o, node, index) { if (node.childrenData && !node.expanded) { @@ -249,15 +264,12 @@ function showNode(o, node, index) if ($(location).attr('hash')) { var link=stripPath($(location).attr('pathname'))+':'+ $(location).attr('hash').substring(1); - a=$('.item a[class*=\""'+link+'"\"]'); + a=$('.item a[class$=\""'+link+'"\"]'); } if (a && a.length) { a.parent().parent().addClass('selected'); a.parent().parent().attr('id','selected'); - var anchor = $($(location).attr('hash')); - var targetDiv = anchor.next(); - $(targetDiv).children('.memproto,.memdoc'). - effect("highlight", {}, 1500); + highlightAnchor(); } else { $(n.itemDiv).addClass('selected'); $(n.itemDiv).attr('id','selected'); @@ -302,7 +314,8 @@ function initNavTree(toroot,relpath) getScript(relpath+"navtreeindex",function(){ var navTreeIndex = eval('NAVTREEINDEX'); if (navTreeIndex) { - o.breadcrumbs = navTreeIndex[toroot]; + var nti = navTreeIndex[toroot+window.location.hash]; + o.breadcrumbs = nti ? nti : navTreeIndex[toroot]; if (o.breadcrumbs==null) o.breadcrumbs = navTreeIndex["index.html"]; o.breadcrumbs.unshift(0); showNode(o, o.node, 0); @@ -311,20 +324,12 @@ function initNavTree(toroot,relpath) $(window).bind('hashchange', function(){ if (window.location.hash && window.location.hash.length>1){ - var anchor = $(window.location.hash); - if (anchor.parent().attr('class')=='memItemLeft'){ - var rows = $('.memberdecls tr[class$=\""'+ - window.location.hash.substring(1)+'"\"]').children(); - rows.effect('highlight',{},1500); - } else { - var targetDiv = anchor.next(); - $(targetDiv).children('.memproto,.memdoc').effect("highlight",{},1500); - } + highlightAnchor(); var a; if ($(location).attr('hash')){ var link=stripPath($(location).attr('pathname'))+':'+ $(location).attr('hash').substring(1); - a=$('.item a[class*=\""'+link+'"\"]'); + a=$('.item a[class$=\""'+link+'"\"]'); } if (a && a.length){ $('.item').removeClass('selected'); diff --git a/src/navtree_js.h b/src/navtree_js.h index c231b6b..63c104b 100644 --- a/src/navtree_js.h +++ b/src/navtree_js.h @@ -210,6 +210,21 @@ " }\n" "}\n" "\n" +"function highlightAnchor()\n" +"{\n" +" var anchor = $($(location).attr('hash'));\n" +" if (anchor.parent().attr('class')=='memItemLeft'){\n" +" var rows = $('.memberdecls tr[class$=\\\"\"'+\n" +" window.location.hash.substring(1)+'\"\\\"]').children();\n" +" rows.effect('highlight',{},1500);\n" +" } else if (anchor.parent().is(\":header\")) {\n" +" anchor.parent().effect('highlight',{},1500);\n" +" } else {\n" +" var targetDiv = anchor.next();\n" +" $(targetDiv).children('.memproto,.memdoc').effect(\"highlight\",{},1500);\n" +" }\n" +"}\n" +"\n" "function showNode(o, node, index)\n" "{\n" " if (node.childrenData && !node.expanded) {\n" @@ -249,15 +264,12 @@ " if ($(location).attr('hash')) {\n" " var link=stripPath($(location).attr('pathname'))+':'+\n" " $(location).attr('hash').substring(1);\n" -" a=$('.item a[class*=\\\"\"'+link+'\"\\\"]');\n" +" a=$('.item a[class$=\\\"\"'+link+'\"\\\"]');\n" " }\n" " if (a && a.length) {\n" " a.parent().parent().addClass('selected');\n" " a.parent().parent().attr('id','selected');\n" -" var anchor = $($(location).attr('hash'));\n" -" var targetDiv = anchor.next();\n" -" $(targetDiv).children('.memproto,.memdoc').\n" -" effect(\"highlight\", {}, 1500);\n" +" highlightAnchor();\n" " } else {\n" " $(n.itemDiv).addClass('selected');\n" " $(n.itemDiv).attr('id','selected');\n" @@ -302,7 +314,8 @@ " getScript(relpath+\"navtreeindex\",function(){\n" " var navTreeIndex = eval('NAVTREEINDEX');\n" " if (navTreeIndex) {\n" -" o.breadcrumbs = navTreeIndex[toroot];\n" +" var nti = navTreeIndex[toroot+window.location.hash];\n" +" o.breadcrumbs = nti ? nti : navTreeIndex[toroot];\n" " if (o.breadcrumbs==null) o.breadcrumbs = navTreeIndex[\"index.html\"];\n" " o.breadcrumbs.unshift(0);\n" " showNode(o, o.node, 0);\n" @@ -311,20 +324,12 @@ "\n" " $(window).bind('hashchange', function(){\n" " if (window.location.hash && window.location.hash.length>1){\n" -" var anchor = $(window.location.hash);\n" -" if (anchor.parent().attr('class')=='memItemLeft'){\n" -" var rows = $('.memberdecls tr[class$=\\\"\"'+\n" -" window.location.hash.substring(1)+'\"\\\"]').children();\n" -" rows.effect('highlight',{},1500);\n" -" } else {\n" -" var targetDiv = anchor.next();\n" -" $(targetDiv).children('.memproto,.memdoc').effect(\"highlight\",{},1500);\n" -" }\n" +" highlightAnchor();\n" " var a;\n" " if ($(location).attr('hash')){\n" " var link=stripPath($(location).attr('pathname'))+':'+\n" " $(location).attr('hash').substring(1);\n" -" a=$('.item a[class*=\\\"\"'+link+'\"\\\"]');\n" +" a=$('.item a[class$=\\\"\"'+link+'\"\\\"]');\n" " }\n" " if (a && a.length){\n" " $('.item').removeClass('selected');\n" diff --git a/src/parserintf.h b/src/parserintf.h index 6e79162..2e5397e 100644 --- a/src/parserintf.h +++ b/src/parserintf.h @@ -120,8 +120,8 @@ class ParserManager * @param[in] name A symbolic name of the parser, i.e. "c", * "python", "fortran", "vhdl", ... * @param[in] parser The parser that is to be used for the - * given extension. - * @param[in] defParser Use this parser as the default parser, using + * given name. + * @param[in] defParser Use this parser as the default parser, used * for unregistered file extensions. */ void registerParser(const char *name,ParserInterface *parser,bool defParser=FALSE) diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp index 4923bb1..e49a8ed 100644 --- a/src/rtfdocvisitor.cpp +++ b/src/rtfdocvisitor.cpp @@ -328,13 +328,18 @@ void RTFDocVisitor::visit(DocVerbatim *s) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visit(DocVerbatim)}\n"); + QCString lang = m_langExt; + if (!s->language().isEmpty()) // explicit language setting + { + lang = s->language(); + } switch(s->type()) { case DocVerbatim::Code: // fall though m_t << "{" << endl; m_t << "\\par" << endl; m_t << rtf_Style_Reset << getStyle("CodeExample"); - Doxygen::parserManager->getParser(m_langExt) + Doxygen::parserManager->getParser(lang) ->parseCode(m_ci,s->context(),s->text(), s->isExample(),s->exampleFile()); //m_t << "\\par" << endl; diff --git a/src/scanner.l b/src/scanner.l index d211301..63bfde0 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -69,6 +69,7 @@ static int lastPreLineCtrlContext; static int lastSkipVerbStringContext; static int lastCommentInArgContext; static int lastCSConstraint; +static int lastHereDocContext; static Protection protection; static Protection baseProt; static int sharpCount = 0 ; @@ -138,6 +139,7 @@ static QCString *pCopyCurlyString; static QGString *pCopyCurlyGString; static QGString *pCopyRoundGString; static QGString *pCopyQuotedGString; +static QGString *pCopyHereDocGString; static QGString *pSkipVerbString; static QStack<Grouping> autoGroupStack; @@ -698,6 +700,8 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) %x CopyArgVerbatim %x HereDoc %x HereDocEnd +%x CopyHereDoc +%x CopyHereDocEnd %x IDLAttribute %x IDLProp @@ -1833,13 +1837,14 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) else BEGIN( EndTemplate ); } -<EndTemplate>"<<<" { +<EndTemplate>"<<<" { if (!insidePHP) { REJECT; } else { + lastHereDocContext = YY_START; BEGIN(HereDoc); } } @@ -1922,20 +1927,44 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) else REJECT; } +<CopyHereDoc>{ID} { // PHP heredoc + g_hereDocId = yytext; + *pCopyHereDocGString += yytext; + BEGIN(CopyHereDocEnd); + } +<CopyHereDoc>"'"{ID}/"'" { // PHP nowdoc + g_hereDocId = &yytext[1]; + *pCopyHereDocGString += yytext; + BEGIN(CopyHereDocEnd); + } <HereDoc>{ID} { // PHP heredoc g_hereDocId = yytext; BEGIN(HereDocEnd); } <HereDoc>"'"{ID}/"'" { // PHP nowdoc g_hereDocId = &yytext[1]; + BEGIN(HereDocEnd); } <HereDocEnd>^{ID} { // id at start of the line could mark the end of the block if (g_hereDocId==yytext) // it is the end marker { - BEGIN(FindMembers); + BEGIN(lastHereDocContext); } } <HereDocEnd>. { } +<CopyHereDocEnd>^{ID} { // id at start of the line could mark the end of the block + *pCopyHereDocGString += yytext; + if (g_hereDocId==yytext) // it is the end marker + { + BEGIN(lastHereDocContext); + } + } +<CopyHereDocEnd>\n { + *pCopyHereDocGString += yytext; + } +<CopyHereDocEnd>. { + *pCopyHereDocGString += yytext; + } <FindMembers>"Q_OBJECT" { // Qt object macro } <FindMembers>"Q_PROPERTY" { // Qt property declaration @@ -3130,7 +3159,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) /* <FindFieldArg>"," { unput(*yytext); BEGIN(FindFields); } */ -<ReadBody,ReadNSBody,ReadBodyIntf>[^\r\n\#{}"@'/]* { current->program += yytext ; } +<ReadBody,ReadNSBody,ReadBodyIntf>[^\r\n\#{}"@'/<]* { current->program += yytext ; } <ReadBody,ReadNSBody,ReadBodyIntf>"//".* { current->program += yytext ; } <ReadBody,ReadNSBody,ReadBodyIntf>"#".* { if (!insidePHP) REJECT; @@ -3142,6 +3171,18 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) lastSkipVerbStringContext=YY_START; BEGIN( SkipVerbString ); } +<ReadBody,ReadNSBody,ReadBodyIntf>"<<<" { if (insidePHP) + { + current->program += yytext ; + pCopyHereDocGString = ¤t->program; + lastHereDocContext=YY_START; + BEGIN( CopyHereDoc ); + } + else + { + REJECT; + } + } <ReadBody,ReadNSBody,ReadBodyIntf>\" { current->program += yytext ; pCopyQuotedGString = ¤t->program; lastStringContext=YY_START; @@ -4470,7 +4511,18 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) yyLineNr++; //addToBody(yytext); } -<SkipCurly,SkipCurlyCpp>[^\n#"'@\\/{}]+ { +<SkipCurly,SkipCurlyCpp>"<<<" { + if (!insidePHP) + { + REJECT; + } + else + { + lastHereDocContext = YY_START; + BEGIN(HereDoc); + } + } +<SkipCurly,SkipCurlyCpp>[^\n#"'@\\/{}<]+ { //addToBody(yytext); } <SkipCurlyCpp>\n { diff --git a/src/section.h b/src/section.h index c4c9517..78516ae 100644 --- a/src/section.h +++ b/src/section.h @@ -28,13 +28,17 @@ class Definition; struct SectionInfo { - enum SectionType { Page, Section, Subsection, - Subsubsection, Paragraph, Anchor + enum SectionType { Page = 0, + Section = 1, + Subsection = 2, + Subsubsection = 3, + Paragraph = 4, + Anchor = 5 }; SectionInfo(const char *f,const char *l,const char *t, - SectionType st,const char *r=0) : + SectionType st,int lev,const char *r=0) : label(l), title(t), type(st), ref(r), definition(0), - fileName(f), generated(FALSE) + fileName(f), generated(FALSE), level(lev) { } SectionInfo(const SectionInfo &s) @@ -51,12 +55,13 @@ struct SectionInfo Definition *definition; QCString fileName; bool generated; + int level; }; -class SectionDict : public QDict<SectionInfo> +class SectionDict : public SDict<SectionInfo> { public: - SectionDict(int size) : QDict<SectionInfo>(size) {} + SectionDict(int size) : SDict<SectionInfo>(size) {} ~SectionDict() {} }; diff --git a/src/tagreader.cpp b/src/tagreader.cpp index b7a7b7a..36119e2 100644 --- a/src/tagreader.cpp +++ b/src/tagreader.cpp @@ -1035,8 +1035,8 @@ void TagFileParser::addDocAnchors(Entry *e,const TagAnchorInfoList &l) //printf("New sectionInfo file=%s anchor=%s\n", // ta->fileName.data(),ta->label.data()); SectionInfo *si=new SectionInfo(ta->fileName,ta->label,ta->label, - SectionInfo::Anchor,m_tagName); - Doxygen::sectionDict.insert(ta->label,si); + SectionInfo::Anchor,0,m_tagName); + Doxygen::sectionDict.append(ta->label,si); e->anchors->append(si); } else diff --git a/src/util.cpp b/src/util.cpp index 6addbc7..3859c97 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -5908,13 +5908,13 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle, file=pd->getOutputFileBase(); } SectionInfo *si=new SectionInfo( - file,pd->name(),pd->title(),SectionInfo::Page,pd->getReference()); + file,pd->name(),pd->title(),SectionInfo::Page,0,pd->getReference()); //printf("si->label=`%s' si->definition=%s si->fileName=`%s'\n", // si->label.data(),si->definition?si->definition->name().data():"<none>", // si->fileName.data()); //printf(" SectionInfo: sec=%p sec->fileName=%s\n",si,si->fileName.data()); //printf("Adding section key=%s si->fileName=%s\n",pageName.data(),si->fileName.data()); - Doxygen::sectionDict.insert(pd->name(),si); + Doxygen::sectionDict.append(pd->name(),si); } } return pd; @@ -6303,6 +6303,7 @@ bool updateLanguageMapping(const QCString &extension,const QCString &language) void initDefaultExtensionMapping() { g_extLookup.setAutoDelete(TRUE); + // extension parser id updateLanguageMapping(".idl", "idl"); updateLanguageMapping(".ddl", "idl"); updateLanguageMapping(".odl", "idl"); @@ -7166,20 +7167,21 @@ QCString langToString(SrcLangExt lang) { switch(lang) { - case SrcLangExt_Unknown: return "Unknown"; - case SrcLangExt_IDL: return "IDL"; - case SrcLangExt_Java: return "Java"; - case SrcLangExt_CSharp: return "C#"; - case SrcLangExt_D: return "D"; - case SrcLangExt_PHP: return "PHP"; - case SrcLangExt_ObjC: return "Objective-C"; - case SrcLangExt_Cpp: return "C++"; - case SrcLangExt_JS: return "Javascript"; - case SrcLangExt_Python: return "Python"; - case SrcLangExt_Fortran: return "Fortran"; - case SrcLangExt_VHDL: return "VHDL"; - case SrcLangExt_XML: return "XML"; - case SrcLangExt_Tcl: return "Tcl"; + case SrcLangExt_Unknown: return "Unknown"; + case SrcLangExt_IDL: return "IDL"; + case SrcLangExt_Java: return "Java"; + case SrcLangExt_CSharp: return "C#"; + case SrcLangExt_D: return "D"; + case SrcLangExt_PHP: return "PHP"; + case SrcLangExt_ObjC: return "Objective-C"; + case SrcLangExt_Cpp: return "C++"; + case SrcLangExt_JS: return "Javascript"; + case SrcLangExt_Python: return "Python"; + case SrcLangExt_Fortran: return "Fortran"; + case SrcLangExt_VHDL: return "VHDL"; + case SrcLangExt_XML: return "XML"; + case SrcLangExt_Tcl: return "Tcl"; + case SrcLangExt_Markdown: return "Markdown"; } return "Unknown"; } |