diff options
author | Topi Reinio <topi.reinio@qt.io> | 2019-10-10 13:57:53 +0200 |
---|---|---|
committer | Topi Reinio <topi.reinio@qt.io> | 2019-12-18 14:37:05 +0100 |
commit | c2566a8c56f19b0c704a99b9d22997747e21f82a (patch) | |
tree | 7d81119cf3419dba3591552f7e693c498ed9f813 /src/qdoc/doc.cpp | |
parent | ed6658c2c82e2d91f34d57e88b61648fb301baf4 (diff) |
qdoc: Introduce ignorewords configuration variable
QDoc automatically generates hyperlinks for words that qualify for
auto-linking. This may become a problem whenever there is a qualified
word as a section or a page title, and that word appear in the
documentation frequently. For example, 'macOS' is mentioned often
and each occurrence is linked, which is unnecessary and sometimes
confusing.
Provide a way to exclude specified words from being auto-linked.
Create a new helper function, DocParser::isAutoLinkString(), to
determine whether a string qualifies, and replace duplicated
code with calls to that function.
Fixes: QTBUG-79135
Change-Id: Ie53fe7ca0692f7b8e10a5f2208df5cd2ee2aab1d
Reviewed-by: Topi Reiniƶ <topi.reinio@qt.io>
Diffstat (limited to 'src/qdoc/doc.cpp')
-rw-r--r-- | src/qdoc/doc.cpp | 178 |
1 files changed, 76 insertions, 102 deletions
diff --git a/src/qdoc/doc.cpp b/src/qdoc/doc.cpp index 9929a2a2a..61838b69c 100644 --- a/src/qdoc/doc.cpp +++ b/src/qdoc/doc.cpp @@ -426,6 +426,7 @@ public: static QStringList exampleDirs; static QStringList sourceFiles; static QStringList sourceDirs; + static QStringList ignorewords; static bool quoting; private: @@ -470,6 +471,8 @@ private: QString getCode(int cmd, CodeMarker *marker, const QString &argStr = QString()); QString getUnmarkedCode(int cmd); + inline bool isAutoLinkString(const QString &word); + bool isAutoLinkString(const QString &word, int &curPos); bool isBlankLine(); bool isLeftBraceAhead(); bool isLeftBracketAhead(); @@ -517,6 +520,7 @@ QStringList DocParser::exampleFiles; QStringList DocParser::exampleDirs; QStringList DocParser::sourceFiles; QStringList DocParser::sourceDirs; +QStringList DocParser::ignorewords; bool DocParser::quoting = false; /*! @@ -1364,63 +1368,17 @@ void DocParser::parse(const QString &source, DocPrivate *docPrivate, pos = backslashPos; } } + } else if (isAutoLinkString(cmdStr)) { + appendWord(cmdStr); } else { - int curPos = 0; - int numUppercase = 0; - int numLowercase = 0; - int numStrangeSymbols = 0; - - while (curPos < cmdStr.size()) { - unsigned char latin1Ch = cmdStr.at(curPos).toLatin1(); - if (islower(latin1Ch)) { - ++numLowercase; - ++curPos; - } else if (isupper(latin1Ch)) { - ++numUppercase; - ++curPos; - } else if (isdigit(latin1Ch)) { - if (curPos > 0) - ++curPos; - else - break; - } else if (latin1Ch == '_' || latin1Ch == '@') { - ++numStrangeSymbols; - ++curPos; - } else if ((latin1Ch == ':') && (curPos < cmdStr.size() - 1) - && (cmdStr.at(curPos + 1) == QLatin1Char(':'))) { - ++numStrangeSymbols; - curPos += 2; - } else if (latin1Ch == '(') { - if (curPos > 0) { - if ((curPos < cmdStr.size() - 1) - && (cmdStr.at(curPos + 1) == QLatin1Char(')'))) { - ++numStrangeSymbols; - pos += 2; - break; - } else { - // ### handle functions with signatures - // and function calls - break; - } - } else { - break; - } - } else { - break; - } - } - if ((numUppercase >= 1 && numLowercase >= 2) || numStrangeSymbols > 0) { - appendWord(cmdStr); - } else { - if (!cmdStr.endsWith("propertygroup")) { - // The QML and JS property group commands are no longer required - // for grouping QML and JS properties. They are allowed but ignored. - location().warning(tr("Unknown command '\\%1'").arg(cmdStr), - detailsUnknownCommand(metaCommandSet, cmdStr)); - } - enterPara(); - append(Atom::UnknownCommand, cmdStr); + if (!cmdStr.endsWith("propertygroup")) { + // The QML and JS property group commands are no longer required + // for grouping QML and JS properties. They are allowed but ignored. + location().warning(tr("Unknown command '\\%1'").arg(cmdStr), + detailsUnknownCommand(metaCommandSet,cmdStr)); } + enterPara(); + append(Atom::UnknownCommand, cmdStr); } } } // case '\\' (qdoc markup command) @@ -1505,50 +1463,7 @@ void DocParser::parse(const QString &source, DocPrivate *docPrivate, if (newWord) { int startPos = pos; - int numInternalUppercase = 0; - int numLowercase = 0; - int numStrangeSymbols = 0; - - while (pos < len) { - unsigned char latin1Ch = input_.at(pos).toLatin1(); - if (islower(latin1Ch)) { - ++numLowercase; - ++pos; - } else if (isupper(latin1Ch)) { - if (pos > startPos) - ++numInternalUppercase; - ++pos; - } else if (isdigit(latin1Ch)) { - if (pos > startPos) - ++pos; - else - break; - } else if (latin1Ch == '_' || latin1Ch == '@') { - ++numStrangeSymbols; - ++pos; - } else if (latin1Ch == ':' && pos < len - 1 - && input_.at(pos + 1) == QLatin1Char(':')) { - ++numStrangeSymbols; - pos += 2; - } else if (latin1Ch == '(') { - if (pos > startPos) { - if (pos < len - 1 && input_.at(pos + 1) == QLatin1Char(')')) { - ++numStrangeSymbols; - pos += 2; - break; - } else { - // ### handle functions with signatures - // and function calls - break; - } - } else { - break; - } - } else { - break; - } - } - + bool autolink = isAutoLinkString(input_, pos); if (pos == startPos) { if (!ch.isSpace()) { appendChar(ch); @@ -1556,9 +1471,8 @@ void DocParser::parse(const QString &source, DocPrivate *docPrivate, } } else { QString word = input_.mid(startPos, pos - startPos); - // is word a C++ symbol or an English word? - if ((numInternalUppercase >= 1 && numLowercase >= 2) || numStrangeSymbols > 0) { - if (word.startsWith(QString("__"))) + if (autolink) { + if (ignorewords.contains(word) || word.startsWith(QString("__"))) appendWord(word); else append(Atom::AutoLink, word); @@ -1775,6 +1689,65 @@ bool DocParser::openCommand(int cmd) return ok; } +/*! + Returns \c true if \a word qualifies for auto-linking. +*/ +inline bool DocParser::isAutoLinkString(const QString &word) +{ + int start = 0; + return isAutoLinkString(word, start); +} + +bool DocParser::isAutoLinkString(const QString &word, int &curPos) +{ + int len = word.size(); + int startPos = curPos; + int numUppercase = 0; + int numLowercase = 0; + int numStrangeSymbols = 0; + + while (curPos < len) { + unsigned char latin1Ch = word.at(curPos).toLatin1(); + if (islower(latin1Ch)) { + ++numLowercase; + ++curPos; + } else if (isupper(latin1Ch)) { + if (curPos > startPos) + ++numUppercase; + ++curPos; + } else if (isdigit(latin1Ch)) { + if (curPos > startPos) + ++curPos; + else + break; + } else if (latin1Ch == '_' || latin1Ch == '@') { + ++numStrangeSymbols; + ++curPos; + } else if ((latin1Ch == ':') && + (curPos < len - 1) && + (word.at(curPos + 1) == QLatin1Char(':'))) { + ++numStrangeSymbols; + curPos += 2; + } else if (latin1Ch == '(') { + if (curPos > startPos) { + if ((curPos < len - 1) && + (word.at(curPos + 1) == QLatin1Char(')'))) { + ++numStrangeSymbols; + pos += 2; + break; + } else { + break; + } + } else { + break; + } + } else { + break; + } + } + return ((numUppercase >= 1 && numLowercase >= 2) || numStrangeSymbols > 0); +} + bool DocParser::closeCommand(int endCmd) { if (endCmdFor(openedCommands.top()) == endCmd && openedCommands.size() > 1) { @@ -3049,6 +3022,7 @@ void Doc::initialize(const Config &config) DocParser::exampleDirs = config.getCanonicalPathList(CONFIG_EXAMPLEDIRS); DocParser::sourceFiles = config.getCanonicalPathList(CONFIG_SOURCES); DocParser::sourceDirs = config.getCanonicalPathList(CONFIG_SOURCEDIRS); + DocParser::ignorewords = config.getStringList(CONFIG_IGNOREWORDS); QmlTypeNode::qmlOnly = config.getBool(CONFIG_QMLONLY); QStringMap reverseAliasMap; |