Skip to content

Commit 34618e1

Browse files
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. Pick-to: 6.4 Task-number: PYSIDE-2225 Change-Id: Ifbb4f68ecbb56ad039fd61d4361096335139f518 Reviewed-by: Christian Tismer <[email protected]>
1 parent aadb72a commit 34618e1

File tree

3 files changed

+82
-29
lines changed

3 files changed

+82
-29
lines changed

sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,20 @@ static bool isHttpLink(const QString &ref)
6363
return ref.startsWith(u"http://") || ref.startsWith(u"https://");
6464
}
6565

66+
static QString trimRight(QString s)
67+
{
68+
while (!s.isEmpty() && s.crbegin()->isSpace())
69+
s.chop(1);
70+
return s;
71+
}
72+
73+
static QString trimLeadingNewlines(QString s)
74+
{
75+
while (!s.isEmpty() && s.at(0) == u'\n')
76+
s.remove(0, 1);
77+
return s;
78+
}
79+
6680
QDebug operator<<(QDebug d, const QtXmlToSphinxLink &l)
6781
{
6882
static const QHash<QtXmlToSphinxLink::Type, const char *> typeName = {
@@ -407,11 +421,13 @@ void QtXmlToSphinx::callHandler(WebXmlTag t, QXmlStreamReader &r)
407421

408422
void QtXmlToSphinx::formatCurrentTable()
409423
{
410-
if (m_currentTable.isEmpty())
424+
Q_ASSERT(!m_tables.isEmpty());
425+
auto &table = m_tables.back();
426+
if (table.isEmpty())
411427
return;
412-
m_currentTable.normalize();
428+
table.normalize();
413429
m_output << '\n';
414-
m_currentTable.format(m_output);
430+
table.format(m_output);
415431
}
416432

417433
void QtXmlToSphinx::pushOutputBuffer()
@@ -938,11 +954,11 @@ void QtXmlToSphinx::handleTableTag(QXmlStreamReader& reader)
938954
if (token == QXmlStreamReader::StartElement) {
939955
if (parentTag() == WebXmlTag::para)
940956
handleParaTagEnd(); // End <para> to prevent the table from being rst-escaped
941-
m_currentTable.clear();
957+
m_tables.push({});
942958
} else if (token == QXmlStreamReader::EndElement) {
943959
// write the table on m_output
944960
formatCurrentTable();
945-
m_currentTable.clear();
961+
m_tables.pop();
946962
if (parentTag() == WebXmlTag::para)
947963
handleParaTagStart();
948964
}
@@ -958,7 +974,7 @@ void QtXmlToSphinx::handleTermTag(QXmlStreamReader& reader)
958974
} else if (token == QXmlStreamReader::EndElement) {
959975
TableCell cell;
960976
cell.data = popOutputBuffer().trimmed();
961-
m_currentTable.appendRow(TableRow(1, cell));
977+
m_tables.back().appendRow(TableRow(1, cell));
962978
}
963979
}
964980

