diff options
author | Paul Wicking <paul.wicking@qt.io> | 2023-04-14 21:24:36 +0200 |
---|---|---|
committer | Paul Wicking <paul.wicking@qt.io> | 2023-04-25 10:02:54 +0200 |
commit | aa24730660aec04871ac72b8c829b8e50909e47c (patch) | |
tree | bec47758e9cfb20359653144dddfd530a74e769a | |
parent | 3465735012de9dda79b31b4452663878987d4aa9 (diff) | |
download | qttools-aa24730660aec04871ac72b8c829b8e50909e47c.tar.gz |
QDoc: Make \keyword enforce paragraphs
QDoc's \brief command takes an entire paragraph as its argument, and
also allows for the processing QDoc commands or macros that appear in
the argument. Due to QDoc's internals, this may lead to a situation
where such commands consume newline characters that the \brief command
relies upon as indicator of its end condition, leading to a situation
where the \brief command erroneously includes the following paragraph
as part of its argument.
In particular, this may cause issues for certain commands that
"naturally" fit in a document "header". For example, given the
following content in a .qdoc file:
/*!
\page the_page.html
\title The title
\brief This is the brief.
\keyword the_keyword
Lorem ipsum dolor sit amet.
Santa Mozzarella!
*/
the brief will contain:
This is the brief. Lorem ipsum dolor sit amet.
And the only content in the generated output will, unexpectedly, be
Santa Mozzarella!
Due to its design, modifications to the \brief command are difficult,
as they will inevitably change QDoc's behavior significantly, with the
possibility of silent breakage. Therefore, enforce that the \keyword
command starts ends the paragraph it occurs in before further
processing.
This change includes a reproducing test case for the behavior in
question, which serves to validate the fix as well as as a guard for
future regressions.
Fixes: QTBUG-70959
Change-Id: I8f5b8a4aebf2ed2040bf43c1d4551ec280fc895a
Reviewed-by: Topi Reiniƶ <topi.reinio@qt.io>
6 files changed, 62 insertions, 4 deletions
diff --git a/src/qdoc/qdoc/docparser.cpp b/src/qdoc/qdoc/docparser.cpp index 44b0ee3a7..cb6b7788e 100644 --- a/src/qdoc/qdoc/docparser.cpp +++ b/src/qdoc/qdoc/docparser.cpp @@ -635,6 +635,7 @@ void DocParser::parse(const QString &source, DocPrivate *docPrivate, startFormat(ATOM_FORMATTING_INDEX, cmd); break; case CMD_KEYWORD: + leavePara(); insertTarget(getRestOfLine(), true); break; case CMD_L: diff --git a/tests/auto/qdoc/generatedoutput/expected_output/brief-adventures.html b/tests/auto/qdoc/generatedoutput/expected_output/brief-adventures.html new file mode 100644 index 000000000..009104a6f --- /dev/null +++ b/tests/auto/qdoc/generatedoutput/expected_output/brief-adventures.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> +<!-- brief_adventures.qdoc --> + <meta name="description" content="Test that the \brief command doesn't eat content that follows it."> + <title>Adventures with QDoc's \brief command | IllformattedDocumentation</title> +</head> +<body> +<div class="sidebar"> +<div class="toc"> +<h3 id="toc">Contents</h3> +<ul> +<li class="level1"><a href="#further-details">Further details</a></li> +</ul> +</div> +<div class="sidebar-content" id="sidebar-content"></div></div> +<h1 class="title">Adventures with QDoc's \brief command</h1> +<!-- $$$brief-adventures.html-description --> +<div class="descr" id="details"> +<p>The purpose of this test data is to provide a regression mechanism as part of QDoc's end-to-end test, tst_generatedOutput, for an issue (QTBUG-70959) that was reported against QDoc's \keyword command. The issue, as experienced by the reporter of the bug, is that if the \keyword command isn't followed by a new command, or is the last command in a paragraph, the following paragraph is "eaten". That means the entire paragraph is understood by QDoc as keywords and included as html meta information instead of as part of the rendered output.</p> +<h2 id="further-details">Further details</h2> +<p>The bug report is at <a href="https://bugreports.qt.io/browse/QTBUG-70959" translate="no">https://bugreports.qt.io/browse/QTBUG-70959</a>. It refers to a change that bypassed the issue by moving the \keyword command, at <a href="https://codereview.qt-project.org/c/qt/qtdoc/+/242033/" translate="no">https://codereview.qt-project.org/c/qt/qtdoc/+/242033/</a>.</p> +</div> +<!-- @@@brief-adventures.html --> +</body> +</html> diff --git a/tests/auto/qdoc/generatedoutput/expected_output/html/illformatteddocumentation.index b/tests/auto/qdoc/generatedoutput/expected_output/html/illformatteddocumentation.index index eae4c7eda..8acd9baa2 100644 --- a/tests/auto/qdoc/generatedoutput/expected_output/html/illformatteddocumentation.index +++ b/tests/auto/qdoc/generatedoutput/expected_output/html/illformatteddocumentation.index @@ -2,6 +2,10 @@ <!DOCTYPE QDOCINDEX> <INDEX url="" title="IllformattedDocumentation Reference Documentation" version="" project="IllformattedDocumentation"> <namespace name="" status="active" access="public" module="illformatteddocumentation"> + <page name="brief-adventures.html" href="brief-adventures.html" status="active" location="brief_adventures.qdoc" documented="true" subtype="page" title="Adventures with QDoc's \brief command" fulltitle="Adventures with QDoc's \brief command" subtitle="" brief="Test that the \brief command doesn't eat content that follows it"> + <keyword name="some-keyword" title="some_keyword"/> + <contents name="further-details" title="Further details" level="1"/> + </page> <page name="someexample" href="illformatteddocumentation-someexample-example.html" status="active" location="some_example.qdoc" documented="true" groups="illformatted-examples-qml" subtype="example" title="QDoc: some example" fulltitle="QDoc: some example" subtitle=""/> <page name="illformatted-examples.html" href="illformatted-examples.html" status="active" location="illformatted-examples.qdoc" documented="true" groups="all-examples" subtype="page" title="Test generated output for illformatted examples" fulltitle="Test generated output for illformatted examples" subtitle="" brief="Demonstrate correctness for example generation"> <contents name="qml-examples" title="QML Examples" level="1"/> @@ -9,5 +13,6 @@ </page> <group name="all-examples" href="all-examples.html" status="internal" seen="false" title=""/> <group name="illformatted-examples-qml" href="illformatted-examples-qml.html" status="internal" seen="false" title=""/> + <module name="sometestgroup" href="sometestgroup-module.html" status="internal" seen="false" title=""/> </namespace> </INDEX> diff --git a/tests/auto/qdoc/generatedoutput/testdata/illformatted_documentation/brief_adventures.qdoc b/tests/auto/qdoc/generatedoutput/testdata/illformatted_documentation/brief_adventures.qdoc new file mode 100644 index 000000000..b9e621f2b --- /dev/null +++ b/tests/auto/qdoc/generatedoutput/testdata/illformatted_documentation/brief_adventures.qdoc @@ -0,0 +1,24 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \page brief-adventures.html + \title Adventures with QDoc's \\brief command + \brief Test that the \\brief command doesn't eat content that follows it. + \inmodule sometestgroup + \keyword some_keyword + + The purpose of this test data is to provide a regression mechanism as part + of QDoc's end-to-end test, tst_generatedOutput, for an issue (QTBUG-70959) + that was reported against QDoc's \\keyword command. The issue, as + experienced by the reporter of the bug, is that if the \\keyword command + isn't followed by a new command, or is the last command in a paragraph, + the following paragraph is "eaten". That means the entire paragraph is + understood by QDoc as keywords and included as html meta information + instead of as part of the rendered output. + + \section1 Further details + The bug report is at \l https://bugreports.qt.io/browse/QTBUG-70959. + It refers to a change that bypassed the issue by moving the \\keyword + command, at \l https://codereview.qt-project.org/c/qt/qtdoc/+/242033/. +*/ diff --git a/tests/auto/qdoc/generatedoutput/testdata/illformatted_documentation/illformatted_documentation.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/illformatted_documentation/illformatted_documentation.qdocconf index 307dd36b1..a37439720 100644 --- a/tests/auto/qdoc/generatedoutput/testdata/illformatted_documentation/illformatted_documentation.qdocconf +++ b/tests/auto/qdoc/generatedoutput/testdata/illformatted_documentation/illformatted_documentation.qdocconf @@ -5,7 +5,7 @@ headerdirs = . sourcedirs = . exampledirs = . -outputformats = WebXML +outputformats = WebXML HTML WebXML.quotinginformation = true WebXML.nosubdirs = true diff --git a/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp b/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp index f39a87223..785fad427 100644 --- a/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp +++ b/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp @@ -27,7 +27,7 @@ private slots: void webXmlFromCpp(); void webXmlFromQml(); void webXmlFromCppBug80259(); - void illformated_documentation_caused_qtbug112641(); + void illformated_documentation(); // DocBook generator void docBookFromQDocFile(); @@ -294,12 +294,13 @@ void tst_generatedOutput::webXmlFromCppBug80259() "html/index.webxml"); } -void tst_generatedOutput::illformated_documentation_caused_qtbug112641() +void tst_generatedOutput::illformated_documentation() { testAndCompare("testdata/illformatted_documentation/illformatted_documentation.qdocconf", "html/illformatted-examples.webxml " "html/illformatteddocumentation-someexample-example.webxml " - "html/illformatteddocumentation.index"); + "html/illformatteddocumentation.index " + "brief-adventures.html"); } void tst_generatedOutput::docBookFromQDocFile() |