@@ -63,6 +63,20 @@ static bool isHttpLink(const QString &ref)
63
63
return ref.startsWith (u" http://" ) || ref.startsWith (u" https://" );
64
64
}
65
65
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
+
66
80
QDebug operator <<(QDebug d, const QtXmlToSphinxLink &l)
67
81
{
68
82
static const QHash<QtXmlToSphinxLink::Type, const char *> typeName = {
@@ -407,11 +421,13 @@ void QtXmlToSphinx::callHandler(WebXmlTag t, QXmlStreamReader &r)
407
421
408
422
void QtXmlToSphinx::formatCurrentTable ()
409
423
{
410
- if (m_currentTable.isEmpty ())
424
+ Q_ASSERT (!m_tables.isEmpty ());
425
+ auto &table = m_tables.back ();
426
+ if (table.isEmpty ())
411
427
return ;
412
- m_currentTable .normalize ();
428
+ table .normalize ();
413
429
m_output << ' \n ' ;
414
- m_currentTable .format (m_output);
430
+ table .format (m_output);
415
431
}
416
432
417
433
void QtXmlToSphinx::pushOutputBuffer ()
@@ -938,11 +954,11 @@ void QtXmlToSphinx::handleTableTag(QXmlStreamReader& reader)
938
954
if (token == QXmlStreamReader::StartElement) {
939
955
if (parentTag () == WebXmlTag::para)
940
956
handleParaTagEnd (); // End <para> to prevent the table from being rst-escaped
941
- m_currentTable. clear ( );
957
+ m_tables. push ({} );
942
958
} else if (token == QXmlStreamReader::EndElement) {
943
959
// write the table on m_output
944
960
formatCurrentTable ();
945
- m_currentTable. clear ();
961
+ m_tables. pop ();
946
962
if (parentTag () == WebXmlTag::para)
947
963
handleParaTagStart ();
948
964
}
@@ -958,7 +974,7 @@ void QtXmlToSphinx::handleTermTag(QXmlStreamReader& reader)
958
974
} else if (token == QXmlStreamReader::EndElement) {
959
975
TableCell cell;
960
976
cell.data = popOutputBuffer ().trimmed ();
961
- m_currentTable .appendRow (TableRow (1 , cell));
977
+ m_tables. back () .appendRow (TableRow (1 , cell));
962
978
}
963
979
}
964
980
@@ -967,18 +983,20 @@ void QtXmlToSphinx::handleItemTag(QXmlStreamReader& reader)
967
983
{
968
984
QXmlStreamReader::TokenType token = reader.tokenType ();
969
985
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 ();
973
990
TableCell cell;
974
991
cell.colSpan = reader.attributes ().value (u" colspan" _s).toShort ();
975
992
cell.rowSpan = reader.attributes ().value (u" rowspan" _s).toShort ();
976
993
row << cell;
977
994
pushOutputBuffer ();
978
995
} 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 ();
982
1000
if (!row.isEmpty ())
983
1001
row.last ().data = data;
984
1002
}
@@ -991,15 +1009,16 @@ void QtXmlToSphinx::handleHeaderTag(QXmlStreamReader &reader)
991
1009
// C++ header with "name"/"href" attributes.
992
1010
if (reader.tokenType () == QXmlStreamReader::StartElement
993
1011
&& !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 ({});
996
1015
}
997
1016
}
998
1017
999
1018
void QtXmlToSphinx::handleRowTag (QXmlStreamReader& reader)
1000
1019
{
1001
1020
if (reader.tokenType () == QXmlStreamReader::StartElement)
1002
- m_currentTable .appendRow ({});
1021
+ m_tables. back () .appendRow ({});
1003
1022
}
1004
1023
1005
1024
enum ListType { BulletList, OrderedList, EnumeratedList };
@@ -1015,27 +1034,29 @@ static inline ListType webXmlListType(QStringView t)
1015
1034
1016
1035
void QtXmlToSphinx::handleListTag (QXmlStreamReader& reader)
1017
1036
{
1018
- // BUG We do not support a list inside a table cell
1019
1037
static ListType listType = BulletList;
1020
1038
QXmlStreamReader::TokenType token = reader.tokenType ();
1021
1039
if (token == QXmlStreamReader::StartElement) {
1040
+ m_tables.push ({});
1041
+ auto &table = m_tables.back ();
1022
1042
listType = webXmlListType (reader.attributes ().value (u" type" _s));
1023
1043
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 );
1027
1047
}
1028
1048
m_output.indent ();
1029
1049
} else if (token == QXmlStreamReader::EndElement) {
1030
1050
m_output.outdent ();
1031
- if (!m_currentTable.isEmpty ()) {
1051
+ const auto &table = m_tables.back ();
1052
+ if (!table.isEmpty ()) {
1032
1053
switch (listType) {
1033
1054
case BulletList:
1034
1055
case OrderedList: {
1035
1056
m_output << ' \n ' ;
1036
1057
const char *separator = listType == BulletList ? " * " : " #. " ;
1037
1058
const char *indentLine = listType == BulletList ? " " : " " ;
1038
- for (const TableCell &cell : m_currentTable .constFirst ()) {
1059
+ for (const TableCell &cell : table .constFirst ()) {
1039
1060
const auto itemLines = QStringView{cell.data }.split (u' \n ' );
1040
1061
m_output << separator << itemLines.constFirst () << ' \n ' ;
1041
1062
for (qsizetype i = 1 , max = itemLines.size (); i < max; ++i)
@@ -1049,7 +1070,7 @@ void QtXmlToSphinx::handleListTag(QXmlStreamReader& reader)
1049
1070
break ;
1050
1071
}
1051
1072
}
1052
- m_currentTable. clear ();
1073
+ m_tables. pop ();
1053
1074
}
1054
1075
}
1055
1076
0 commit comments