@@ -967,18 +983,20 @@ void QtXmlToSphinx::handleItemTag(QXmlStreamReader& reader)
967983
{
968984
QXmlStreamReader::TokenType token = reader.tokenType();
969985
if (token == QXmlStreamReader::StartElement) {
970-
if (m_currentTable.isEmpty())
971-
m_currentTable.appendRow({});
972-
TableRow& row = m_currentTable.last();
986+
auto &table = m_tables.back();
987+
if (table.isEmpty())
988+
table.appendRow({});
989+
TableRow& row = table.last();
973990
TableCell cell;
974991
cell.colSpan = reader.attributes().value(u"colspan"_s).toShort();
975992
cell.rowSpan = reader.attributes().value(u"rowspan"_s).toShort();
976993
row << cell;
977994
pushOutputBuffer();
978995
} else if (token == QXmlStreamReader::EndElement) {
979-
QString data = popOutputBuffer().trimmed();
980-
if (!m_currentTable.isEmpty()) {
981-
TableRow& row = m_currentTable.last();
996+
QString data = trimLeadingNewlines(trimRight(popOutputBuffer()));
997+
auto &table = m_tables.back();
998+
if (!table.isEmpty()) {
999+
TableRow& row = table.last();
9821000
if (!row.isEmpty())
9831001
row.last().data = data;
9841002
}
@@ -991,15 +1009,16 @@ void QtXmlToSphinx::handleHeaderTag(QXmlStreamReader &reader)
9911009
// C++ header with "name"/"href" attributes.
9921010
if (reader.tokenType() == QXmlStreamReader::StartElement
9931011
&& !reader.attributes().hasAttribute(u"name"_s)) {
994-
m_currentTable.setHeaderEnabled(true);
995-
m_currentTable.appendRow({});
1012+
auto &table = m_tables.back();
1013+
table.setHeaderEnabled(true);
1014+
table.appendRow({});
9961015
}
9971016
}
9981017

9991018
void QtXmlToSphinx::handleRowTag(QXmlStreamReader& reader)
10001019
{
10011020
if (reader.tokenType() == QXmlStreamReader::StartElement)
1002-
m_currentTable.appendRow({});
1021+
m_tables.back().appendRow({});
10031022
}
10041023

10051024
enum ListType { BulletList, OrderedList, EnumeratedList };
@@ -1015,27 +1034,29 @@ static inline ListType webXmlListType(QStringView t)
10151034

10161035
void QtXmlToSphinx::handleListTag(QXmlStreamReader& reader)
10171036
{
1018-
// BUG We do not support a list inside a table cell
10191037
static ListType listType = BulletList;
10201038
QXmlStreamReader::TokenType token = reader.tokenType();
10211039
if (token == QXmlStreamReader::StartElement) {
1040+
m_tables.push({});
1041+
auto &table = m_tables.back();
10221042
listType = webXmlListType(reader.attributes().value(u"type"_s));
10231043
if (listType == EnumeratedList) {
1024-
m_currentTable.appendRow(TableRow{TableCell(u"Constant"_s),
1025-
TableCell(u"Description"_s)});
1026-
m_currentTable.setHeaderEnabled(true);
1044+
table.appendRow(TableRow{TableCell(u"Constant"_s),
1045+
TableCell(u"Description"_s)});
1046+
table.setHeaderEnabled(true);
10271047
}
10281048
m_output.indent();
10291049
} else if (token == QXmlStreamReader::EndElement) {
10301050
m_output.outdent();
1031-
if (!m_currentTable.isEmpty()) {
1051+
const auto &table = m_tables.back();
1052+
if (!table.isEmpty()) {
10321053
switch (listType) {
10331054
case BulletList:
10341055
case OrderedList: {
10351056
m_output << '\n';
10361057
const char *separator = listType == BulletList ? "* " : "#. ";
10371058
const char *indentLine = listType == BulletList ? " " : " ";
1038-
for (const TableCell &cell : m_currentTable.constFirst()) {
1059+
for (const TableCell &cell : table.constFirst()) {
10391060
const auto itemLines = QStringView{cell.data}.split(u'\n');
10401061
m_output << separator << itemLines.constFirst() << '\n';
10411062
for (qsizetype i = 1, max = itemLines.size(); i < max; ++i)
@@ -1049,7 +1070,7 @@ void QtXmlToSphinx::handleListTag(QXmlStreamReader& reader)
10491070
break;
10501071
}
10511072
}
1052-
m_currentTable.clear();
1073+
m_tables.pop();
10531074
}
10541075
}
10551076

sources/shiboken6/generator/qtdoc/qtxmltosphinx.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,9 @@ class QtXmlToSphinx
7070
return m_normalized;
7171
}
7272

73-
void clear() {
74-
m_normalized = false;
75-
m_rows.clear();
76-
}
77-
7873
void appendRow(const TableRow &row) { m_rows.append(row); }
7974

80-
const TableRow &constFirst() { return m_rows.constFirst(); }
75+
const TableRow &constFirst() const { return m_rows.constFirst(); }
8176
TableRow &first() { return m_rows.first(); }
8277
TableRow &last() { return m_rows.last(); }
8378

@@ -161,7 +156,7 @@ class QtXmlToSphinx
161156

162157
QStack<StringSharedPtr> m_buffers; // Maintain address stability since it used in TextStream
163158

164-
Table m_currentTable;
159+
QStack<Table> m_tables; // Stack of tables, used for <table><list> with nested <item>
165160
QScopedPointer<QtXmlToSphinxLink> m_linkContext; // for <link>
166161
QScopedPointer<QtXmlToSphinxLink> m_seeAlsoContext; // for <see-also>foo()</see-also>
167162
QString m_context;

sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,43 @@ void QtXmlToSphinxTest::testTable_data()
271271
QTest::newRow("testRowSpan2")
272272
<< QString::fromLatin1(xml) << QString::fromLatin1(expected);
273273

274+
// testNestedList
275+
xml = R"(<table>
276+
<row>
277+
<item>
278+
<list type="bullet">
279+
<item>
280+
<para>I11</para>
281+
</item>
282+
<item>
283+
<para>I21</para>
284+
</item>
285+
</list>
286+
</item>
287+
<item>
288+
<list type="bullet">
289+
<item>
290+
<para>I12</para>
291+
</item>
292+
<item>
293+
<para>I22</para>
294+
</item>
295+
</list>
296+
</item>
297+
</row>
298+
</table>)";
299+
300+
expected = R"(
301+
+---------+---------+
302+
| * I11| * I12|
303+
| * I21| * I22|
304+
+---------+---------+
305+
306+
)";
307+
308+
QTest::newRow("testNestedList")
309+
<< QString::fromLatin1(xml) << QString::fromLatin1(expected);
310+
274311
// testBrokenTable
275312
xml = R"(<table>
276313
<header>

0 commit comments

Comments
 (0)