diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2021-11-19 15:46:33 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-11-23 18:16:50 +0000 |
commit | 79ed82dcbdf38f199c1d3e29203350000a09441a (patch) | |
tree | 374328a9f19f302e297a3e4ca6142deaab042fea | |
parent | 7264bc3930ee752b843a04255fcdda4a1095aab5 (diff) |
Documentation: Fix most sphinx errors "Inline strong start-string without end-string."
Ensure characters following a formatting end are escaped by adding
handling and some RST manipulators to class TextStream.
Task-number: PYSIDE-1112
Change-Id: I167160cd18fd890d73e31738487d2c91e012196c
Reviewed-by: Christian Tismer <tismer@stackless.com>
(cherry picked from commit 2cfe8433c861c3602e5e23af8d4fdfb6fd219f4d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
6 files changed, 130 insertions, 20 deletions
diff --git a/sources/pyside6/doc/tutorials/basictutorial/signals_and_slots.rst b/sources/pyside6/doc/tutorials/basictutorial/signals_and_slots.rst index ffe22efb0..a221e775a 100644 --- a/sources/pyside6/doc/tutorials/basictutorial/signals_and_slots.rst +++ b/sources/pyside6/doc/tutorials/basictutorial/signals_and_slots.rst @@ -1,7 +1,7 @@ Signals and Slots ================= -Due to the nature of Qt, ``QObject``s require a way to communicate, and that's +Due to the nature of Qt, ``QObject``\s require a way to communicate, and that's the reason for this mechanism to be a **central feature of Qt**. In simple terms, you can understand **Signal and Slots** in the same way you diff --git a/sources/shiboken6/ApiExtractor/tests/testcodeinjection.cpp b/sources/shiboken6/ApiExtractor/tests/testcodeinjection.cpp index 1d7ba9666..42a3fe08b 100644 --- a/sources/shiboken6/ApiExtractor/tests/testcodeinjection.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testcodeinjection.cpp @@ -165,4 +165,19 @@ static const char expected[] = R"(void foo(int a, int b) { QCOMPARE(str.toString(), QLatin1String(expected)); } +void TestCodeInjections::testTextStreamRst() +{ + // Test that sphinx error: "Inline strong start-string without end-string." + // is avoided, that is, characters following a formatting end are escaped. + + StringStream str; + str << rstBold << "QObject" << rstBoldOff << "'s properties..." + << rstItalic << "some italic" << rstItalicOff << " followed by space."; + + static const char16_t expected[] = + uR"(**QObject**\'s properties...*some italic* followed by space.)"; + + QCOMPARE(str.toString(), expected); +} + QTEST_APPLESS_MAIN(TestCodeInjections) diff --git a/sources/shiboken6/ApiExtractor/tests/testcodeinjection.h b/sources/shiboken6/ApiExtractor/tests/testcodeinjection.h index 05b95a11e..473ddb13f 100644 --- a/sources/shiboken6/ApiExtractor/tests/testcodeinjection.h +++ b/sources/shiboken6/ApiExtractor/tests/testcodeinjection.h @@ -42,6 +42,7 @@ private slots: void testInjectWithValidApiVersion(); void testInjectWithInvalidApiVersion(); void testTextStream(); + void testTextStreamRst(); }; #endif diff --git a/sources/shiboken6/ApiExtractor/textstream.cpp b/sources/shiboken6/ApiExtractor/textstream.cpp index 364634f2d..2b8e9f29b 100644 --- a/sources/shiboken6/ApiExtractor/textstream.cpp +++ b/sources/shiboken6/ApiExtractor/textstream.cpp @@ -75,6 +75,12 @@ qint64 TextStream::pos() const return m_str.pos(); } +void TextStream::setString(QString *string, QIODeviceBase::OpenMode openMode) +{ + m_str.setString(string, openMode); + m_rstFormattingEnd = false; +} + void TextStream::putRepetitiveChars(char c, int count) { if (count > 0) { @@ -87,6 +93,11 @@ void TextStream::putRepetitiveChars(char c, int count) } } +void TextStream::_setRstFormattingEnd() +{ + m_rstFormattingEnd = true; +} + void TextStream::setLastCharClass(CharClass c) { m_lastCharClass = c; @@ -110,6 +121,11 @@ static TextStream::CharClass charClassHelper(Char c) return TextStream::CharClass::NewLine; case '#': return TextStream::CharClass::Hash; + case ' ': + case '\t': + return TextStream::CharClass::Space; + case '\\': + return TextStream::CharClass::BackSlash; default: break; } @@ -124,6 +140,13 @@ static inline TextStream::CharClass charClass(QChar c) void TextStream::checkIndent(CharClass upComingCharClass) { + if (m_rstFormattingEnd) { + if (upComingCharClass != CharClass::Space && upComingCharClass != CharClass::NewLine + && upComingCharClass != CharClass::BackSlash) { + m_str << '\\'; + } + m_rstFormattingEnd = false; + } if (m_indentationEnabled && m_lastCharClass == CharClass::NewLine && (upComingCharClass != CharClass::NewLine && (m_language != Language::Cpp || upComingCharClass != CharClass::Hash))) { @@ -135,7 +158,8 @@ void TextStream::checkIndent(CharClass upComingCharClass) template <class Char> void TextStream::putCharHelper(Char c) { - checkIndent(charClass(c)); + const auto klass = charClass(c); + checkIndent(klass); m_str << c; } @@ -150,7 +174,8 @@ void TextStream::putString(QStringView v) // If there is no newline, write as a blob. This is important to make // field formatting (alignment/width) working, else each char will be // considered a field. - checkIndent(charClass(*v.cbegin())); + const auto klass = charClass(*v.cbegin()); + checkIndent(klass); m_str << v; m_lastCharClass = CharClass::Other; } @@ -228,3 +253,36 @@ void ensureEndl(TextStream &s) if (s.lastChar() != QLatin1Char('\n')) s << '\n'; } + +void rstBold(TextStream &s) +{ + s.putRawString("**"); +} + +void rstBoldOff(TextStream &s) +{ + s.putRawString("**"); + s._setRstFormattingEnd(); +} + +void rstItalic(TextStream &s) +{ + s.putRawChar('*'); +} + +void rstItalicOff(TextStream &s) +{ + s.putRawChar('*'); + s._setRstFormattingEnd(); +} + +void rstCode(TextStream &s) +{ + s.putRawString("``"); +} + +void rstCodeOff(TextStream &s) +{ + s.putRawString("``"); + s._setRstFormattingEnd(); +} diff --git a/sources/shiboken6/ApiExtractor/textstream.h b/sources/shiboken6/ApiExtractor/textstream.h index dff79b939..1e21f55da 100644 --- a/sources/shiboken6/ApiExtractor/textstream.h +++ b/sources/shiboken6/ApiExtractor/textstream.h @@ -46,7 +46,7 @@ public: enum class CharClass { - Other, NewLine, Hash + Other, NewLine, Space, Hash, BackSlash }; explicit TextStream(QIODevice *device, Language l = Language::None); @@ -79,8 +79,7 @@ public: { return m_str.fieldAlignment(); } void setFieldAlignment(QTextStream::FieldAlignment al) { m_str.setFieldAlignment(al); } - void setString(QString *string, QIODeviceBase::OpenMode openMode = QIODeviceBase::ReadWrite) - { m_str.setString(string, openMode); } + void setString(QString *string, QIODeviceBase::OpenMode openMode = QIODeviceBase::ReadWrite); QString *string() const { return m_str.string(); } void flush() { m_str.flush(); } void setDevice(QIODevice *device) { m_str.setDevice(device); } @@ -98,6 +97,9 @@ public: void putInt(int t); void putSizeType(qsizetype t); + void putRawString(const char *s) { m_str << s; } + void putRawChar(char c) { m_str << c; } + TextStream &operator<<(QStringView v) { putString(v); return *this; } TextStream &operator<<(QChar c) { putChar(c); return *this; } TextStream &operator<<(const char *s) { putString(s); return *this; } @@ -112,6 +114,8 @@ public: void putRepetitiveChars(char c, int count); + void _setRstFormattingEnd(); + protected: void setLastCharClass(CharClass c); @@ -126,6 +130,7 @@ private: int m_tabWidth = 4; int m_indentation = 0; bool m_indentationEnabled = true; + bool m_rstFormattingEnd = false; // just past some **bla** where '\' needs to be enforced Language m_language; }; @@ -152,6 +157,13 @@ void disableIndent(TextStream &s); // Works only for streams on strings void ensureEndl(TextStream &s); +void rstBold(TextStream &s); +void rstBoldOff(TextStream &s); +void rstCode(TextStream &s); +void rstCodeOff(TextStream &s); +void rstItalic(TextStream &s); +void rstItalicOff(TextStream &s); + /// Format an aligned field template <class T> class AlignedField diff --git a/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp b/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp index 4607f3f78..dba24f2fe 100644 --- a/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp +++ b/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp @@ -623,33 +623,57 @@ void QtXmlToSphinx::handleParaTagEnd() void QtXmlToSphinx::handleItalicTag(QXmlStreamReader& reader) { - QXmlStreamReader::TokenType token = reader.tokenType(); - if (token == QXmlStreamReader::StartElement || token == QXmlStreamReader::EndElement) { - m_insideItalic = !m_insideItalic; - m_output << '*'; - } else if (token == QXmlStreamReader::Characters) { + switch (reader.tokenType()) { + case QXmlStreamReader::StartElement: + m_insideItalic = true; + m_output << rstItalic; + break; + case QXmlStreamReader::EndElement: + m_insideItalic = false; + m_output << rstItalicOff; + break; + case QXmlStreamReader::Characters: m_output << escape(reader.text().trimmed()); + break; + default: + break; } } void QtXmlToSphinx::handleBoldTag(QXmlStreamReader& reader) { - QXmlStreamReader::TokenType token = reader.tokenType(); - if (token == QXmlStreamReader::StartElement || token == QXmlStreamReader::EndElement) { - m_insideBold = !m_insideBold; - m_output << "**"; - } else if (token == QXmlStreamReader::Characters) { + switch (reader.tokenType()) { + case QXmlStreamReader::StartElement: + m_insideBold = true; + m_output << rstBold; + break; + case QXmlStreamReader::EndElement: + m_insideBold = false; + m_output << rstBoldOff; + break; + case QXmlStreamReader::Characters: m_output << escape(reader.text().trimmed()); + break; + default: + break; } } void QtXmlToSphinx::handleArgumentTag(QXmlStreamReader& reader) { - QXmlStreamReader::TokenType token = reader.tokenType(); - if (token == QXmlStreamReader::StartElement || token == QXmlStreamReader::EndElement) - m_output << "``"; - else if (token == QXmlStreamReader::Characters) + switch (reader.tokenType()) { + case QXmlStreamReader::StartElement: + m_output << rstCode; + break; + case QXmlStreamReader::EndElement: + m_output << rstCodeOff; + break; + case QXmlStreamReader::Characters: m_output << reader.text().trimmed(); + break; + default: + break; + } } static inline QString functionLinkType() { return QStringLiteral("function"); } |