From 2052757831db677b78b6f9b56bf075ab8413b92c Mon Sep 17 00:00:00 2001 From: albert-github Date: Fri, 3 Jul 2020 17:49:04 +0200 Subject: issue #7884 Python to xml: Whitespace in method doc not preserved (MARKDOWN_SUPPORT=NO) Corrected handling of the comment blocks. Due to the possible nesting of classes and the handling of the first line special handling is required by means of the stripping of spaces after a return in a doc block (otherwise it might be stripped away multiple times / left multiple times). --- src/pyscanner.l | 70 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 14 deletions(-) diff --git a/src/pyscanner.l b/src/pyscanner.l index a3dbaba..5181c0d 100644 --- a/src/pyscanner.l +++ b/src/pyscanner.l @@ -97,6 +97,7 @@ struct pyscannerYY_state QGString * copyString = 0; int indent = 0; int curIndent = 0; + int commentIndent = 0; bool importTuple = FALSE; QDict packageNameCache; char atomStart = 0; @@ -140,6 +141,7 @@ static void initSpecialBlock(yyscan_t yyscanner); static void searchFoundDef(yyscan_t yyscanner); static void searchFoundClass(yyscan_t yyscanner); static QCString findPackageScope(yyscan_t yyscanner,const char *fileName); +static QCString stripSpace(const char * doc,const int ind); static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size); @@ -1251,7 +1253,8 @@ STARTDOCSYMS "##" QCString actualDoc=yyextra->docBlock; if (!yyextra->docBlockSpecial) // legacy unformatted docstring { - actualDoc.prepend("\\verbatim "); + actualDoc = stripSpace(actualDoc,yyextra->commentIndent); + actualDoc.prepend("\\verbatim\n"); actualDoc.append("\\endverbatim "); } //printf("-------> yyextra->current=%p yyextra->bodyEntry=%p\n",yyextra->current,yyextra->bodyEntry); @@ -1262,7 +1265,8 @@ STARTDOCSYMS "##" QCString actualDoc=yyextra->docBlock; if (!yyextra->docBlockSpecial) // legacy unformatted docstring { - actualDoc.prepend("\\verbatim "); + actualDoc = stripSpace(actualDoc,yyextra->commentIndent); + actualDoc.prepend("\\verbatim\n"); actualDoc.append("\\endverbatim "); } actualDoc.prepend("\\namespace "+yyextra->moduleScope+" "); @@ -1290,18 +1294,7 @@ STARTDOCSYMS "##" ^{BB} { // leading whitespace - int indent = computeIndent(yytext); - if (indent>=yyextra->curIndent) - { // strip yyextra->curIndent amount of whitespace - int i; - for (i=0;icurIndent;i++) yyextra->docBlock+=' '; - DBG_CTX((stderr,"stripping indent %d\n",yyextra->curIndent)); - } - else - { - DBG_CTX((stderr,"not stripping: %d<%d\n",indent,yyextra->curIndent)); - yyextra->docBlock += yytext; - } + yyextra->docBlock += yytext; } [^"'\n \t\\]+ { yyextra->docBlock += yytext; @@ -1529,6 +1522,52 @@ static inline int computeIndent(const char *s) return col; } +static QCString stripSpace(const char *doc,const int ind) +{ + static GrowBuf growBuf; + growBuf.clear(); + if (ind <= 0) return doc; + signed char c; + const signed char *p=(const signed char*)doc; + bool startLine = false; + int cnt = 0; + while ((c=*p++)!=0) + { + switch(c) + { + case '\n': + growBuf.addChar(c); + startLine = true; + cnt = ind; + break; + case ' ': + if (startLine) + { + if (cnt) + { + cnt--; + } + else + { + startLine = false; + growBuf.addChar(c); + } + } + else + { + growBuf.addChar(c); + } + break; + default: + startLine = false; + growBuf.addChar(c); + break; + } + } + + growBuf.addChar(0); + return growBuf.get(); +} static QCString findPackageScopeFromPath(yyscan_t yyscanner,const QCString &path) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; @@ -1686,6 +1725,7 @@ static void initTriDoubleQuoteBlock(yyscan_t yyscanner) yyextra->docBlockJavaStyle = TRUE; yyextra->docBlockSpecial = yytext[strlen(yytext) - 1]=='!'; yyextra->docBlock.resize(0); + yyextra->commentIndent = yyextra->curIndent; yyextra->doubleQuote = TRUE; startCommentBlock(yyscanner,FALSE); } @@ -1698,6 +1738,7 @@ static void initTriSingleQuoteBlock(yyscan_t yyscanner) yyextra->docBlockJavaStyle = TRUE; yyextra->docBlockSpecial = yytext[strlen(yytext) - 1]=='!'; yyextra->docBlock.resize(0); + yyextra->commentIndent = yyextra->curIndent; yyextra->doubleQuote = FALSE; startCommentBlock(yyscanner,FALSE); } @@ -1710,6 +1751,7 @@ static void initSpecialBlock(yyscan_t yyscanner) yyextra->docBlockJavaStyle = TRUE; yyextra->docBrief = TRUE; yyextra->docBlock.resize(0); + yyextra->commentIndent = yyextra->curIndent; startCommentBlock(yyscanner,TRUE); } -- cgit v0.12 From d2b3bc01f81e842ecc5baaf74e4402bc24e841e5 Mon Sep 17 00:00:00 2001 From: Dimitri van Heesch Date: Wed, 29 Jul 2020 22:13:58 +0200 Subject: Renamed stripSpaces to stripIndentation and make it work directly on the string passed. --- src/pyscanner.l | 55 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/src/pyscanner.l b/src/pyscanner.l index 7e06b77..773391b 100644 --- a/src/pyscanner.l +++ b/src/pyscanner.l @@ -141,7 +141,7 @@ static void initSpecialBlock(yyscan_t yyscanner); static void searchFoundDef(yyscan_t yyscanner); static void searchFoundClass(yyscan_t yyscanner); static QCString findPackageScope(yyscan_t yyscanner,const char *fileName); -static QCString stripSpace(const char * doc,const int ind); +static void stripIndentation(QCString &doc,const int indentationLevel); static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size); @@ -1253,7 +1253,7 @@ STARTDOCSYMS "##" QCString actualDoc=yyextra->docBlock; if (!yyextra->docBlockSpecial) // legacy unformatted docstring { - actualDoc = stripSpace(actualDoc,yyextra->commentIndent); + stripIndentation(actualDoc,yyextra->commentIndent); actualDoc.prepend("\\verbatim\n"); actualDoc.append("\\endverbatim "); } @@ -1265,7 +1265,7 @@ STARTDOCSYMS "##" QCString actualDoc=yyextra->docBlock; if (!yyextra->docBlockSpecial) // legacy unformatted docstring { - actualDoc = stripSpace(actualDoc,yyextra->commentIndent); + stripIndentation(actualDoc,yyextra->commentIndent); actualDoc.prepend("\\verbatim\n"); actualDoc.append("\\endverbatim "); } @@ -1522,52 +1522,55 @@ static inline int computeIndent(const char *s) return col; } -static QCString stripSpace(const char *doc,const int ind) +// strip up to \a indentationLevel spaces from each line in \a doc (excluding the first line) +static void stripIndentation(QCString &doc,const int indentationLevel) { - static GrowBuf growBuf; - growBuf.clear(); - if (ind <= 0) return doc; - signed char c; - const signed char *p=(const signed char*)doc; - bool startLine = false; + if (indentationLevel <= 0) return; // nothing to strip + + // by stripping content the string will only become shorter so we write the results + // back into the input string and then resize it at the end. + char c; + const char *src = doc.data(); + char *dst = doc.rawData(); + bool insideIndent = false; // skip the initial line from stripping int cnt = 0; - while ((c=*p++)!=0) + while ((c=*src++)!=0) { + // invariant: dst<=src switch(c) { case '\n': - growBuf.addChar(c); - startLine = true; - cnt = ind; + *dst++ = c; + insideIndent = true; + cnt = indentationLevel; break; case ' ': - if (startLine) + if (insideIndent) { - if (cnt) + if (cnt>0) // count down the spacing until the end of the indent { cnt--; } - else + else // reached the end of the indent, start of the part of the line to keep { - startLine = false; - growBuf.addChar(c); + insideIndent = false; + *dst++ = c; } } - else + else // part after indent, copy to the output { - growBuf.addChar(c); + *dst++ = c; } break; default: - startLine = false; - growBuf.addChar(c); + insideIndent = false; + *dst++ = c; break; } } - - growBuf.addChar(0); - return growBuf.get(); + doc.resize(dst-doc.data()+1); } + static QCString findPackageScopeFromPath(yyscan_t yyscanner,const QCString &path) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; -- cgit v0.12