Reimplement QTextDocument's find method

        Add support for *multiline* regular expressions
345876
def find_multiline_pattern(self, regexp, cursor, findflag):
        """"""
        pattern = to_text_string(regexp.pattern())
        text = to_text_string(self.toPlainText())
        try:
            regobj = re.compile(pattern)
        except sre_constants.error:
            return
        if findflag & QTextDocument.FindBackward:
            # Find backward
            offset = min([cursor.selectionEnd(), cursor.selectionStart()])
            text = text[:offset]
            matches = [_m for _m in regobj.finditer(text, 0, offset)]
            if matches:
                match = matches[-1]
            else:
                return
        else:
            # Find forward
            offset = max([cursor.selectionEnd(), cursor.selectionStart()])
            match = regobj.search(text, offset)
        if match:
            pos1, pos2 = match.span()
            fcursor = self.textCursor()
            fcursor.setPosition(pos1)
            fcursor.setPosition(pos2, QTextCursor.KeepAnchor)
            return fcursor
1272717
def _parse_doc(doc):
    
    lines = doc.split("\n")
    descriptions = list(itertools.takewhile(_checker(_KEYWORDS), lines))

    if len(descriptions) < 3:
        description = lines[0]
    else:
        description = "{0}\n\n{1}".format(
            lines[0], textwrap.dedent("\n".join(descriptions[2:])))

    args = list(itertools.takewhile(
        _checker(_KEYWORDS_OTHERS),
        itertools.dropwhile(_checker(_KEYWORDS_ARGS), lines)))
    argmap = {}
    if len(args) > 1:
        for pair in args[1:]:
            kv = [v.strip() for v in pair.split(":")]
            if len(kv) >= 2:
                argmap[kv[0]] = ":".join(kv[1:])

    return dict(headline=descriptions[0], description=description, args=argmap)
707732
def find( self, flags = 0 ):
        
        # check against the web and text views
        if ( not (self._textEdit or self._webView) ):
            fg = QColor('darkRed')
            bg = QColor('red').lighter(180)
            
            palette = self.palette()
            palette.setColor(palette.Text, fg)
            palette.setColor(palette.Base, bg)
            
            self._searchEdit.setPalette(palette)
            self._searchEdit.setToolTip( 'No Text Edit is linked.' )
            
            return False
        
        if ( self._caseSensitiveCheckbox.isChecked() ):
            flags |= QTextDocument.FindCaseSensitively
        
        if ( self._textEdit and self._wholeWordsCheckbox.isChecked() ):
            flags |= QTextDocument.FindWholeWords
        
        terms = self._searchEdit.text()
        if ( terms != self._lastText ):
            self._lastCursor = QTextCursor()
        
        if ( self._regexCheckbox.isChecked() ):
            terms = QRegExp(terms)
        
        palette = self.palette()
        
        # search on a text edit
        if ( self._textEdit ):
            cursor  = self._textEdit.document().find(terms, 
                                                 self._lastCursor, 
                                                 QTextDocument.FindFlags(flags))
            found   = not cursor.isNull()
            self._lastCursor = cursor
            self._textEdit.setTextCursor(cursor)
        
        elif ( QWebPage ):
            flags = QWebPage.FindFlags(flags)
            flags |= QWebPage.FindWrapsAroundDocument
            
            found = self._webView.findText(terms, flags)
        
        self._lastText = self._searchEdit.text()
        
        if ( not terms or found ):
            fg = palette.color(palette.Text)
            bg = palette.color(palette.Base)
        else:
            fg = QColor('darkRed')
            bg = QColor('red').lighter(180)
        
        palette.setColor(palette.Text, fg)
        palette.setColor(palette.Base, bg)
        
        self._searchEdit.setPalette(palette)
        
        return found
1274803
def rex_text(self, regexp, flags=0, byte=False, default=NULL):
        

        # pylint: disable=no-member
        try:
            match = self.rex_search(regexp, flags=flags, byte=byte)
        except DataNotFound:
            if default is NULL:
                raise DataNotFound('Regexp not found')
            else:
                return default
        else:
            return normalize_space(decode_entities(match.group(1)))
