Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    Unsolved Highlighting multiline text in quotes

    General and Desktop
    2
    9
    223
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • M
      MyNick 0 last edited by Christian Ehrlicher

      Code:

      quotationFormat.setForeground(Qt::darkGreen);
      rule.pattern = QRegularExpression(QStringLiteral("\".*\""));
      rule.format = quotationFormat;
      highlightingRules.append(rule);
      

      highlights text only to the end of the line.
      How to make any number of lines highlighted?

      JonB 1 Reply Last reply Reply Quote 0
      • JonB
        JonB @MyNick 0 last edited by JonB

        @MyNick-0
        Difficult to know when the types of quotationFormat and highlightingRules are not mentioned....

        In the absence of that, regular expression for that is usually

        QStringLiteral("\"(.|\\n)*\"")
        

        Or you can use the QRegularExpression::DotMatchesEverythingOption option from https://doc.qt.io/qt-5/qregularexpression.html#PatternOption-enum as an argument to QRegularExpression() and stick with your original pattern.

        1 Reply Last reply Reply Quote 1
        • M
          MyNick 0 last edited by

          this expression doesn't work for me.

          You need to highlight several lines of subrad, for example:
          "str 1
          str 2
          str 3"

          JonB 1 Reply Last reply Reply Quote 0
          • JonB
            JonB @MyNick 0 last edited by JonB

            @MyNick-0 said in Highlighting multiline text in quotes:

            this expression doesn't work for me.

            Who knows, since you still don't give any context....

            Try matching the regular expression I gave you against a C string like "Hello\\nGoodbye\\nForever".

            1 Reply Last reply Reply Quote 0
            • M
              MyNick 0 last edited by

              i have code from documentation:

              #include "highlighter.h"
              
              Highlighter::Highlighter(QTextDocument *parent)
                  : QSyntaxHighlighter(parent)
              {
                  HighlightingRule rule;
              
                  //functionFormat.setFontItalic(true);
                  //functionFormat.setFontWeight(QFont::Bold);
                  functionFormat.setForeground(QColor(00, 00, 00));
                  rule.pattern = QRegularExpression(QStringLiteral("\\b[A-Za-z0-9_]+(?=\\()"));
                  rule.format = functionFormat;
                  highlightingRules.append(rule);
              
                  keywordFormat.setForeground(QColor(00, 80, 80));
                  keywordFormat.setFontWeight(QFont::Bold);
                  const QString keywordPatternsC[] = {
                      QStringLiteral("\\becho\\b"), QStringLiteral("\\bclass\\b"), QStringLiteral("\\bconst\\b"),
                      QStringLiteral("\\bdouble\\b"), QStringLiteral("\\benum\\b"), QStringLiteral("\\bexplicit\\b"),
                      QStringLiteral("\\bfriend\\b"), QStringLiteral("\\binline\\b"), QStringLiteral("\\bint\\b"),
                      QStringLiteral("\\blong\\b"), QStringLiteral("\\bnamespace\\b"), QStringLiteral("\\boperator\\b"),
                      QStringLiteral("\\bprivate\\b"), QStringLiteral("\\bprotected\\b"), QStringLiteral("\\bpublic\\b"),
                      QStringLiteral("\\bshort\\b"), QStringLiteral("\\bsignals\\b"), QStringLiteral("\\bsigned\\b"),
                      QStringLiteral("\\bslots\\b"), QStringLiteral("\\bstatic\\b"), QStringLiteral("\\bstruct\\b"),
                      QStringLiteral("\\btemplate\\b"), QStringLiteral("\\btypedef\\b"), QStringLiteral("\\btypename\\b"),
                      QStringLiteral("\\bunion\\b"), QStringLiteral("\\bunsigned\\b"), QStringLiteral("\\bvirtual\\b"),
                      QStringLiteral("\\bvoid\\b"), QStringLiteral("\\bvolatile\\b"), QStringLiteral("\\bbool\\b")
                  };
                  for (const QString &pattern : keywordPatterns) {
                      rule.pattern = QRegularExpression(pattern);
                      rule.format = keywordFormat;
                      highlightingRules.append(rule);
                  }
              
                  classFormat.setFontWeight(QFont::Bold);
                  classFormat.setForeground(Qt::darkMagenta);
                  rule.pattern = QRegularExpression(QStringLiteral("\\bQ[A-Za-z]+\\b"));
                  rule.format = classFormat;
                  highlightingRules.append(rule);
              
                  quotationFormat.setForeground(QColor(80, 00, 00));//Qt::darkGreen
                  rule.pattern = QRegularExpression(QStringLiteral("\"(.|\\n)*\""));
                  rule.format = quotationFormat;
                  highlightingRules.append(rule);
              
                  singleLineCommentFormat.setForeground(Qt::gray);
                  rule.pattern = QRegularExpression(QStringLiteral("#[^\n]*|//[^\n]*"));//"//[^\n]*"
                  rule.format = singleLineCommentFormat;
                  highlightingRules.append(rule);
              
                  multiLineCommentFormat.setForeground(Qt::gray);
              
                  commentStartExpression = QRegularExpression(QStringLiteral("/\\*"));
                  commentEndExpression = QRegularExpression(QStringLiteral("\\*/"));
              }
              
              void Highlighter::highlightBlock(const QString &text)
              {
                  for (const HighlightingRule &rule : qAsConst(highlightingRules)) {
                      QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text);
                      while (matchIterator.hasNext()) {
                          QRegularExpressionMatch match = matchIterator.next();
                          setFormat(match.capturedStart(), match.capturedLength(), rule.format);
                      }
                  }
                  setCurrentBlockState(0);
              
                  int startIndex = 0;
                  if (previousBlockState() != 1)
                      startIndex = text.indexOf(commentStartExpression);
              
                  while (startIndex >= 0) {
                      QRegularExpressionMatch match = commentEndExpression.match(text, startIndex);
                      int endIndex = match.capturedStart();
                      int commentLength = 0;
                      if (endIndex == -1) {
                          setCurrentBlockState(1);
                          commentLength = text.length() - startIndex;
                      } else {
                          commentLength = endIndex - startIndex
                                          + match.capturedLength();
                      }
                      setFormat(startIndex, commentLength, multiLineCommentFormat);
                      startIndex = text.indexOf(commentStartExpression, startIndex + commentLength);
                  }
              }
              

              And I use it like this:

              highlighter = new Highlighter(textEdit->document());
              
              1 Reply Last reply Reply Quote 0
              • M
                MyNick 0 last edited by

                My operating system, Windows 7 x64

                JonB 1 Reply Last reply Reply Quote 0
                • JonB
                  JonB @MyNick 0 last edited by

                  @MyNick-0
                  This is a lot of code. I don't know why/whether the multiline does not work for you. I gave you the correct regular expression for you to test out. It's your job to reduce the code to minimal if you are having a problem.

                  Meanwhile, your "#[^\n]*|//[^\n]*" at least is wrong, I don't know whether that has any effect.

                  1 Reply Last reply Reply Quote 0
                  • M
                    MyNick 0 last edited by

                    i am using regex you gave me here:

                    quotationFormat.setForeground(QColor(80, 00, 00));
                    rule.pattern = QRegularExpression(QStringLiteral("\"(.|\\n)*\""));
                    rule.format = quotationFormat;
                    highlightingRules.append(rule);
                    
                    JonB 1 Reply Last reply Reply Quote 0
                    • JonB
                      JonB @MyNick 0 last edited by JonB

                      @MyNick-0
                      I don't know about the behaviour of QSyntaxHighlighter which you have now started mentioning, not mentioned in your topic title or original question. The regular expression I gave should be right as a regular expression.

                      However, in your case of wanting leading & trailing " characters, and * being greedy, you would probably want something more like (even if it works)

                      "\"([^\"]|\\n)*\""
                      

                      Even then it won't work right if your C literal string contain any embedded \" sequences....

                      Start by removing all your code except for this one and only one rule, while you see its behaviour/debug. Test that the reg ex I have given you does work against a multiline string, independent of anything to do with QSyntaxHighlighter.

                      Then, I think but don't know, read carefully what https://doc.qt.io/qt-5/qsyntaxhighlighter.html#details says:

                      Some syntaxes can have constructs that span several text blocks. For example, a C++ syntax highlighter should be able to cope with /*...*/ multiline comments. To deal with these cases it is necessary to know the end state of the previous text block (e.g. "in comment").

                      Since the quoted-string-multiline-format is similar to the C-comment-multiline-format, and the same code you are copying from has special code for that which does not use newline-in-regular-experssion, I'm guessing you need to implement multiline string in an analogous way to how that implements the code for its multiLineCommentFormat? It says:

                      But the multiline comment needs special care due to the design of the QSyntaxHighlighter class.

                      1 Reply Last reply Reply Quote 0
                      • First post
                        Last post