summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/code.l2
-rw-r--r--src/commentcnv.l102
-rw-r--r--src/commentscan.l127
-rw-r--r--src/definition.cpp69
-rw-r--r--src/definition.h3
-rw-r--r--src/docparser.cpp27
-rw-r--r--src/docparser.h11
-rw-r--r--src/docsets.cpp3
-rw-r--r--src/doctokenizer.l15
-rw-r--r--src/doxygen.cpp11
-rw-r--r--src/doxygen.css1
-rw-r--r--src/doxygen_css.h1
-rw-r--r--src/fortrancode.l4
-rw-r--r--src/fortranscanner.l17
-rw-r--r--src/ftvhelp.cpp14
-rw-r--r--src/htmldocvisitor.cpp7
-rw-r--r--src/index.cpp28
-rw-r--r--src/latexdocvisitor.cpp89
-rw-r--r--src/latexgen.cpp75
-rw-r--r--src/markdown.cpp539
-rw-r--r--src/markdown.h4
-rw-r--r--src/marshal.cpp8
-rw-r--r--src/navtree.js37
-rw-r--r--src/navtree_js.h37
-rw-r--r--src/parserintf.h4
-rw-r--r--src/rtfdocvisitor.cpp7
-rw-r--r--src/scanner.l60
-rw-r--r--src/section.h17
-rw-r--r--src/tagreader.cpp4
-rw-r--r--src/util.cpp34
30 files changed, 985 insertions, 372 deletions
diff --git a/src/code.l b/src/code.l
index 36ebec6..6c9bcef 100644
--- a/src/code.l
+++ b/src/code.l
@@ -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(),"\"","&quot;"));
- 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(),"\"","&quot;"));
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(),"\"","&quot;"));
+ out.addStr("\"");
+ }
+ out.addStr(">");
+ out.addStr(content.simplifyWhiteSpace());
+ out.addStr("</a>");
+ }
+ else // avoid link to e.g. F[x](y)
{
//printf("no link for '%s'\n",link.data());
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 = &current->program;
+ lastHereDocContext=YY_START;
+ BEGIN( CopyHereDoc );
+ }
+ else
+ {
+ REJECT;
+ }
+ }
<ReadBody,ReadNSBody,ReadBodyIntf>\" { current->program += yytext ;
pCopyQuotedGString = &current->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";
}