550044
function(matches, index, tokens, regexValue) {
      var i = tokens.length;

      while (--i >= 0) {
        var token = tokens[i];
        var type = token.type;

        if (type === _Comment ||
            type === _WhiteSpace ||
            type === _LineTerminator) {
          continue;
        }

        var value = token.value;
        if (type === _Punctuator) {
          if (value === ')') {
            if (this.isValidRegExpPrefix(tokens, i + 1)) {
              break;
            }
          } else if (regexPrefixRe.test(value)) {
            break;
          }
        } else if ((type === _Keyword && regexPrefixRe.test(value)) ||
                   (type === _Template && value.slice(-2) === '${')) {
          break;
        }

        var parts = regexValue.match(tokenizeNotRegExpRe);
        splice.apply(matches, [index, 1].concat(parts));
        return true;
      }
      return false;
    }
1152784
def find_by_ast(line, version_token="__version__"):  # type: (str,str) -> Optional[str]
    
    if not line:
        return ""
    # clean up line.
    simplified_line = simplify_line(line)

    if simplified_line.startswith(version_token):
        try:
            tree = ast.parse(simplified_line)  # type: Any
            if hasattr(tree.body[0].value, "s"):
                return unicode(tree.body[0].value.s)
            if hasattr(tree.body[0].value, "elts"):
                version_parts = []
                for elt in tree.body[0].value.elts:
                    if hasattr(elt, "n"):
                        version_parts.append(unicode(elt.n))
                    else:
                        version_parts.append(unicode(elt.s))
                return ".".join(version_parts)
            if hasattr(tree.body[0].value, "n"):
                return unicode(tree.body[0].value.n)
            # print(tree)
        except Exception:
            # raise
            return None

    return None
963658
function matchedText(pattern, candidate) {
        ts.Debug.assert(isPatternMatch(pattern, candidate));
        return candidate.substr(pattern.prefix.length, candidate.length - pattern.suffix.length);
    }
547011
def doctype_matches(text, regex):
    
    m = doctype_lookup_re.match(text)
    if m is None:
        return False
    doctype = m.group(2)
    return re.compile(regex, re.I).match(doctype.strip()) is not None
644220
def _filter_by_regex(self, regex, text, group=1):
        """"""
        match = re.search(
            regex,
            text,
            re.MULTILINE
        )

        return match.group(group).strip() if (
            match and match.groups()
        ) else text
637896
def re_filter(text, regexps):
    """"""
    if not regexps:
        return text

    matched_text = []
    compiled_regexps = [re.compile(x) for x in regexps]
    for line in text:
        if line in matched_text:
            continue

        for regexp in compiled_regexps:
            found = regexp.search(line)
            if found and found.group():
                matched_text.append(line)

    return matched_text or text
615783
def find_multiple(line, lookup):
        
        match = re.search(lookup, line)
        if match:
            ret = []
            for i in range(1, len(match.groups()) + 1):
                ret.append(match.group(i))
            if ret:
                return ret
        return False
465744
function extractJavadoc(str) {
  var lines = str
    .replace(/^[ \t]+|[ \t]+$/g, '') // Trim whitespace.
    .split('\n').map(function (line, i) {
      return i ? line.replace(/^\s*\*\s?/, '') : line;
    });
  while (!lines[0]) {
    lines.shift();
  }
  while (!lines[lines.length - 1]) {
    lines.pop();
  }
  return lines.join('\n');
}
1085220
def smart_fitting_predicate(
    page_width,
    ribbon_frac,
    min_nesting_level,
    max_width,
    triplestack
):
    
    chars_left = max_width

    while chars_left >= 0:
        if not triplestack:
            return True

        indent, mode, doc = triplestack.pop()

        if doc is NIL:
            continue
        elif isinstance(doc, str):
            chars_left -= len(doc)
        elif isinstance(doc, Concat):
            # Recursive call in Strictly Pretty: docs within Concat
            # are processed in order, with keeping the current
            # indentation and mode.
            # We want the leftmost element at the top of the stack,
            # so we append the concatenated documents in reverse order.
            triplestack.extend(
                (indent, mode, doc)
                for doc in reversed(doc.docs)
            )
        elif isinstance(doc, Annotated):
            triplestack.append((indent, mode, doc.doc))
        elif isinstance(doc, Fill):
            # Same as the Concat case.
            triplestack.extend(
                (indent, mode, doc)
                for doc in reversed(doc.docs)
            )
        elif isinstance(doc, Nest):
            # Nest is a combination of an indent and a doc.
            # Increase indentation, then add the doc for processing.
            triplestack.append((indent + doc.indent, mode, doc.doc))
        elif isinstance(doc, AlwaysBreak):
            return False
        elif doc is HARDLINE:
            # In the fast algorithm, when we see a line,
            # we return True. Here, as long as the minimum indentation
            # level is satisfied, we continue processing the next line.
            # This causes the longer runtime.
            if indent > min_nesting_level:
                chars_left = page_width - indent
            else:
                return True
        elif isinstance(doc, FlatChoice):
            if mode is FLAT_MODE:
                triplestack.append((indent, mode, doc.when_flat))
            elif mode is BREAK_MODE:
                triplestack.append((indent, mode, doc.when_broken))
            else:
                raise ValueError
        elif isinstance(doc, Group):
            # Group just changes the mode.
            triplestack.append((indent, FLAT_MODE, doc.doc))
        elif isinstance(doc, Contextual):
            ribbon_width = max(0, min(page_width, round(ribbon_frac * page_width)))

            evaluated_doc = doc.fn(
                indent=indent,
                column=max_width - chars_left,
                page_width=page_width,
                ribbon_width=ribbon_width,
            )
            normalized = normalize_doc(evaluated_doc)
            triplestack.append((indent, mode, normalized))
        elif isinstance(doc, SAnnotationPush):
            continue
        elif isinstance(doc, SAnnotationPop):
            continue
        else:
            raise ValueError((indent, mode, doc))

    return False
