diff options
author | László Németh <nemeth@numbertext.org> | 2022-04-10 19:53:56 +0200 |
---|---|---|
committer | László Németh <nemeth@numbertext.org> | 2022-04-22 20:46:35 +0200 |
commit | 89c34706331984d12af8ce99444d53f19b40b496 (patch) | |
tree | 380263aa37977bd6dfef9065e05f2e6a8ee7bacf | |
parent | 1c924efe1f80207a5e104d755615b1eb9a91d418 (diff) |
LibreLogo: add basic HTML formatting support to LABEL
It's possible to format character spans in text
of LABEL, as bold, italic and underline text
using HTML tags <B>, <I> and <U> and their
lowercase equivalents. For example,
LABEL '<i>Italic, <b>also bold</b></i> and <u>underline</u>.'
Use HTML "<" to avoid of the replacement. For example,
LABEL 'some <i>text</i>'
prints "some <i>text</i>" instead of "some text"
with italic "text" in it.
Change-Id: I70fd97763c6c488eba23c168a541b84cff0c90e4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132786
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
-rw-r--r-- | librelogo/source/LibreLogo/LibreLogo.py | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/librelogo/source/LibreLogo/LibreLogo.py b/librelogo/source/LibreLogo/LibreLogo.py index 804057a9689d..7aa71cac7be0 100644 --- a/librelogo/source/LibreLogo/LibreLogo.py +++ b/librelogo/source/LibreLogo/LibreLogo.py @@ -203,6 +203,7 @@ from com.sun.star.drawing.CircleKind import CUT as __CUT__ from com.sun.star.drawing.CircleKind import ARC as __ARC__ from com.sun.star.awt.FontSlant import NONE as __Slant_NONE__ from com.sun.star.awt.FontSlant import ITALIC as __Slant_ITALIC__ +from com.sun.star.awt.FontUnderline import SINGLE as __Underline_SINGLE__ from com.sun.star.awt import Size as __Size__ from com.sun.star.awt import WindowDescriptor as __WinDesc__ from com.sun.star.awt.WindowClass import MODALTOP as __MODALTOP__ @@ -1270,8 +1271,55 @@ def label(st): _.shapecache[__ACTUAL__] = actual return z -def text(shape, st): +def __get_HTML_format__(orig_st): + "Process HTML-like tags, and return with text and formatting vector" + st = orig_st.replace('<', '\uE000') + if not ('<' in st and '>' in st): + return st.replace('\uE000', '<'), None + tex = "" # characters without HTML tags + pat = [] # bit vectors of the previous characters + # 1st bit: bold + # 2nd bit: italic + # 3rd bit: underline + f = 0 + tags = ['<b>', '</b>', '<i>', '</i>', '<u>', '</u>'] + # store embedding level of the same element to disable it + # only at the most outer closing tag, e.g. <i>a <i>double</i> italic here, too</i> + bit_level = {0: 0, 1: 0, 2: 0} + i = 0 + while i < len(st): + is_tag = False + for j in range(len(tags)): + if st[i:i + 4].lower().startswith(tags[j]): + bit = j // 2 + # opening tag + if j % 2 == 0: + f |= (1 << bit) + bit_level[bit] += 1 + else: + if bit_level[bit] > 0: + bit_level[bit] -= 1 + if bit_level[bit] == 0: + f &= ~(1 << bit) + i += len(tags[j]) - 1 + is_tag = True + break + + if not is_tag: + tex = tex + st[i] + pat.append(f) + i += 1 + + # no tags + if len(st) == len(tex): + pat = None + + return tex.replace('\uE000', '<'), pat + +def text(shape, orig_st): if shape: + # analyse HTML + st, formatting = __get_HTML_format__(orig_st) shape.setString(__string__(st, _.decimal)) c = shape.createTextCursor() c.gotoStart(False) @@ -1281,6 +1329,27 @@ def text(shape, st): c.CharWeight = __fontweight__(_.fontweight) c.CharPosture = __fontstyle__(_.fontstyle) c.CharFontName = _.fontfamily + # has HTML-like formatting + if formatting != None: + prev_format = 0 + c.collapseToStart() + n = 0 # length of the previous text span + formatting.append(0) # add terminating 0 to process last span + for i in formatting: + if i != prev_format: + do_formatting = prev_format != 0 + c.goRight(n, do_formatting) # move cursor with optional selection + if do_formatting: + if prev_format & (1 << 0): + c.CharWeight = 150 + if prev_format & (1 << 1): + c.CharPosture = __Slant_ITALIC__ + if prev_format & (1 << 2): + c.CharUnderline = __Underline_SINGLE__ + c.collapseToEnd() + n = 0 + n += 1 + prev_format = i def sleep(t): _.time = _.time + t |