aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2023-02-14 09:56:12 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-02-15 18:44:14 +0000
commit5ed75ce48e0bbae365f753e888135096a82591fe (patch)
treeb1af58236012b4b7296e287149e83b3665bb889b
parent66038655a67483b5c4e47d15d7081e9f4222e141 (diff)
Documentation/WebXML conversion: Handle lists nested into tables
Lists and tables use the <item> element, which QtXmlToSphinx recorded into a table. Introduce a stack of tables to handle nesting, which for example occurs in solutions-for-ui-design.webxml. Task-number: PYSIDE-2225 Change-Id: Ifbb4f68ecbb56ad039fd61d4361096335139f518 Reviewed-by: Christian Tismer <tismer@stackless.com> (cherry picked from commit 34618e17eaeea838ab4954a38aa855a3263fb62c) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp65
-rw-r--r--sources/shiboken6/generator/qtdoc/qtxmltosphinx.h9
-rw-r--r--sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.cpp37
3 files changed, 82 insertions, 29 deletions
diff --git a/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp b/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp
index 754619ceb..4b7f718a4 100644
--- a/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp
+++ b/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp
@@ -63,6 +63,20 @@ static bool isHttpLink(const QString &ref)
return ref.startsWith(u"http://") || ref.startsWith(u"https://");
}
+static QString trimRight(QString s)
+{
+ while (!s.isEmpty() && s.crbegin()->isSpace())
+ s.chop(1);
+ return s;
+}
+
+static QString trimLeadingNewlines(QString s)
+{
+ while (!s.isEmpty() && s.at(0) == u'\n')
+ s.remove(0, 1);
+ return s;
+}
+
QDebug operator<<(QDebug d, const QtXmlToSphinxLink &l)
{
static const QHash<QtXmlToSphinxLink::Type, const char *> typeName = {
@@ -407,11 +421,13 @@ void QtXmlToSphinx::callHandler(WebXmlTag t, QXmlStreamReader &r)
void QtXmlToSphinx::formatCurrentTable()
{
- if (m_currentTable.isEmpty())
+ Q_ASSERT(!m_tables.isEmpty());
+ auto &table = m_tables.back();
+ if (table.isEmpty())
return;
- m_currentTable.normalize();
+ table.normalize();
m_output << '\n';
- m_currentTable.format(m_output);
+ table.format(m_output);
}
void QtXmlToSphinx::pushOutputBuffer()
@@ -938,11 +954,11 @@ void QtXmlToSphinx::handleTableTag(QXmlStreamReader& reader)
if (token == QXmlStreamReader::StartElement) {
if (parentTag() == WebXmlTag::para)
handleParaTagEnd(); // End <para> to prevent the table from being rst-escaped
- m_currentTable.clear();
+ m_tables.push({});
} else if (token == QXmlStreamReader::EndElement) {
// write the table on m_output
formatCurrentTable();
- m_currentTable.clear();
+ m_tables.pop();
if (parentTag() == WebXmlTag::para)
handleParaTagStart();
}
@@ -958,7 +974,7 @@ void QtXmlToSphinx::handleTermTag(QXmlStreamReader& reader)
} else if (token == QXmlStreamReader::EndElement) {
TableCell cell;
cell.data = popOutputBuffer().trimmed();
- m_currentTable.appendRow(TableRow(1, cell));
+ m_tables.back().appendRow(TableRow(1, cell));
}
}
@@ -967,18 +983,20 @@ void QtXmlToSphinx::handleItemTag(QXmlStreamReader& reader)
{
QXmlStreamReader::TokenType token = reader.tokenType();
if (token == QXmlStreamReader::StartElement) {
- if (m_currentTable.isEmpty())
- m_currentTable.appendRow({});
- TableRow& row = m_currentTable.last();
+ auto &table = m_tables.back();
+ if (table.isEmpty())
+ table.appendRow({});
+ TableRow& row = table.last();
TableCell cell;
cell.colSpan = reader.attributes().value(u"colspan"_s).toShort();
cell.rowSpan = reader.attributes().value(u"rowspan"_s).toShort();
row << cell;
pushOutputBuffer();
} else if (token == QXmlStreamReader::EndElement) {
- QString data = popOutputBuffer().trimmed();
- if (!m_currentTable.isEmpty()) {
- TableRow& row = m_currentTable.last();
+ QString data = trimLeadingNewlines(trimRight(popOutputBuffer()));
+ auto &table = m_tables.back();
+ if (!table.isEmpty()) {
+ TableRow& row = table.last();
if (!row.isEmpty())
row.last().data = data;
}
@@ -991,15 +1009,16 @@ void QtXmlToSphinx::handleHeaderTag(QXmlStreamReader &reader)
// C++ header with "name"/"href" attributes.
if (reader.tokenType() == QXmlStreamReader::StartElement
&& !reader.attributes().hasAttribute(u"name"_s)) {
- m_currentTable.setHeaderEnabled(true);
- m_currentTable.appendRow({});
+ auto &table = m_tables.back();
+ table.setHeaderEnabled(true);
+ table.appendRow({});
}
}
void QtXmlToSphinx::handleRowTag(QXmlStreamReader& reader)
{
if (reader.tokenType() == QXmlStreamReader::StartElement)
- m_currentTable.appendRow({});
+ m_tables.back().appendRow({});
}
enum ListType { BulletList, OrderedList, EnumeratedList };
@@ -1015,27 +1034,29 @@ static inline ListType webXmlListType(QStringView t)
void QtXmlToSphinx::handleListTag(QXmlStreamReader& reader)
{
- // BUG We do not support a list inside a table cell
static ListType listType = BulletList;
QXmlStreamReader::TokenType token = reader.tokenType();
if (token == QXmlStreamReader::StartElement) {
+ m_tables.push({});
+ auto &table = m_tables.back();
listType = webXmlListType(reader.attributes().value(u"type"_s));
if (listType == EnumeratedList) {
- m_currentTable.appendRow(TableRow{TableCell(u"Constant"_s),
- TableCell(u"Description"_s)});
- m_currentTable.setHeaderEnabled(true);
+ table.appendRow(TableRow{TableCell(u"Constant"_s),
+ TableCell(u"Description"_s)});
+ table.setHeaderEnabled(true);
}
m_output.indent();
} else if (token == QXmlStreamReader::EndElement) {
m_output.outdent();
- if (!m_currentTable.isEmpty()) {
+ const auto &table = m_tables.back();
+ if (!table.isEmpty()) {
switch (listType) {
case BulletList:
case OrderedList: {
m_output << '\n';
const char *separator = listType == BulletList ? "* " : "#. ";
const char *indentLine = listType == BulletList ? " " : " ";
- for (const TableCell &cell : m_currentTable.constFirst()) {
+ for (const TableCell &cell : table.constFirst()) {
const auto itemLines = QStringView{cell.data}.split(u'\n');
m_output << separator << itemLines.constFirst() << '\n';
for (qsizetype i = 1, max = itemLines.size(); i < max; ++i)
@@ -1049,7 +1070,7 @@ void QtXmlToSphinx::handleListTag(QXmlStreamReader& reader)
break;
}
}
- m_currentTable.clear();
+ m_tables.pop();
}
}
diff --git a/sources/shiboken6/generator/qtdoc/qtxmltosphinx.h b/sources/shiboken6/generator/qtdoc/qtxmltosphinx.h
index f86e0e5e5..bb1ea7c59 100644
--- a/sources/shiboken6/generator/qtdoc/qtxmltosphinx.h
+++ b/sources/shiboken6/generator/qtdoc/qtxmltosphinx.h
@@ -69,14 +69,9 @@ public:
return m_normalized;
}
- void clear() {
- m_normalized = false;
- m_rows.clear();
- }
-
void appendRow(const TableRow &row) { m_rows.append(row); }
- const TableRow &constFirst() { return m_rows.constFirst(); }
+ const TableRow &constFirst() const { return m_rows.constFirst(); }
TableRow &first() { return m_rows.first(); }
TableRow &last() { return m_rows.last(); }
@@ -160,7 +155,7 @@ private:
QStack<StringSharedPtr> m_buffers; // Maintain address stability since it used in TextStream
- Table m_currentTable;
+ QStack<Table> m_tables; // Stack of tables, used for <table><list> with nested <item>
QScopedPointer<QtXmlToSphinxLink> m_linkContext; // for <link>
QScopedPointer<QtXmlToSphinxLink> m_seeAlsoContext; // for <see-also>foo()</see-also>
QString m_context;
diff --git a/sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.cpp b/sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.cpp
index e30033ae7..a2a89b67b 100644
--- a/sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.cpp
+++ b/sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.cpp
@@ -271,6 +271,43 @@ void QtXmlToSphinxTest::testTable_data()
QTest::newRow("testRowSpan2")
<< QString::fromLatin1(xml) << QString::fromLatin1(expected);
+ // testNestedList
+ xml = R"(<table>
+ <row>
+ <item>
+ <list type="bullet">
+ <item>
+ <para>I11</para>
+ </item>
+ <item>
+ <para>I21</para>
+ </item>
+ </list>
+ </item>
+ <item>
+ <list type="bullet">
+ <item>
+ <para>I12</para>
+ </item>
+ <item>
+ <para>I22</para>
+ </item>
+ </list>
+ </item>
+ </row>
+</table>)";
+
+ expected = R"(
+ +---------+---------+
+ | * I11| * I12|
+ | * I21| * I22|
+ +---------+---------+
+
+)";
+
+ QTest::newRow("testNestedList")
+ << QString::fromLatin1(xml) << QString::fromLatin1(expected);
+
// testBrokenTable
xml = R"(<table>
<header>