458047
def search(pattern, text):
    ''
    return re.compile(str(pattern)).search(str(text))
718199
function findContext(doc, data) {
    var before = data.context.slice(0, data.contextOffset).split("\n");
    var startLine = data.start.line - (before.length - 1);
    var start = Pos(startLine, (before.length == 1 ? data.start.ch : doc.getLine(startLine).length) - before[0].length);

    var text = doc.getLine(startLine).slice(start.ch);
    for (var cur = startLine + 1; cur < doc.lineCount() && text.length < data.context.length; ++cur)
      text += "\n" + doc.getLine(cur);
    if (text.slice(0, data.context.length) == data.context) return data;

    var cursor = doc.getSearchCursor(data.context, 0, false);
    var nearest, nearestDist = Infinity;
    while (cursor.findNext()) {
      var from = cursor.from(), dist = Math.abs(from.line - start.line) * 10000;
      if (!dist) dist = Math.abs(from.ch - start.ch);
      if (dist < nearestDist) { nearest = from; nearestDist = dist; }
    }
    if (!nearest) return null;

    if (before.length == 1)
      nearest.ch += before[0].length;
    else
      nearest = Pos(nearest.line + (before.length - 1), before[before.length - 1].length);
    if (data.start.line == data.end.line)
      var end = Pos(nearest.line, nearest.ch + (data.end.ch - data.start.ch));
    else
      var end = Pos(nearest.line + (data.end.line - data.start.line), data.end.ch);
    return {start: nearest, end: end};
  }
1160843
def _filter(self, text):
        """"""

        if self.line_endings:
            text = self.norm_nl(text)

        new_text = []
        index = 0
        last = 0
        end = len(text)
        while index < end:
            m = self.escapes.match(text, pos=index) if self.escapes else None
            if m:
                index = m.end(0)
                continue
            handled = False
            for delimiter in self.delimiters:
                m = delimiter[0].match(text, pos=index)
                if m:
                    if self.context_visible_first is True:
                        new_text.append(text[last:m.start(0)])
                    else:
                        new_text.append(m.group(delimiter[1]))
                    index = m.end(0)
                    last = index
                    handled = True
                    break
            if handled:
                continue
            index += 1
        if last < end and self.context_visible_first is True:
            new_text.append(text[last:end])

        return ' '.join(new_text)
629167
def document_is_multiline_python(document):
    
    def ends_in_multiline_string():
        """
        ``True`` if we're inside a multiline string at the end of the text.
        """
        delims = _multiline_string_delims.findall(document.text)
        opening = None
        for delim in delims:
            if opening is None:
                opening = delim
            elif delim == opening:
                opening = None
        return bool(opening)

    if '\n' in document.text or ends_in_multiline_string():
        return True

    def line_ends_with_colon():
        return document.current_line.rstrip()[-1:] == ':'

    # If we just typed a colon, or still have open brackets, always insert a real newline.
    if line_ends_with_colon() or \
            (document.is_cursor_at_the_end and
             has_unclosed_brackets(document.text_before_cursor)) or \
            document.text.startswith('@'):
        return True

    # If the character before the cursor is a backslash (line continuation
    # char), insert a new line.
    elif document.text_before_cursor[-1:] == '\\':
        return True

    return False