-----------------------------------------------------------------------------
| 128 | |
| 129 | //----------------------------------------------------------------------------- |
| 130 | QString pqPythonSyntaxHighlighter::Highlight(const QString& text) const |
| 131 | { |
| 132 | int leadingWhiteSpaceLength = 0; |
| 133 | int trailingWhiteSpaceLength = 0; |
| 134 | while (leadingWhiteSpaceLength < text.length() && text.at(leadingWhiteSpaceLength).isSpace()) |
| 135 | { |
| 136 | ++leadingWhiteSpaceLength; |
| 137 | } |
| 138 | |
| 139 | QString result; |
| 140 | if (this->PygmentsModule && leadingWhiteSpaceLength < text.length()) |
| 141 | { |
| 142 | while (trailingWhiteSpaceLength < text.length() && |
| 143 | text.at(text.length() - 1 - trailingWhiteSpaceLength).isSpace()) |
| 144 | { |
| 145 | ++trailingWhiteSpaceLength; |
| 146 | } |
| 147 | QString leadingWhitespace = text.left(leadingWhiteSpaceLength); |
| 148 | QString trailingWhitespace = text.right(trailingWhiteSpaceLength); |
| 149 | |
| 150 | QByteArray bytes = text.trimmed().toUtf8(); |
| 151 | |
| 152 | vtkPythonScopeGilEnsurer gilEnsurer; |
| 153 | vtkSmartPyObject unicode(PyUnicode_DecodeUTF8(bytes.data(), bytes.size(), nullptr)); |
| 154 | vtkSmartPyObject args(Py_BuildValue("OOO", unicode.GetPointer(), this->PythonLexer.GetPointer(), |
| 155 | this->HtmlFormatter.GetPointer())); |
| 156 | vtkSmartPyObject resultingText(PyObject_Call(this->HighlightFunction, args, nullptr)); |
| 157 | |
| 158 | #if PY_VERSION_HEX >= 0x03070000 |
| 159 | char* resultingTextAsCString = const_cast<char*>(PyUnicode_AsUTF8(resultingText)); |
| 160 | #else |
| 161 | const char* resultingTextAsCString = PyUnicode_AsUTF8(resultingText); |
| 162 | #endif |
| 163 | |
| 164 | const QString pygmentsOutput = QString::fromUtf8(resultingTextAsCString); |
| 165 | |
| 166 | // the first span tag always should follow the pre tag like this; <pre ...><span |
| 167 | const int startOfPre = pygmentsOutput.indexOf(">", pygmentsOutput.indexOf("<pre")) + 1; |
| 168 | const int endOfPre = pygmentsOutput.lastIndexOf("</pre>"); |
| 169 | const QString startOfHtml = pygmentsOutput.left(startOfPre); |
| 170 | const QString formatted = pygmentsOutput.mid(startOfPre, endOfPre - startOfPre).trimmed(); |
| 171 | const QString endOfHtml = pygmentsOutput.right(pygmentsOutput.length() - endOfPre).trimmed(); |
| 172 | |
| 173 | // The <pre ...> tag will ignore a newline immediately following the >, |
| 174 | // so insert one to be ignored. Similarly, the </pre> will ignore a |
| 175 | // newline immediately preceding it, so put one in. These quirks allow |
| 176 | // inserting newlines at the beginning and end of the text and took a |
| 177 | // long time to figure out. |
| 178 | result = QString("%1\n%2%3%4\n%5") |
| 179 | .arg(startOfHtml, leadingWhitespace, formatted, trailingWhitespace, endOfHtml); |
| 180 | } |
| 181 | |
| 182 | return result; |
| 183 | } |
| 184 | |
| 185 | //----------------------------------------------------------------------------- |
| 186 | void pqPythonSyntaxHighlighter::ConnectHighligter() const |
no test coverage detected