def do_insert_link(self, *args): link, name, is_image = self.ask_link() if not link: return url = self.parse_link(link) if url.isValid(): url = str(url.toString(NO_URL_FORMATTING)) self.focus_self() with self.editing_cursor() as c: if is_image: c.insertImage(url) else: oldfmt = QTextCharFormat(c.charFormat()) fmt = QTextCharFormat() fmt.setAnchor(True) fmt.setAnchorHref(url) fmt.setForeground(QBrush(self.palette().color(QPalette.ColorRole.Link))) if name or not c.hasSelection(): c.mergeCharFormat(fmt) c.insertText(name or url) else: pos, anchor = c.position(), c.anchor() start, end = min(pos, anchor), max(pos, anchor) for i in range(start, end): cur = self.textCursor() cur.setPosition(i), cur.setPosition(i + 1, QTextCursor.MoveMode.KeepAnchor) cur.mergeCharFormat(fmt) c.setPosition(c.position()) c.setCharFormat(oldfmt) else: error_dialog(self, _('Invalid URL'), _('The url %r is invalid') % link, show=True)
def process_text(state, text, nbsp_format, spell_format, user_data): ans = [] fmt = None if state.is_bold or state.is_italic: fmt = syntax_text_char_format() if state.is_bold: fmt.setFontWeight(QFont.Weight.Bold) if state.is_italic: fmt.setFontItalic(True) last = 0 for m in nbsp_pat.finditer(text): ans.extend([(m.start() - last, fmt), (m.end() - m.start(), nbsp_format)]) last = m.end() if not ans: ans = [(len(text), fmt)] elif last < len(text): ans.append((len(text) - last, fmt)) if do_spell_check and state.tags and user_data.tag_ok_for_spell( state.tags[-1].name): split_ans = [] locale = state.current_lang or dictionaries.default_locale sfmt = QTextCharFormat(spell_format) if fmt is not None: sfmt.merge(fmt) tpos = 0 for tlen, fmt in ans: if fmt is nbsp_format: split_ans.append((tlen, fmt)) else: split_ans.extend( check_spelling(text[tpos:tpos + tlen], tlen, fmt, locale, sfmt, store_locale.enabled)) tpos += tlen ans = split_ans return ans
def parse_text_formatting(text): pos = 0 tokens = [] for m in re.finditer(r'</?([a-zA-Z1-6]+)/?>', text): q = text[pos:m.start()] if q: tokens.append((False, q)) tokens.append((True, (m.group(1).lower(), '/' in m.group()[:2]))) pos = m.end() if tokens: if text[pos:]: tokens.append((False, text[pos:])) else: tokens = [(False, text)] ranges, open_ranges, text = [], [], [] offset = 0 for is_tag, tok in tokens: if is_tag: tag, closing = tok if closing: if open_ranges: r = open_ranges.pop() r[-1] = offset - r[-2] if r[-1] > 0: ranges.append(r) else: if tag in {'b', 'strong', 'i', 'em'}: open_ranges.append([tag, offset, -1]) else: offset += len(tok.replace('&', '&')) text.append(tok) text = ''.join(text) formats = [] for tag, start, length in chain(ranges, open_ranges): fmt = QTextCharFormat() if tag in {'b', 'strong'}: fmt.setFontWeight(QFont.Weight.Bold) elif tag in {'i', 'em'}: fmt.setFontItalic(True) else: continue if length == -1: length = len(text) - start if length > 0: r = QTextLayout.FormatRange() r.format = fmt r.start, r.length = start, length formats.append(r) return text, formats
def do_format_block(self): name = self.sender().block_name with self.editing_cursor() as c: bf = QTextBlockFormat() cf = QTextCharFormat() bcf = c.blockCharFormat() lvl = self.level_for_block_type(name) wt = QFont.Weight.Bold if lvl else None adjust = (0, 3, 2, 1, 0, -1, -1)[lvl] pos = None if not c.hasSelection(): pos = c.position() c.movePosition(QTextCursor.MoveOperation.StartOfBlock, QTextCursor.MoveMode.MoveAnchor) c.movePosition(QTextCursor.MoveOperation.EndOfBlock, QTextCursor.MoveMode.KeepAnchor) # margin values are taken from qtexthtmlparser.cpp hmargin = 0 if name == 'blockquote': hmargin = 40 tmargin = bmargin = 12 if name == 'h1': tmargin, bmargin = 18, 12 elif name == 'h2': tmargin, bmargin = 16, 12 elif name == 'h3': tmargin, bmargin = 14, 12 elif name == 'h4': tmargin, bmargin = 12, 12 elif name == 'h5': tmargin, bmargin = 12, 4 bf.setLeftMargin(hmargin), bf.setRightMargin(hmargin) bf.setTopMargin(tmargin), bf.setBottomMargin(bmargin) bf.setHeadingLevel(lvl) if adjust: bcf.setProperty(QTextFormat.Property.FontSizeAdjustment, adjust) cf.setProperty(QTextFormat.Property.FontSizeAdjustment, adjust) if wt: bcf.setProperty(QTextFormat.Property.FontWeight, wt) cf.setProperty(QTextFormat.Property.FontWeight, wt) c.setBlockCharFormat(bcf) c.mergeCharFormat(cf) c.mergeBlockFormat(bf) if pos is not None: c.setPosition(pos) self.update_cursor_position_actions()
def syntax_text_char_format(*args): ans = QTextCharFormat(*args) ans.setProperty(SYNTAX_PROPERTY, True) return ans
def initializeFormats(cls): baseFormat = QTextCharFormat() baseFormat.setFontFamily('monospace') p = QApplication.instance().palette() for name, color, bold, italic in ( ("normal", None, False, False), ("keyword", p.color(QPalette.ColorRole.Link).name(), True, False), ("builtin", p.color(QPalette.ColorRole.Link).name(), False, False), ("constant", p.color(QPalette.ColorRole.Link).name(), False, False), ("decorator", "#0000E0", False, False), ("comment", "#007F00", False, True), ("string", "#808000", False, False), ("number", "#924900", False, False), ("error", "#FF0000", False, False), ("pyqt", "#50621A", False, False)): fmt = QTextCharFormat(baseFormat) if color is not None: fmt.setForeground(QColor(color)) if bold: fmt.setFontWeight(QFont.Weight.Bold) if italic: fmt.setFontItalic(italic) cls.Formats[name] = fmt
def initializeFormats(self): font_name = gprefs.get('gpm_template_editor_font', None) size = gprefs['gpm_template_editor_font_size'] if font_name is None: font = QFont() font.setFixedPitch(True) font.setPointSize(size) font_name = font.family() Config = self.Config Config["fontfamily"] = font_name pal = QApplication.instance().palette() for name, color, bold, italic in ( ("normal", None, False, False), ("keyword", pal.color(QPalette.ColorRole.Link).name(), True, False), ("builtin", pal.color(QPalette.ColorRole.Link).name(), False, False), ("comment", "#007F00", False, True), ("string", "#808000", False, False), ("number", "#924900", False, False), ("lparen", None, True, True), ("rparen", None, True, True)): Config["%sfontcolor" % name] = color Config["%sfontbold" % name] = bold Config["%sfontitalic" % name] = italic baseFormat = QTextCharFormat() baseFormat.setFontFamily(Config["fontfamily"]) Config["fontsize"] = size baseFormat.setFontPointSize(Config["fontsize"]) for name in ("normal", "keyword", "builtin", "comment", "string", "number", "lparen", "rparen"): format = QTextCharFormat(baseFormat) col = Config["%sfontcolor" % name] if col: format.setForeground(QColor(col)) if Config["%sfontbold" % name]: format.setFontWeight(QFont.Weight.Bold) format.setFontItalic(Config["%sfontitalic" % name]) self.Formats[name] = format
def do_remove_format(self): with self.editing_cursor() as c: c.setBlockFormat(QTextBlockFormat()) c.setCharFormat(QTextCharFormat())
def do_vertical_align(self, which): with self.editing_cursor() as c: fmt = QTextCharFormat() fmt.setVerticalAlignment(which) c.mergeCharFormat(fmt)
def do_strikethrough(self): with self.editing_cursor() as c: fmt = QTextCharFormat() fmt.setFontStrikeOut(not c.charFormat().fontStrikeOut()) c.mergeCharFormat(fmt)
def do_underline(self): with self.editing_cursor() as c: fmt = QTextCharFormat() fmt.setFontUnderline(not c.charFormat().fontUnderline()) c.mergeCharFormat(fmt)
def do_italic(self): with self.editing_cursor() as c: fmt = QTextCharFormat() fmt.setFontItalic(not c.charFormat().fontItalic()) c.mergeCharFormat(fmt)
def do_bold(self): with self.editing_cursor() as c: fmt = QTextCharFormat() fmt.setFontWeight( QFont.Weight.Bold if c.charFormat().fontWeight() != QFont.Weight.Bold else QFont.Weight.Normal) c.mergeCharFormat(fmt)
#!/usr/bin/env python __license__ = 'GPL v3' __copyright__ = '2014, Kovid Goyal <kovid at kovidgoyal.net>' from qt.core import QTextCharFormat NULL_FMT = QTextCharFormat() _pyg_map = None def pygments_map(): global _pyg_map if _pyg_map is None: from pygments.token import Token _pyg_map = { Token: None, Token.Comment: 'Comment', Token.Comment.Preproc: 'PreProc', Token.String: 'String', Token.Number: 'Number', Token.Keyword.Type: 'Type', Token.Keyword: 'Keyword', Token.Name.Builtin: 'Identifier', Token.Operator: 'Statement', Token.Name.Function: 'Function', Token.Literal: 'Constant', Token.Error: 'Error', } return _pyg_map
def do_remove_format(self): with self.editing_cursor() as c: c.setBlockFormat(QTextBlockFormat()) c.setCharFormat(QTextCharFormat()) self.update_cursor_position_actions()
def spell_property(sfmt, locale): s = QTextCharFormat(sfmt) s.setProperty(SPELL_LOCALE_PROPERTY, locale) return s