Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/LibreOffice/librelogo/source/LibreLogo/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 334 kB image not shown  

Quelle  LibreLogo.py   Sprache: Python

 
# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
import sys
import os
import uno
import unohelper
import re
import random
import traceback
import itertools
import threading
import time as __time__
from math import pi, sin, cos, asin, hypot

from com.sun.star.awt import Point as __Point__
from com.sun.star.awt import Gradient as __Gradient__
from com.sun.star.awt.GradientStyle import LINEAR as __GradientStyle_LINEAR__
from com.sun.star.drawing import LineDash as __LineDash__
from com.sun.star.drawing import Hatch as __Hatch__
from com.sun.star.drawing import PolyPolygonBezierCoords as __Bezier__
from com.sun.star.text.TextContentAnchorType import AT_PAGE as __AT_PAGE__
from com.sun.star.text.WrapTextMode import THROUGH as __THROUGH__
from com.sun.star.drawing.LineCap import BUTT as __Cap_NONE__
from com.sun.star.drawing.LineCap import ROUND as __Cap_ROUND__
from com.sun.star.drawing.LineCap import SQUARE as __Cap_SQUARE__
from com.sun.star.drawing.LineJoint import NONE as __Joint_NONE__
from com.sun.star.drawing.LineJoint import BEVEL as __BEVEL__
from com.sun.star.drawing.LineJoint import MITER as __MITER__
from com.sun.star.drawing.LineJoint import ROUND as __ROUNDED__
from com.sun.star.drawing.FillStyle import NONE as __FillStyle_NONE__
from com.sun.star.drawing.FillStyle import GRADIENT as __FillStyle_GRADIENT__
from com.sun.star.drawing.LineStyle import NONE as __LineStyle_NONE__
from com.sun.star.drawing.LineStyle import SOLID as __LineStyle_SOLID__
from com.sun.star.drawing.LineStyle import DASH as __LineStyle_DASHED__
from com.sun.star.drawing.DashStyle import RECT as __DashStyle_RECT__
from com.sun.star.drawing.CircleKind import FULL as __FULL__
from com.sun.star.drawing.CircleKind import SECTION as __SECTION__
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.FontStrikeout import SINGLE as __Strikeout_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__
from com.sun.star.awt.VclWindowPeerAttribute import OK as __OK__
from com.sun.star.awt.VclWindowPeerAttribute import OK_CANCEL as __OK_CANCEL__
from com.sun.star.awt.VclWindowPeerAttribute import YES_NO_CANCEL as __YES_NO_CANCEL_# OK_CANCEL, YES_NO, RETRY_CANCEL, DEF_OK, DEF_CANCEL, DEF_RETRY, DEF_YES, DEF_NO
from com.sun.star.awt.PushButtonType import OK as __Button_OK__
from com.sun.star.awt.PushButtonType import CANCEL as __Button_CANCEL__
from com.sun.star.util.MeasureUnit import APPFONT as __APPFONT__
from com.sun.star.beans import PropertyValue as __property__
from com.sun.star.lang import Locale

__lng__ = {}

def __trace__():
    if 'PYUNO_LOGLEVEL' in os.environ:
        print(traceback.format_exc())

# get localized commands and messages
def __l12n__(lng):
    global __lng_fallback__
    try:
        return __lng__[lng]
    except Exception:
        try:
            # load resource file
            __lng__[lng] = dict([[i.decode("unicode-escape").split("=")[0].strip(), i.decode("unicode-escape").split("=")[1].strip().strip("|")] for i in open(__lngpath__ + "LibreLogo_" + lng + ".properties"'rb').readlines() if b"=" in i])
            return __lng__[lng]
        except Exception:
            try:
                # or use embedded fallback resource dictionary
                __lng__[lng] = {}
                for i in __lng_fallback__:
                    try:
                        __lng__[lng][i] = __lng_fallback__[i][lng]
                    except Exception:
                        try:
                            __lng__[lng][i] = __lng_fallback__[i][lng.split('_')[0]]
                        except Exception:
                            __lng__[lng][i] = __lng_fallback__[i]["en_US"]
                return __lng__[lng]
            except Exception:
                __trace__()
                return None

try:
    urebootstrap = os.environ["URE_BOOTSTRAP"]
except Exception:
    # starting in command line updates embedded fallback language dictionary
    print("Update fallback language resource using property file arguments")
    for i in sys.argv[1:]:
        r = re.match("^(.*)LibreLogo_(.*)[.]properties$", i)
        __lngpath__= r.group(1)
        __l12n__(r.group(2))
    fallback = {}

    # fallback of fallback is en_US
    for i in __lng__["en_US"]:
        fallback[i] = { "en_US": __lng__["en_US"][i] }

    # create fallback dictionary
    for i in __lng__:
        dif = 0
        for j in __lng__[i]:
            if __lng__[i][j] != __lng__["en_US"][j]:
                fallback[j][i] = __lng__[i][j]
                dif = dif + 1
        print(i, dif)

    # update fallback resource data in this program file
    import fileinput

    for line in fileinput.input(sys.argv[0], inplace=True):
        if re.match("^__lng_fallback__", line):
            print("__lng_fallback__ = {")
            # break it (CPython has problem with very long Unicode line)
            for i in fallback:
                print("'%s':%s," % (i, str(fallback[i])))
            print("}")
            sys.exit(1)
        else:
            print(line.rstrip("\n")),

if "vnd.sun.star.pathname" in urebootstrap:
    __lngpath__ = re.sub(r"^vnd.sun.star.pathname:(.*)program(/|\\)fundamental([.]ini|rc)$""\\1", urebootstrap)
else:
    # A way to know if we use MacOs
    if "Resources" in urebootstrap:
        __lngpath__ = unohelper.fileUrlToSystemPath(re.sub("fundamentalrc$""", urebootstrap))
    else:
        __lngpath__ = unohelper.fileUrlToSystemPath(re.sub("program/(fundamental.ini|fundamentalrc)$""share", urebootstrap))
__lngpath__ = __lngpath__ + "/Scripts/python/LibreLogo/".replace("/", os.sep)
__translang__ = "am|ca|cs|de|dk|el|en|eo|es|et|fr|hu|it|ja|nl|no|pl|pt|ru|se|sl" # FIXME supported languages for language guessing, expand this list, according to the localizations
__docs__ = {}
__prevcode__ = None
__prevlang__ = None
__prevcompiledcode__ = None
__thread__ = None
__lock__ = threading.Lock()
__halt__ = False
__compiled__ = ""
__group__ = 0
__groupstack__ = []
__grouplefthang__ = 0
__comp__ = {}
__strings__ = []
__colors__ = {}
__COLORS__ = ['BLACK', 0x000000], ['SILVER', 0xc0c0c0], ['GRAY', 0x808080], \
    ['WHITE', 0xffffff], ['MAROON', 0x800000], ['RED', 0xff0000], \
    ['PURPLE', 0x800080], ['FUCHSIA', 0xff00ff], ['GREEN', 0x008000], \
    ['LIME', 0x00ff00], ['OLIVE', 0x808000], ['YELLOW', 0xffff00], \
    ['NAVY', 0x000080], ['BLUE', 0x0000ff], ['TEAL', 0x008080], \
    ['AQUA', 0x00ffff], ['PINK', 0xffc0cb], ['TOMATO', 0xff6347], \
    ['ORANGE', 0xffa500], ['GOLD', 0xffd700], ['VIOLET', 0x9400d3], \
    ['SKYBLUE', 0x87ceeb], ['CHOCOLATE', 0xd2691e], ['BROWN', 0xa52a2a], \
    ['INVISIBLE', 0xffffffff]
__NORMCOLORS__ = [[[255, 255, 0], 0, -11, 1, -11],
    [[255, 128, 0], 1, 116, 1, -33], [[255, 0, 0], 1, 95, 2, 42],
    [[255, 0, 255], 2, -213, 0, -106], [[0, 0, 255], 0, 148, 1, 127],
    [[0, 255, 255], 1, -128, 2, -63], [[0, 255, 0], 2, 192, 0, 244]]
__STRCONST__ = [i[0] for i in __COLORS__] + ['NONE''BEVEL''MITER''ROUNDED''SOLID''DASH''DOTTED''BOLD''ITALIC''UPRIGHT''NORMAL'"HOUR""PT""INCH""MM""CM"]
__SLEEP_SLICE_IN_MILLISECONDS__ = 500
__PT_TO_TWIP__ = 20
__MM_TO_PT__ = 1/(25.4/72)
__MM10_TO_TWIP__ = 1/(2540.0/72/20) # 0.01 mm to twentieth point
__FILLCOLOR__ = 0x8000cc00
__LINEWIDTH__ = 0.5 * __PT_TO_TWIP__
__ENCODED_STRING__ = "_s_%s___"
__ENCODED_COMMENT__ = "_c_%s___"
__DECODE_STRING_REGEX__ = "_s_([0-9]+)___"
__DECODE_COMMENT_REGEX__ = "_c_([0-9]+)___"
__LINEBREAK__ = "#_@L_i_N_e@_#"
__TURTLE__ = "turtle"
__ACTUAL__ = "actual"
__BASEFONTFAMILY__ = "Linux Biolinum G"
__LineStyle_DOTTED__ = 2
# LABEL supports font features with the simplified syntax <FEATURE>text</FEATURE>, e.g.
#   LABEL "Small caps: <smcp>text</smcp>"
# prints "Small caps: TEXT", where TEXT is small capital, if that feature is supported by the font
# See https://en.wikipedia.org/wiki/List_of_typographic_features
__match_fontfeatures__ = re.compile( r"(
 # OpenType
 "abvf|abvm|abvs|blwf|blwm|blws|pref|pres|psts|pstf|dist|akhn|haln|half|nukt|rkrf|rphf|vatu|cjct|cfar|"
 "smpl|trad|tnam|expt|hojo|nlck|jp78|jp83|jp90|jp04|hngl|ljmo|tjmo|vjmo|fwid|hwid|halt|twid|qwid|pwid|palt|pkna|ruby|hkna|vkna|cpct|"
 "curs|jalt|mset|rclt|rlig|isol|init|medi|med2|fina|fin2|fin3|falt|stch|"
 "lnum|onum|pnum|tnum|frac|afrc|dnom|numr|sinf|zero|mgrk|flac|dtls|ssty|"
 "smcp|c2sc|pcap|c2pc|unic|cpsp|case|ital|ordn|"
 "valt|vhal|vpal|vert|vrt2|vrtr|vkrn|ltra|ltrm|rtla|rtlm"
 "aalt|swsh|cswh|calt|hist|locl|rand|nalt|cv[0-9][0-9]|salt|ss[01][0-9]|ss20|subs|sups|titl|rvrn|clig|dlig|hlig|liga"
 "ccmp|kern|mark|mkmk|opbd|lfbd|rtbd|"
 # Linux Libertine G
 "size|ornm|ingl|algn|arti|caps|circ|dash|dbls|foot|frsp|grkn|hang|itlc|ligc|minu|nfsp|para|quot|texm|thou|vari)((=.*)?>)", re.IGNORECASE )
# LABEL localized color tags, e.g. <red>text in red</red>
__match_localized_colors__ = {}
# LABEL not localized tags (localized translated to these):
__match_tags__ = [re.compile(i, re.IGNORECASE) for i in [r'<(b|strong)>', r'', r'<(i|em)>', r''''''
, r'<(s|del)>', r'''''''''', r'<(fontcolor) ([^<>]*)>', r'', r'<(fillcolor) ([^<>]*)>', r'', r'<(fontfamily) ([^<>]*)>', r'', r'<(fontfeature) ([^<>]*)>', r']*)>', r'<(fontheight) ([^<>]*)>', r'']]

class __Doc__:
    def __init__(self, doc):
        self.doc = doc
        self.secure = False
        try:
            self.drawpage = doc.DrawPage # Writer
        except Exception:
            self.drawpage = doc.DrawPages.getByIndex(0) # Draw, Impress
        self.shapecache = {}
        self.shapecount = itertools.count()
        self.time = 0
        self.zoomvalue = 0
        self.lockturtle = False
        self.fixSVG = False
        self.initialize()

    def initialize(self):
        self.pen = 1
        self.pencolor = 0
        self.pensize = __LINEWIDTH__
        self.linestyle = __LineStyle_SOLID__
        self.linejoint = __ROUNDED__
        self.linecap = __Cap_NONE__
        self.oldlc = 0
        self.oldlw = 0
        self.oldls = __LineStyle_SOLID__
        self.oldlj = __ROUNDED__
        self.oldlcap = __Cap_NONE__
        self.continuous = True
        self.areacolor = __FILLCOLOR__
        self.t10y = int((__FILLCOLOR__ >> 24) / (255.0/100))
        self.hatch = None
        self.textcolor = 0
        self.fontfamily = __BASEFONTFAMILY__
        self.fontheight = 12
        self.fontweight = 100
        self.fontstyle = 0
        self.points = []

def __getprop__(name, value):
    p, p.Name, p.Value = __property__(), name, value
    return p

__uilocale__ = uno.getComponentContext().getValueByName("/singletons/com.sun.star.configuration.theDefaultProvider").\
    createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess",\
    (__getprop__("nodepath""/org.openoffice.Setup/L10N"),)).getByName("ooLocale") + '-' # handle missing Country of locale 'eo'

# dot for dotted line (implemented as an array of dot-headed arrows, because PostScript dot isn't supported by Writer)
def __gendots__(n):
    return [__Point__(round(sin(360.0/n * i * pi/180.0) * 600), round(cos(360.0/n * i * pi/180) * 600)) for i in range(n)]
__bezierdot__ = __Bezier__()
__bezierdot__.Coordinates = (tuple(__gendots__(32)),)
__bezierdot__.Flags = ((0,) * 32,)

# turtle shape
__TURTLESHAPE__ = [tuple([(__Point__(-120, 130), __Point__(-245, 347), __Point__(-291, 176), ), (__Point__(0, -500), __Point__(126, -375), __Point__(0, -250), __Point__(-124, -375), ), (__Point__(295, 170), __Point__(124, 124), __Point__(250, 340), ), (__Point__(466, -204), __Point__(224, -269), __Point__(71, -180), __Point__(313, -116), ), (__Point__(-75, -175), __Point__(-292, -300), __Point__(-417, -83), ), (__Point__(250, 0), __Point__(0, -250), __Point__(-250, 0), __Point__(0, 250), )] +
            [(i,) for i in __gendots__(32)] + # single points for wider selection
            [(__Point__(0, 0),)]), # last point for position handling
            ((__Point__(0, 0),),)] # hidden turtle (single point to draw at the left border of the page area)

def __getdocument__():
    global __docs__, _
    # The XSCRIPTCONTEXT object is part of the UNO (Universal Network Objects)
    # API provided by LibreOffice, which allows scripting languages like Python
    # to interact with LibreOffice's underlying functionality. It provides a
    # bridge between the scripting environment and the LibreOffice application,
    # making it possible for scripts to control and extend the functionality of LibreOffice.

    # Because XSCRIPTCONTEXT is automatically available in LibreOffice Python
    # scripts, developers can directly use it to access the LibreOffice API
    # without needing to define it themselves, simplifying script development
    # and making it easier to work with LibreOffice's features and capabilities._

    # It would be good to use a linter that can be told to ignore this
    # "undefined variable" in the code (like flake8 or ruff) using # noqa: F821
    doc = XSCRIPTCONTEXT.getDocument() # noqa: F821
    try:
        _ = __docs__[doc.RuntimeUID]
    except Exception:
        _ = __Doc__(doc)
        __docs__[doc.RuntimeUID] = _

# input function, result: input string or 0
def Input(s):
    global __halt__
    try:
        ctx = uno.getComponentContext()
        smgr = ctx.ServiceManager

        # dialog
        d = smgr.createInstanceWithContext("com.sun.star.awt.UnoControlDialogModel", ctx)
        ps = _.doc.CurrentController.Frame.ContainerWindow.getPosSize()
        lo = _.doc.CurrentController.Frame.ContainerWindow.convertSizeToLogic(__Size__(ps.Width, ps.Height), __APPFONT__)
        d.PositionX, d.PositionY, d.Width, d.Height = lo.Width/2 - 75, lo.Height/2 - 25, 150, 50

        # label
        l = d.createInstance("com.sun.star.awt.UnoControlFixedTextModel" )

        if type(s) is list:
            s = s[0]
        l.PositionX, l.PositionY, l.Width, l.Height, l.Name, l.TabIndex, l.Label = 5, 4, 140, 14, "l1", 2, s

        # textbox or combobox
        e = d.createInstance("com.sun.star.awt.UnoControlEditModel")
        e.PositionX, e.PositionY, e.Width, e.Height, e.Name, e.TabIndex = 5, 14, 140, 12, "e1", 0

        # buttons
        b = d.createInstance( "com.sun.star.awt.UnoControlButtonModel" )
        b.PositionX, b.PositionY, b.Width, b.Height, b.Name, b.TabIndex, b.PushButtonType, b.DefaultButton =  55, 32, 45, 14, "b1", 1, __Button_OK__, True
        b2 = d.createInstance( "com.sun.star.awt.UnoControlButtonModel" )
        b2.PositionX, b2.PositionY, b2.Width, b2.Height, b2.Name, b2.TabIndex, b2.PushButtonType = 100, 32, 45, 14, "b2", 1, __Button_CANCEL__

        # insert the control models into the dialog model
        d.insertByName( "l1", l)
        d.insertByName( "b1", b)
        d.insertByName( "b2", b2)
        d.insertByName( "e1", e)

        # create the dialog control and set the model
        controlContainer = smgr.createInstanceWithContext("com.sun.star.awt.UnoControlDialog", ctx)
        controlContainer.setModel(d)

        # create a peer
        toolkit = smgr.createInstanceWithContext("com.sun.star.awt.ExtToolkit", ctx)
        controlContainer.setVisible(False)
        controlContainer.createPeer(toolkit, None)

        # execute it
        inputtext = controlContainer.execute()
        if inputtext:
            inputtext = e.Text
        else:
            # Cancel button
            __halt__ = True

        # dispose the dialog
        controlContainer.dispose()
        # stop program at pressing Cancel
        __checkhalt__()
        return inputtext
    except Exception:
        __trace__()

def __string__(s, decimal = None): # convert decimal sign, localized BOOL and SET
    if not decimal:
        decimal = _.decimal
    if decimal == ',' and type(s) is float:
        return str(s).replace("."",")
    if type(s) in [list, tuple, dict, set]:
        s = re.sub("(?u)(['\"])(([^'\"]|\\['\"])*)(?, __encodestring__, str(s)) # XXX fix double '\'\"'
        if decimal == ',':
            s = s.replace("."",")
        return re.sub(__DECODE_STRING_REGEX__, __decodestring__, \
            s.replace('set', __locname__('SET')).replace('True', __locname__('TRUE')).replace('False', __locname__('FALSE')))
    if type(s) in [str]:
        return s
    elif type(s) is bool:
        return __locname__(str(s).upper())
    return str(s)

def Print(s):
    global __halt__
    s = __string__(s, _.decimal)
    if not MessageBox(_.doc.CurrentController.Frame.ContainerWindow, s[:500] + s[500:5000].replace('\n'' '), """messbox", __OK_CANCEL__):
        # stop program at pressing Cancel
        __halt__ = True
        __checkhalt__()

def MessageBox(parent, message, title, msgtype = "messbox", buttons = __OK__):
    msgtypes = ("messbox""infobox""errorbox""warningbox""querybox")
    if msgtype not in msgtypes:
        msgtype = "messbox"
    d = __WinDesc__()
    d.Type = __MODALTOP__
    d.WindowServiceName = msgtype
    d.ParentIndex = -1
    d.Parent = parent
    d.WindowAttributes = buttons
    tk = parent.getToolkit()
    msgbox = tk.createWindow(d)
    msgbox.MessageText = message
    if title:
        msgbox.CaptionText = title
    return msgbox.execute()

def Random(r):
    try:
        return r * random.random()
    except Exception:
        return list(r)[int(random.random() * len(r))]

def to_ascii(s):
    return s.encode("unicode-escape").decode("utf-8").replace("\\u""__u__").replace(r"\x""__x__")

def to_unicode(s):
    return bytes(s.replace("__x__", r"\x").replace("__u__""\\u"), "ascii").decode("unicode-escape")

def __locname__(name, l = -1):
    if l == -1:
        l = _.lng
    for i in __l12n__(l):
        if i == name.upper():
            return __l12n__(l)[i].split("|")[0] # return with the first localized name
    return to_unicode(name)

def __getcursor__(fulltext):
    realselection = False
    try:
        text = _.doc.getCurrentController().getViewCursor().getText().createTextCursor() # copy selection (also in frames)
        text.gotoRange(_.doc.getCurrentController().getViewCursor(), False)
        if fulltext:
            1/len(text.getString()) # exception, if zero length
        realselection = True
    except Exception:
        text = _.doc.getText().createTextCursorByRange(_.doc.getText().getStart())
        text.gotoEnd(True)
    return text, realselection

def __translate__(arg = None):
    global _
    __getdocument__()
    selection = __getcursor__(True)[0]
    __initialize__()
    __setlang__()
    # detect language
    text = selection.getString()
    # remove comments and strings
    text = re.sub(r"[ ]*;[^\n]*""", re.sub(r"['„“‘«»「][^\n'”“‘’«»」]*['”“‘’«»」]""", re.sub(r"^[ \t]*[;#][^\n]*", "", text)))
    text = " ".join(set(re.findall(r"(?u)\w+", text)) - set(re.findall(r"(?u)\w*\d+\w*", text))).lower()  # only words
    ctx = uno.getComponentContext()
    guess = ctx.ServiceManager.createInstanceWithContext("com.sun.star.linguistic2.LanguageGuessing", ctx)
    guess.disableLanguages(guess.getEnabledLanguages())
    guess.enableLanguages(tuple([Locale(i, """"for i in __translang__.split("|")]))
    guess = guess.guessPrimaryLanguage(text, 0, len(text))
    try:
        l = {'cs''cs_CZ''el''el_GR''en''en_US''pt''pt_BR'}[guess.Language]
    except Exception:
        l = guess.Language + '_' + guess.Language.upper()
    lang = __l12n__(l)
    if not lang:
        lang = __l12n__(guess.Language)
        if not lang:
            lang = __l12n__(_.lng)
            if not lang:
                lang = __l12n__("en_US")
    lq = '\'' + lang['LEFTSTRING'].replace("|", "")
    rq = '\'' + lang['RIGHTSTRING'].replace("|", "")

    text = re.sub(r"^(([ \t]*[;#][^\n]*))", __encodecomment__, text)
    text = re.sub("(?u)([%s])((?:[^\n%s]|\\\\[%s])*)(? % (lq, rq, rq, rq), __encodestring__, selection.getString())
    text = re.sub(r'(?u)(?, __encodestring__, text)
    text = re.sub(r";(([^\n]*))", __encodecomment__, text)

    # translate the program to the language of the document FIXME space/tab
    exception = ['DECIMAL']
    in1 = lang['IN'].upper()
    in2 = __l12n__(_.lng)['IN'].split("|")[0].upper()
    if in1[0] == '-' and in2[0] != '-'# "for x y-in" -> "for x in y"
        exception += ['IN']
        text = re.sub(r"(?ui)\b((?:%s) +:?\w+) +([^\n]+)(?:%s) +(?=[\[] |[\[]\n)" % (lang['FOR'], in1), "\\1 %s \\2 " % in2, text)
        text = re.sub(r"(?ui)(:?\b\w+|[\[][^[\n]*])\b(?:%s)\b" % in1, "%s \\1" % in2, text)
    elif in1[0] != '-' and in2[0] == '-'# "for x in y" -> "for x y-in"
        exception += ['IN']
        text = re.sub(r"(?ui)(?<=\n)((?:%s)\b +:?\w+) +(?:%s) +([^\n]+?) +(?=[\[] |[\[]\n)" % (lang['FOR'], in1), "\\1 \\2%s " % in2, text)
        text = re.sub(r"(?ui)(? % in1, "\\1%s" % in2, text)
    for i in set(lang) - set(exception):
        text = re.sub(r'(?ui)(? % lang[i], __l12n__(_.lng)[i].split("|")[0].upper(), text)
    text = re.sub(r"(?<=\d)[%s](?=\d)" % lang['DECIMAL'], __l12n__(_.lng)['DECIMAL'], text)

    # decode strings and comments
    quoted = u"(?ui)(?<=%s)(%%s)(?=%s)" % (__l12n__(_.lng)['LEFTSTRING'][0], __l12n__(_.lng)['RIGHTSTRING'][0])
    text = re.sub(__DECODE_STRING_REGEX__, __decodestring2__, text)
    for i in __STRCONST__:
        text = re.sub(quoted % lang[i], __l12n__(_.lng)[i].split("|")[0].upper(), text)
    text = re.sub(__DECODE_COMMENT_REGEX__, __decodecomment__, text)
    if _.doc.getText().compareRegionStarts(selection.getStart(), _.doc.getText().getStart()) == 0:
        pagebreak = True
        selection.setString("\n" + text.lstrip("\n"))
    else:
        pagebreak = False
        selection.setString(text)
    # convert to paragraphs
    __dispatcher__(".uno:ExecuteSearch", (__getprop__("SearchItem.SearchString", r"\n"), __getprop__("SearchItem.ReplaceString", r"\n"), \
        __getprop__("Quiet"True), __getprop__("SearchItem.Command", 3), __getprop__("SearchItem.StyleFamily", 2), \
        __getprop__("SearchItem.AlgorithmType", 1), __getprop__("SearchItem.AlgorithmType2", 2), __getprop__("SearchItem.SearchFlags", 0)))
    # set 2-page layout
    if pagebreak:
        selection.getStart().BreakType = 4
    __dispatcher__(".uno:ZoomPage")

def __get_time__():
    return __time__.process_time() - _.start_time

class LogoProgram(threading.Thread):
    def __init__(self, code):
        self.code = code
        threading.Thread.__init__(self)

    def secure(self):
        # 0 = secure
        if _.secure:
            return 0

        # 1 = forms, fields or embedded objects are forbidden
        if _.doc.DrawPage.Forms.getCount() > 0 or _.doc.getTextFields().createEnumeration().hasMoreElements() or _.doc.getEmbeddedObjects().getCount() > 0:
            return 1

        # 2 = hyperlinks with script events
        nodes = _.doc.Text.createEnumeration()
        while nodes.hasMoreElements():
            node = nodes.nextElement()
            if node.supportsService("com.sun.star.text.Paragraph"):
                portions = node.createEnumeration()
                while portions.hasMoreElements():
                    portion = portions.nextElement()
                    if portion.PropertySetInfo.hasPropertyByName("HyperLinkEvents"):
                        events = portion.getPropertyValue("HyperLinkEvents")
                        for event in events.getElementNames():
                            attributes = events.getByName(event)
                            for attribute in attributes:
                                if attribute.Name == "EventType" and attribute.Value == "Script":
                                    return 2

        # 2 = images with script events
        images = _.doc.DrawPage.createEnumeration()
        while images.hasMoreElements():
            image = images.nextElement()
            try:
                events = image.Events
                for event in events.getElementNames():
                    attributes = events.getByName(event)
                    for attribute in attributes:
                        if attribute.Name == "EventType" and attribute.Value == "Script":
                            return 2
            except Exception:
                pass

        _.secure = True
        return 0

    def run(self):
        global __thread__
        try:
            # check document security
            secid = self.secure()
            if secid > 0:
                parent = _.doc.CurrentController.Frame.ContainerWindow
                MessageBox(parent, "Document objects with%s script events" % [" possible"""][secid-1], "LibreLogo program can't start""errorbox")
            else:
                _.fixSVG = False
                _.start_time = __time__.process_time()
                exec(self.code)
                __unlock__(all_levels = True)
            if _.origcursor[0] and _.origcursor[1]:
                __dispatcher__(".uno:Escape")
                try:
                    _.doc.CurrentController.getViewCursor().gotoRange(_.origcursor[0], False)
                except Exception:
                    _.doc.CurrentController.getViewCursor().gotoRange(_.origcursor[0].getStart(), False)
        except Exception:
            try:
              __unlock__(all_levels = True)
              TRACEPATTERN = '"", line '
              message = traceback.format_exc()
              l = re.findall(TRACEPATTERN + '[0-9]+', message)
              if len(l) > 0 and "SystemExit" not in message:
                line = len(re.findall(__LINEBREAK__, ''.join(self.code.split("\n")[:int(l[-1][len(TRACEPATTERN):])]))) + 1
                caption = __l12n__(_.lng)['LIBRELOGO']
                if __prevcode__ and "\n" in __prevcode__:
                    __gotoline__(line)
                    caption = __l12n__(_.lng)['ERROR'] % line
                parent = _.doc.CurrentController.Frame.ContainerWindow
                if "maximum recursion" in message:
                    MessageBox(parent, __l12n__(_.lng)['ERR_STOP'] + " " + __l12n__(_.lng)['ERR_MAXRECURSION'] % sys.getrecursionlimit(), __l12n__(_.lng)['LIBRELOGO'])
                elif "cannot initialize memory" in message or "Couldn't instantiate" in message:
                    MessageBox(parent, __l12n__(_.lng)['ERR_STOP'] + " " + __l12n__(_.lng)['ERR_MEMORY'], __l12n__(_.lng)['LIBRELOGO'])
                elif "ZeroDivisionError" in message:
                    MessageBox(parent, __l12n__(_.lng)['ERR_ZERODIVISION'], caption, "errorbox")
                elif "IndexError" in message:
                    MessageBox(parent, __l12n__(_.lng)['ERR_INDEX'], caption, "errorbox")
                elif "KeyError" in message:
                    MessageBox(parent, __l12n__(_.lng)['ERR_KEY'] % eval(re.search("KeyError: ([^\n]*)", message).group(1)), caption, "errorbox")
                elif "NameError" in message:
                    if "__repeat__" in message:
                        MessageBox(parent, __l12n__(_.lng)['ERR_ARGUMENTS'] % (__locname__('REPEAT'), 1, 0), caption, "errorbox")
                    else:
                        MessageBox(parent, __l12n__(_.lng)['ERR_NAME'] % \
                            to_unicode(re.search(r"(?<=name ')[\w_]*(?=')", message).group(0)), caption, "errorbox")
                elif "TypeError" in message and "argument" in message and "given" in message:
                    r = re.search(r"([\w_]*)[(][)][^\n]* (\w+) arguments? [(](\d+)", message) # XXX later: handle 'no arguments' + plural
                    MessageBox(parent, __l12n__(_.lng)['ERR_ARGUMENTS'] % (__locname__(r.group(1)), r.group(2), r.group(3)), caption, "errorbox")
                else:
                    origline = __compiled__.split("\n")[line-1]
                    if "com.sun.star" not in message and "__repeat__" not in message and "*)" not in message and ("[" in origline or "]" in origline):
                        MessageBox(parent, __l12n__(_.lng)['ERR_BLOCK'], caption, "errorbox")
                    else:
                        MessageBox(parent, __l12n__(_.lng)['ERROR'] %line, __l12n__(_.lng)['LIBRELOGO'], "errorbox")
              __trace__()
            except Exception:
              pass
        with __lock__:
            __thread__ = None

# to check LibreLogo program termination (in that case, return value is False)
def __is_alive__():
    return __thread__ is not None

def __encodestring__(m):
    __strings__.append(re.sub("(\\[^\\]|\\\\(?=[‘’“”»」』]))""", m.group(2)))
    # replace the string with the numbered identifier _s_0___, _s_1___, ...
    return __ENCODED_STRING__ % (len(__strings__) - 1)

def __encodecomment__(m):
    __strings__.append(re.sub("\\[^\\]""", m.group(2)))
    return __ENCODED_COMMENT__ % (len(__strings__) - 1)

def __decodestring__(m):
    return "u'%s'" % __strings__[int(m.group(1))]

def __decodestring2__(m):
    return __l12n__(_.lng)['LEFTSTRING'][0] + __strings__[int(m.group(1))] + __l12n__(_.lng)['RIGHTSTRING'][0]

def __decodecomment__(m):
    return ";" + __strings__[int(m.group(1))]

def __initialize__():
    global __halt__, __thread__
    __getdocument__()
    _.zoomvalue = _.doc.CurrentController.getViewSettings().ZoomValue
    shape = __getshape__(__TURTLE__)
    if not shape:
        shape = _.doc.createInstance( "com.sun.star.drawing.PolyPolygonShape" )
        shape.AnchorType = __AT_PAGE__
        shape.TextWrap = __THROUGH__
        shape.Opaque = True
        _.drawpage.add(shape)
        shape.PolyPolygon = __TURTLESHAPE__[0]
        _.shapecache[__TURTLE__] = shape
        shape.Name = __TURTLE__
        _.initialize()
        turtlehome()
        _.doc.CurrentController.select(shape)
        shape.FillColor, transparence = __splitcolor__(_.areacolor, shape)
        shape.LineColor, shape.LineTransparence = __splitcolor__(_.pencolor)
    elif shape.Visible:
        if shape.FillStyle == __FillStyle_NONE__:
            _.areacolor = 0xffffffff
        else:
            _.areacolor = shape.FillColor + (int(255.0 * shape.FillTransparence/100) << 24)
        if shape.LineWidth != round((1 + _.pen * 2) * __PT_TO_TWIP__ / __MM10_TO_TWIP__) and shape.LineWidth != round(__LINEWIDTH__ / __MM10_TO_TWIP__):
            _.pensize = shape.LineWidth * __MM10_TO_TWIP__
        if shape.LineStyle == __LineStyle_NONE__: # - none -
            __pen__(0)
        else:
            if shape.LineStyle == __LineStyle_SOLID__:
                __pen__(1)
            _.pencolor = shape.LineColor + (int(255.0 * shape.LineTransparence/100) << 24)
    shape.LineJoint = __ROUNDED__
    shape.Shadow = True
    shape.FillColor, transparence = __splitcolor__(_.areacolor, shape)
    shape.FillTransparence = min(95, transparence)
    shape.ShadowColor, shape.ShadowTransparence, shape.ShadowXDistance, shape.ShadowYDistance = (0, 20, 0, 0)
    shape.LineWidth = min(_.pensize, (1 + _.pen * 2) * __PT_TO_TWIP__) / __MM10_TO_TWIP__
    shape.SizeProtect = True

def pagesize(n = -1):
    if n == -1:
        ps = _.doc.CurrentController.getViewCursor().PageStyleName
        page = _.doc.StyleFamilies.getByName("PageStyles").getByName(ps)
        return [page.Width * __MM10_TO_TWIP__ / __PT_TO_TWIP__, page.Height * __MM10_TO_TWIP__ / __PT_TO_TWIP__]
    return None

def turtlehome():
    turtle = __getshape__(__TURTLE__)
    if turtle:
        ps = _.doc.CurrentController.getViewCursor().PageStyleName
        page = _.doc.StyleFamilies.getByName("PageStyles").getByName(ps)
        turtle.setPosition(__Point__((page.Width - turtle.BoundRect.Width)/2, (page.Height - turtle.BoundRect.Height)/2))
        turtle.LineStyle = __LineStyle_SOLID__
        turtle.LineJoint = __MITER__
        turtle.LineWidth = min(_.pensize, (1 + _.pen * 2) * __PT_TO_TWIP__) / __MM10_TO_TWIP__
        turtle.LineColor, none = __splitcolor__(_.pencolor)
        turtle.LineTransparence = 25
        turtle.RotateAngle = 0
        turtle.ZOrder = 1000

def __pen__(n):
    _.pen = n
    turtle = __getshape__(__TURTLE__)
    if turtle:
        if n:
            turtle.LineStyle = __LineStyle_SOLID__
            turtle.LineWidth = min(_.pensize, 3 * __PT_TO_TWIP__) / __MM10_TO_TWIP__
        else:
            turtle.LineStyle = __LineStyle_DASHED__
            turtle.LineDash = __LineDash__(__DashStyle_RECT__, 0, 0, 1, __PT_TO_TWIP__, __PT_TO_TWIP__)
            turtle.LineWidth = min(_.pensize, __PT_TO_TWIP__) / __MM10_TO_TWIP__


def __visible__(shape, visible = -1): # for OOo 3.2 compatibility
    try:
        if visible == -1:
            return shape.Visible
        shape.Visible = visible
    except Exception:
        return True

def hideturtle():
    turtle = __getshape__(__TURTLE__)
    if turtle and turtle.Visible:
        z = turtle.getPosition()
        z = __Point__(z.X + turtle.BoundRect.Width / 2.0, z.Y + turtle.BoundRect.Height / 2.0)
        turtle.PolyPolygon = __TURTLESHAPE__[1]
        __visible__(turtle, False)
        turtle.LineTransparence, turtle.FillTransparence = 100, 100 # for saved files
        turtle.setPosition(z)
    else:
        # HIDETURTLE during locking, no need SHOWTURTLE at the end of locking
        _.lockturtle = False
    __dispatcher__(".uno:Escape")

def showturtle():
    turtle = __getshape__(__TURTLE__)
    if turtle and not turtle.Visible:
        if not turtle.Parent:
            _.drawpage.add(turtle)
        z = turtle.getPosition()
        r, turtle.RotateAngle = turtle.RotateAngle, 0
        turtle.PolyPolygon, turtle.RotateAngle = __TURTLESHAPE__[0], r
        z = __Point__(z.X - turtle.BoundRect.Width / 2.0, z.Y - turtle.BoundRect.Height / 2.0)
        turtle.setPosition(z)
        __visible__(turtle, True)
        pencolor(_.pencolor)
        fillcolor(_.areacolor)
        pensize(_.pensize/__PT_TO_TWIP__)
        _.doc.CurrentController.select(__getshape__(__TURTLE__))
    elif not turtle:
        __initialize__()

def left(arg=None):
    if __thread__:
        return None
    __initialize__()
    turtle = uno.getComponentContext().ServiceManager.createInstance('com.sun.star.drawing.ShapeCollection')
    turtle.add(__getshape__(__TURTLE__))
    _.doc.CurrentController.select(turtle)
    rotate(__TURTLE__, 1500)
    return None

def right(arg=None):
    if __thread__:
        return None
    __initialize__()
    turtle = uno.getComponentContext().ServiceManager.createInstance('com.sun.star.drawing.ShapeCollection')
    turtle.add(__getshape__(__TURTLE__))
    _.doc.CurrentController.select(turtle)
    rotate(__TURTLE__, -1500)
    return None

def goforward(arg=None):
    if __thread__:
        return None
    __initialize__()
    turtle = uno.getComponentContext().ServiceManager.createInstance('com.sun.star.drawing.ShapeCollection')
    turtle.add(__getshape__(__TURTLE__))
    _.doc.CurrentController.select(turtle)
    forward(10)
    return None

def gobackward(arg=None):
    if __thread__:
        return None
    __initialize__()
    turtle = uno.getComponentContext().ServiceManager.createInstance('com.sun.star.drawing.ShapeCollection')
    turtle.add(__getshape__(__TURTLE__))
    _.doc.CurrentController.select(turtle)
    backward(10)
    return None

def commandline(arg=None, arg2=None):
    run(arg, arg2)

def __setlang__():
        global _
        c = _.doc.CurrentController.getViewCursor()
        locs = [i for i in [c.CharLocale, c.CharLocaleAsian, c.CharLocaleComplex] if i.Language != 'zxx'# not None language
  # FIXME-BCP47: this needs adaptation to language tags, a simple split on
  # '-' and assuming second field would be country would already fail if
  # a script tag was present.
        loc = Locale(__uilocale__.split('-')[0], __uilocale__.split('-')[1], '')
        if locs and loc not in locs:
            loc = locs[0]
        _.lng = loc.Language + '_' + loc.Country
        if not __l12n__(_.lng):
            _.lng = loc.Language
            if not __l12n__(_.lng):
                _.lng = "en_US"

def run(arg=None, arg2 = -1):
    global _, __thread__, __halt__, _, __prevcode__, __prevlang__, __prevcompiledcode__
    if __thread__:
        return None
    with __lock__:
        __thread__ = 1
    try:
        __getdocument__()
        _.origcursor = [NoneNone]
        if arg2 == -1:
            _.origcursor, _.cursor = __getcursor__(False), __getcursor__(True)[0]
            __dispatcher__(".uno:Escape")
            c = _.doc.Text.createTextCursor() # go to the first page
            c.gotoStart(False)
            _.doc.CurrentController.getViewCursor().gotoRange(c, False)
            __initialize__()
            __setlang__()
            arg2 = _.cursor.getString()
            if len(arg2) > 20000:
                if MessageBox(_.doc.CurrentController.Frame.ContainerWindow, __l12n__(_.lng)['ERR_NOTAPROGRAM'], __l12n__(_.lng)['LIBRELOGO'], "querybox", __YES_NO_CANCEL__) != 2:
                    with __lock__:
                        __thread__ = None
                    return None
            elif len(arg2) == 0 and _.origcursor[1]:
                _.origcursor[0].setString("fontcolor 'green'\nlabel 'LIBRE'\npu\nback 30\npic [\n\tfc any\n\tcircle 40\n\tfontcolor 'black'\n\tlabel 'LOGO'\n\tleft 180\n\tfd 20\n\tpd\n\tpc any\n\tps 1\n\tfd 40\n\trepeat 20 [\n\t\tfd repcount*2\n\t\trt 90\n\t]\n]\npu pos any pd")
                __translate__()
                _.origcursor, _.cursor = __getcursor__(False), __getcursor__(True)[0]
                arg2 = _.cursor.getString()
        else:
            __initialize__()
            __setlang__()
        if __prevcode__ and __prevcode__ == arg2 and __prevlang__ == _.lng:
            __thread__ = LogoProgram(__prevcompiledcode__)
        else:
            __prevcode__ = arg2
            __prevlang__ = _.lng
            __prevcompiledcode__ = __compil__(arg2)
            __thread__ = LogoProgram(__prevcompiledcode__)
        __halt__ = False
        turtle = uno.getComponentContext().ServiceManager.createInstance('com.sun.star.drawing.ShapeCollection')
        turtle.add(__getshape__(__TURTLE__))
        _.doc.CurrentController.select(turtle)
        # set working directory for file operations
        if _.doc.hasLocation():
          os.chdir(unohelper.fileUrlToSystemPath(re.sub("[^/]*$""", _.doc.getURL())))
        else:
          os.chdir(os.path.expanduser('~'))
        __thread__.start()
    except Exception:
        __thread__ = None
        __trace__()
    return None

def __unlock__(all_levels):
    while _.doc.hasControllersLocked():
        # show turtle which was hidden by locking
        if _.lockturtle:
            showturtle()
        _.doc.unlockControllers()
        if not all_levels:
            break
    if not _.doc.hasControllersLocked() and _.lockturtle:
        _.lockturtle = False
    elif _.doc.hasControllersLocked() and _.lockturtle:
        hideturtle()

def stop(arg=None):
    global __halt__
    with __lock__:
        __halt__ = True
    __unlock__(all_levels = True)
    return None

def home(arg=None):
    if __thread__:
        return None
    __getdocument__()
    turtle = __getshape__(__TURTLE__)
    if turtle:
        __removeshape__(__TURTLE__)
        _.drawpage.remove(turtle)
    __initialize__()
    __dispatcher__(".uno:Escape")
    if not __halt__:
        return None
    _.pencolor = 0
    _.pensize = __LINEWIDTH__
    _.areacolor = __FILLCOLOR__
    __removeshape__(__ACTUAL__)

def clearscreen(arg=None):
    if __thread__:
        return None
    __getdocument__()
    turtle = __getshape__(__TURTLE__)
    if not turtle:
        __initialize__()
        if not __halt__:
            # avoid unintentional image deletion in large documents
            if len(__getcursor__(True)[0].getString()) < 5000:
                __cs__(False)
            return
    __cs__(False)
    __dispatcher__(".uno:Escape")

def __checkhalt__():
    global __thread__, __halt__
    if __halt__:
        with __lock__:
            __thread__ = None
        sys.exit()

def __cs__(select = True):
    turtle = __getshape__(__TURTLE__)
    visible = False
    if turtle and turtle.Visible:
        __visible__(turtle, False)
        visible = True
    if _.doc.CurrentController.select(_.drawpage) and \
        _.doc.CurrentController.getSelection().ImplementationName == "com.sun.star.drawing.SvxShapeCollection":
            __dispatcher__(".uno:Delete")
    if turtle and visible:
        __visible__(turtle, True)
        if select:
            _.doc.CurrentController.select(_.drawpage)

def __dispatcher__(s, properties = (), doc = 0):
    ctx = XSCRIPTCONTEXT.getComponentContext() # noqa: F821
    d = ctx.ServiceManager.createInstanceWithContext("com.sun.star.frame.DispatchHelper", ctx)
    if doc != 0:
      d.executeDispatch(doc.CurrentController.Frame, s, "", 0, properties)
    else:
      d.executeDispatch(_.doc.CurrentController.Frame, s, "", 0, properties)

def __getshape__(shapename):
    try:
        if _.shapecache[shapename].Parent:
            return _.shapecache[shapename]
        _.shapecache.pop(shapename)
    except Exception:
        pass
    return None

def __angle__(deg):
    if deg == u'any':
        return random.random() * 36000
    return deg * 100

def turnleft(deg):
    rotate(__TURTLE__, __angle__(deg))

def turnright(deg):
    rotate(__TURTLE__, -__angle__(deg))

def heading(deg = -1, go = False):
    turtle = __getshape__(__TURTLE__)
    if deg == -1:
        return -turtle.RotateAngle / 100 + 360
    else:
        if deg == u'any':
            turtle.RotateAngle = random.random() * 36000
        elif type(deg) is list:
            pos = turtle.getPosition()
            px, py = pos.X + turtle.BoundRect.Width / 2.0, pos.Y + turtle.BoundRect.Height / 2.0
            dx = px * __MM10_TO_TWIP__ - deg[0] * __PT_TO_TWIP__
            dy = deg[1] * __PT_TO_TWIP__ - py * __MM10_TO_TWIP__
            n = hypot(dx, dy)
            if dy > 0 and n > 0:
                turtle.RotateAngle = a = -(180 + asin(dx / n) / (pi/180)) * 100 + 72000 # +720 for max(angle, preciseAngle) of __go__()
            elif n > 0:
                turtle.RotateAngle = a = asin(dx / n) / (pi/180) * 100 + 72000
            if go and n > 0:
                __go__(__TURTLE__, -n, False, a)
        else:
            turtle.RotateAngle = -deg * 100

def rotate(shapename, deg):
    shape = __getshape__(shapename)
    if shape:
        shape.RotateAngle = shape.RotateAngle + deg

def forward(n):
    if type(n) is list:
        pos = position()
        angle = heading()
        dx = n[1] * sin((pi/180) * angle) + n[0] * sin((pi/180)*(angle + 90))
        dy = n[1] * cos((pi/180) * angle) + n[0] * cos((pi/180)*(angle + 90))
        position([pos[0] + dx, pos[1] - dy])
    elif type(n) is str:
        siz = label([1, 1, n])
        pos = position()
        angle = heading()
        w, _ = siz.Width / (__PT_TO_TWIP__ / __MM10_TO_TWIP__), siz.Height / (__PT_TO_TWIP__ / __MM10_TO_TWIP__)
        dx = 0 * sin((pi/180) * (angle)) + w * sin((pi/180)*(angle + 90))
        dy = 0 * cos((pi/180) * (angle)) + w * cos((pi/180)*(angle + 90))
        position([pos[0] + dx, pos[1] - dy])
        heading(angle)
    else:
        __go__(__TURTLE__, -n * __PT_TO_TWIP__)

def backward(n):
    if type(n) is list:
        forward([-n[0], -n[1]])
        turnright(180)
    else:
        __go__(__TURTLE__, n * __PT_TO_TWIP__)

def __dots__(n, pos, dx, dy, r = -1, q = 0): # dots for dotted polyline or circle
    f = [1, 4, 4, 4, 4][q]
    k = abs(int(1.0 * n / max(20, _.pensize) / 2.0 / f))
    dots = []
    px, py = pos.X, pos.Y
    for i in range(k + 1):
        if k > 0:
            if r != -1:
                px, py = pos.X + sin(((f-1)*(q-1)*30 + 360.0/f/k * i) * pi/180.0) * r[0], pos.Y + cos(((f-1)*(q-1)*30 + 360.0/f/k * i) * pi/180) * r[1]
            else:
                px, py = pos.X + round(i * dx/k), pos.Y + round(i * dy/k)
        dots += [(__Point__(px, py), __Point__(px + 7, py + 7))]
    return dots

def __draw__(d, count = True):
    shape = _.doc.createInstance( "com.sun.star.drawing." + d)
    shape.AnchorType = __AT_PAGE__
    shape.TextWrap = __THROUGH__
    __visible__(shape, False)
    while __zoom__(): # temporary fix program halt with continuous zoom
        while __zoom__():
            __time__.sleep(0.2)
        __time__.sleep(0.2)
    _.drawpage.add(shape)
    if __group__ != 0:
        __group__.add(shape)
        if count:
            _.shapecache[next(_.shapecount)] = str(_.time)
    return shape

def __zoom__():
    z = _.doc.CurrentController.getViewSettings().ZoomValue
    if z != _.zoomvalue:
        _.zoomvalue = z
        return True
    return False

def __lefthang__(shape):
    global __grouplefthang__
    if __group__ != 0:
        p = shape.getPosition()
        if p.X < __grouplefthang__:
            __grouplefthang__ = p.X

def __go__(shapename, n, dot = False, preciseAngle = -1):
    turtle = __getshape__(shapename)
    turtlepos = None
    if shapename == __TURTLE__:
        try:
            turtlepos = turtle.PolyPolygon[-1][-1]
        except Exception:
            pass
    pos = turtle.getPosition()
    dx = n * sin((pi/180)*(max(turtle.RotateAngle, preciseAngle)/100))
    dy = n * cos((pi/180)*(max(turtle.RotateAngle, preciseAngle)/100))
    turtle.setPosition(__Point__(pos.X + dx / __MM10_TO_TWIP__, pos.Y + dy / __MM10_TO_TWIP__))
    if (_.pencolor != _.oldlc or _.pensize != _.oldlw or _.linestyle != _.oldls or _.linejoint != _.oldlj or _.linecap != _.oldlcap):
        __removeshape__(__ACTUAL__)
        shape = None
    else:
        shape = __getshape__(__ACTUAL__)
    _.oldlw = _.pensize
    _.oldlc = _.pencolor
    _.oldls = _.linestyle
    _.oldlj = _.linejoint
    _.oldlcap = _.linecap
    if shape and not _.pen and not dot:
        _.continuous = False
        return
    c, c2 = __Point__(pos.X + turtle.BoundRect.Width / 2.0, pos.Y + turtle.BoundRect.Height / 2.0), __Point__(round(dx / __MM10_TO_TWIP__), round(dy / __MM10_TO_TWIP__))
    if shape and "LineShape" in shape.ShapeType:
            if _.continuous or dot:
                last = shape.PolyPolygon[-1][-1]
                if not (turtlepos and (abs(last.X - turtlepos.X) > 100 or abs(last.Y - turtlepos.Y) > 100) and
                  (__group__ == 0 or (shape.getPosition().X > 0 and turtle.getPosition().X > 0))): # picture [ ] keeps hanging shapes
                    if dot or _.linestyle == __LineStyle_DOTTED__:
                         shape.PolyPolygon = tuple( list(shape.PolyPolygon) + __dots__(n, turtlepos, dx, dy))
                    else:
                        last.X = last.X + c2.X
                        last.Y = last.Y + c2.Y
                        shape.PolyPolygon = tuple( list(shape.PolyPolygon[:-1]) + [tuple( list(shape.PolyPolygon[-1]) + [last])])
                    __lefthang__(shape)
                    return
            elif turtlepos:
                shape.PolyPolygon = tuple( list(shape.PolyPolygon) + [(turtlepos, __Point__(turtlepos.X + c2.X, turtlepos.Y + c2.Y))])
                _.continuous = True
                __lefthang__(shape)
                return
    if not _.pen and not dot:
        return
    if _.pen and not dot:
        _.points = [] # new line drawing: forget the points
    shape = __draw__("PolyLineShape")
    shape.RotateAngle = 0
    shape.PolyPolygon = tuple([tuple([__Point__(0, 0)])])
    shape.setPosition(c)
    last = shape.PolyPolygon[-1][-1]
    last2 = __Point__(last.X + c2.X, last.Y + c2.Y)
    shape.LineStyle, shape.LineDash = __linestyle__(_.linestyle)
    shape.LineJoint = _.linejoint
    shape.LineCap = _.linecap
    if dot or _.linestyle == __LineStyle_DOTTED__:
        shape.PolyPolygon = tuple( list(shape.PolyPolygon) + __dots__(n, last, c2.X, c2.Y))
        shape.LineStart = __bezierdot__
        shape.LineStartCenter = True
        shape.LineStartWidth = max(20, _.pensize) / __MM10_TO_TWIP__
        shape.LineWidth = 0
    else:
        shape.PolyPolygon = tuple([tuple( list(shape.PolyPolygon[-1]) + [last2])])
        shape.LineWidth = _.pensize / __MM10_TO_TWIP__
    shape.LineColor, shape.LineTransparence = __splitcolor__(_.pencolor)
    if shape.LineTransparence == 100:
        shape.LineStyle = 0
    __visible__(shape, True)
    shape.Name = __ACTUAL__
    _.shapecache[__ACTUAL__] = shape
    _.oldlw = _.pensize
    _.oldlc = _.pencolor
    _.oldls = _.linestyle
    _.oldlj = _.linejoint
    _.oldlcap = _.linecap
    _.continuous = True
    __lefthang__(shape)

def __fillit__(filled = True):
    oldshape = __getshape__(__ACTUAL__)
    if (oldshape and oldshape.LineStartCenter) or _.points:
        if oldshape:
            __removeshape__(__ACTUAL__)  # FIXME close dotted polyline
        if _.points:
            p = position()
            h = heading()
            for i in _.points:
                position(i)
                __pen__(1)
                __checkhalt__()
            _.points = []
            __fillit__(filled)
            __pen__(0)
            position(p)
            heading(h)
        return
    if oldshape and "LineShape" in oldshape.ShapeType:
        shape = __draw__("PolyPolygonShape"False)
        shape.PolyPolygon = oldshape.PolyPolygon
        shape.setPosition(oldshape.getPosition())
        shape.LineStyle, shape.LineDash = __linestyle__(_.linestyle)
        shape.LineJoint = _.linejoint
        shape.LineCap = _.linecap
        shape.LineWidth = _.pensize / __MM10_TO_TWIP__
        shape.LineColor, shape.LineTransparence = __splitcolor__(_.pencolor)
        shape.FillColor, shape.FillTransparence = __splitcolor__(_.areacolor, shape)
        if _.hatch:
            shape.FillBackground = True if shape.FillTransparence != 100 else False
            shape.FillHatch = _.hatch
            shape.FillStyle = 3
        elif type(_.areacolor) is not tuple:
            shape.FillStyle = int(filled)
        if shape.LineTransparence == 100:
            shape.LineStyle = 0
        if shape.FillTransparence == 100:
            shape.FillTransparence = 0 # for hatching and better modifications on UI
            if not _.hatch:
                shape.FillStyle = 0
        shape.setString(oldshape.getString())
        oldshape.Name = ""
        shape.Name = __ACTUAL__
        _.shapecache[__ACTUAL__] = shape
        if __group__ != 0:
            __group__.remove(oldshape)
        __visible__(shape, True)
        _.drawpage.remove(oldshape)
    elif oldshape and "PolyPolygon" in oldshape.ShapeType:
        oldshape.LineStyle = int(_.pen)
        oldshape.LineJoint = _.linejoint
        oldshape.LineCap = _.linecap
        if _.hatch:
            oldshape.FillBackground = True
            oldshape.FillHatch = _.hatch
            oldshape.FillStyle = 3
        else:
            oldshape.FillStyle = int(filled)
        oldshape.LineWidth = _.pensize / __MM10_TO_TWIP__
        oldshape.LineColor, oldshape.LineTransparence = __splitcolor__(_.pencolor)
        oldshape.FillColor, oldshape.FillTransparence = __splitcolor__(_.areacolor, oldshape)

def point():
    oldpen, _.pen = _.pen, 1
    oldstyle, _.linestyle = _.linestyle, __LineStyle_DOTTED__
    __go__(__TURTLE__, 0, True)
    _.pen, _.linestyle = oldpen, oldstyle
    _.points.append(position())

def __boxshape__(shapetype, l):
    turtle = __getshape__(__TURTLE__)
    shape = __draw__(shapetype + "Shape")
    pos = turtle.getPosition()
    pos.X = pos.X - (l[0] * __PT_TO_TWIP__ / __MM10_TO_TWIP__ / 2) + turtle.BoundRect.Width / 2.0
    pos.Y = pos.Y - (l[1] * __PT_TO_TWIP__ / __MM10_TO_TWIP__ / 2) + turtle.BoundRect.Height / 2.0
    shape.setPosition(pos)
    shape.setSize(__Size__(l[0] * __PT_TO_TWIP__ / __MM10_TO_TWIP__, l[1] * __PT_TO_TWIP__ / __MM10_TO_TWIP__))
    shape.LineStyle, shape.LineDash = __linestyle__(_.linestyle)
    shape.LineWidth = _.pensize / __MM10_TO_TWIP__
    shape.LineJoint = _.linejoint
    shape.LineCap = _.linecap
    shape.LineColor, shape.LineTransparence = __splitcolor__(_.pencolor)
    shape.FillColor, shape.FillTransparence = __splitcolor__(_.areacolor, shape, turtle.RotateAngle)
    if _.hatch:
        shape.FillBackground = True if shape.FillTransparence != 100 else False
        shape.FillHatch = _.hatch
        shape.FillStyle = 3
    elif type(_.areacolor) is not tuple:
        shape.FillStyle = 1
    if shape.LineTransparence == 100:
        shape.LineStyle = 0
    if shape.FillTransparence == 100:
        shape.FillTransparence = 0 # for hatching and better modifications on UI
        if not _.hatch:
            shape.FillStyle = 0
    shape.RotateAngle = turtle.RotateAngle
    if shapetype == "Rectangle" and len(l) > 2:
        shape.CornerRadius = (l[2] * __PT_TO_TWIP__) / __MM10_TO_TWIP__
    elif shapetype == "Ellipse" and len(l) > 2:
        oldBoundRect = shape.BoundRect
        try:
            shape.CircleKind = __SECTION__
            shape.CircleStartAngle = (-l[3] - 270) * 100
            shape.CircleEndAngle = (-l[2] - 270) * 100
            shape.CircleKind = [__FULL__, __SECTION__, __CUT__, __ARC__][l[4]]
        except Exception:
            pass
        pos.X = pos.X + shape.BoundRect.X - oldBoundRect.X
        pos.Y = pos.Y + shape.BoundRect.Y - oldBoundRect.Y
        shape.setPosition(pos)
    __visible__(shape, True)
    __removeshape__(__ACTUAL__)
    _.shapecache[__ACTUAL__] = shape
    __lefthang__(shape)

def ellipse(l):
    if type(l) is not type([]): # default for circle and square
        l = [l, l]
    if _.linestyle == __LineStyle_DOTTED__:
        __groupstart__()
        _.linestyle = __LineStyle_SOLID__
        pc, _.pencolor = _.pencolor, 0xff000000
        ellipse(l)
        _.pencolor, _.linestyle = pc, __LineStyle_DOTTED__
        point()
        shape = __getshape__(__ACTUAL__)
        shape.PolyPolygon = tuple(__dots__(max(l[0], l[1]) * pi * __PT_TO_TWIP__, shape.PolyPolygon[0][0], 0, 0, [i/2.0 * __PT_TO_TWIP__ for i in l]))
        turtle = __getshape__(__TURTLE__)
        shape.RotateAngle = turtle.RotateAngle
        __groupend__()
    else:
        __boxshape__("Ellipse", l)

def rectangle(l):
    if type(l) is not type([]): # default for circle and square
        l = [l, l]
    if _.linestyle == __LineStyle_DOTTED__:
        __groupstart__()
        _.linestyle = __LineStyle_SOLID__
        pc, _.pencolor = _.pencolor, 0xff000000
        rectangle(l)
        _.pencolor, _.linestyle = pc, __LineStyle_DOTTED__
        point()
        shape = __getshape__(__ACTUAL__)
        if type(l) is not type([]):
            l = [l, l]
        if len(l) == 2:
            l = l + [0]
        l = [i * __PT_TO_TWIP__ for i in l]
        c = shape.PolyPolygon[0][0]
        k = [min(l[0] / 2.0, l[2]), min(l[1] / 2.0, l[2])]
        p = __dots__(l[0] - 2 * k[0], __Point__(c.X - l[0]/2 + k[0], c.Y - l[1]/2), l[0] - 2 * k[0], 0)
        p = p[:-1] + __dots__(l[1] - 2 * k[1], __Point__(c.X + l[0]/2, c.Y - l[1]/2 + k[1]), 0, l[1] - 2 * k[1])
        p = p[:-1] + __dots__(l[0] - 2 * k[0], __Point__(c.X + l[0]/2 - k[0], c.Y + l[1]/2), -l[0] + 2 * k[0], 0)
        p = p[:-1] + __dots__(l[1] - 2 * k[1], __Point__(c.X - l[0]/2, c.Y + l[1]/2 - k[1]), 0, -l[1] + 2 * k[1])
        if l[2] > 0:
               p = p + __dots__(max(k) * 2 * pi, __Point__(c.X - l[0]/2 + k[0], c.Y - l[1]/2 + k[1]), 0, 0, k, 3)[1:]
               p = p + __dots__(max(k) * 2 * pi, __Point__(c.X + l[0]/2 - k[0], c.Y - l[1]/2 + k[1]), 0, 0, k, 2)[1:]
               p = p + __dots__(max(k) * 2 * pi, __Point__(c.X + l[0]/2 - k[0], c.Y + l[1]/2 - k[1]), 0, 0, k, 1)[1:]
               p = p + __dots__(max(k) * 2 * pi, __Point__(c.X - l[0]/2 + k[0], c.Y + l[1]/2 - k[1]), 0, 0, k, 4)[1:]
        shape.PolyPolygon = tuple(p)
        turtle = __getshape__(__TURTLE__)
        shape.RotateAngle = turtle.RotateAngle
        __groupend__()
    else:
        __boxshape__("Rectangle", l)

def label(st):
    if type(st) is not type([]):
        st = [0, 0, st]
    # get text size
    shape = _.doc.createInstance( "com.sun.star.drawing.TextShape")
    shape.TextAutoGrowWidth = True
    shape.Visible = False
    actual = __getshape__(__ACTUAL__)
    _.drawpage.add(shape)
    text(shape, st[2])
    z = shape.getSize()
    # show text using RectangleShape (for correct SVG export)
    ac, pc =  _.areacolor, _.pencolor
    _.areacolor, _.pencolor = 0xff000000, 0xff000000 # invisible
    rectangle([z.Width / (__PT_TO_TWIP__ / __MM10_TO_TWIP__), z.Height / (__PT_TO_TWIP__ / __MM10_TO_TWIP__)])
    _.drawpage.remove(shape)
    _.pencolor, _.areacolor = pc, ac
    lab = __getshape__(__ACTUAL__)
    text(lab, st[2])
    if st[0] != 0 or st[1] != 0:
        pos = position()
        angle = heading()
        n = [st[0] * z.Width/2, st[1] * z.Height/2]
        dx = n[1] * sin((pi/180) * angle) + n[0] * sin((pi/180)*(angle + 90))
        dy = n[1] * cos((pi/180) * angle) + n[0] * cos((pi/180)*(angle + 90))
        lab.setPosition(__Point__(round(pos[0] * __PT_TO_TWIP__ / __MM10_TO_TWIP__ + dx - lab.BoundRect.Width/2), round(pos[1] * __PT_TO_TWIP__ / __MM10_TO_TWIP__ - dy - lab.BoundRect.Height/2)))
    _.shapecache[__ACTUAL__] = actual
    return z

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''<'), NoneNone

  # convert localized bold, and italic values to <B> and <I> tags
  for i in ('BOLD''ITALIC'):
      st = re.sub(r'( + __l12n__(_.lng)[i] + r')>', r'\1%s>' % i[0], st, flags=re.I)

  for i in ('FONTCOLOR''FILLCOLOR''FONTFAMILY''FONTHEIGHT'):
      st = re.sub(r'<(' + __l12n__(_.lng)[i] + r')( *[^<> ][^<>]*)>', r'<%s\2>' % i.lower(), st, flags=re.I)
      st = re.sub(r' + __l12n__(_.lng)[i] + r')>', r'' % i.lower(), st, flags=re.I)

  # expand localized color names
  if _.lng not in __match_localized_colors__:
      __match_localized_colors__[_.lng] = re.compile(r'<(/?)(' + '|'.join(__colors__[_.lng].keys()) + ')>', re.IGNORECASE)
  # replacement lambda function: if it's an opening tag, return with the argument, too
  get_fontcolor_tag = lambda m: "" % m.group(2) if len(m.group(1)) == 0 else ""
  st = re.sub(__match_localized_colors__[_.lng], get_fontcolor_tag, st)

  # expand abbreviated forms of font features
  # <smcp>small caps</smcp> -> <fontfeature smcp>small caps</fontfeature smcp>
  st = re.sub(__match_fontfeatures__, r'\1fontfeature \2\3', st)

  tex = "" # characters without HTML tags
  pat = [] # bit vectors of the previous characters
  extra_pat = [] # extra data of the previous characters
  # 0th bit: bold
  # 1st bit: italic
  # 2nd bit: underline
  # 3rd bit: strikethrough
  # 4th bit: superscript
  # 5th bit: subscript
  # 6th bit: color
  # 7th bit: background color
  # 8th bit: font family
  # 9th bit: font feature (Graphite or OpenType)
  # 10th bit: font size
  f = 0
  # 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, ...,  10: 0}
  bit_level = { i: 0 for i in range(11) }

  extra_data = {}
  i = 0
  while i < len(st):
      is_tag = False

      if st[i] == '<':
        for j in range(len(__match_tags__)):
          m = __match_tags__[j].match(st[i:])
          if m:
              tag = ""
              bit = j // 2
              if bit > 5:
                  tag = m.group(1).lower()
              # opening tag
              if j % 2 == 0:
                  f |= (1 << bit)
                  bit_level[bit] += 1
                  # extra data (color bit and over)
                  if bit > 5:
                      if tag in extra_data:
                          extra_data[tag] = extra_data[tag] + [m.group(2)]
                      else:
                          extra_data[tag] = [m.group(2)]
              else:
                  if bit_level[bit] > 0:
                      bit_level[bit] -= 1
                  if bit_level[bit] == 0:
                      f &= ~(1 << bit)
                  # extra data for font feature
                  # fontfeature has a special closing tag, remove that from the extra_data
                  # (allowing to use overlapping elements)
                  if bit > 5 and (tag in extra_data):
                      if bit == 9 and len(m.group(2)) > 0:
                          # create a new list to keep the extra data of the previous characters,
                          # and remove the last occurance of the feature
                          z = list(extra_data[tag])
                          for j in reversed(range(len(z))):
                              if z[j].startswith(m.group(2)):
                                  z.pop(j)
                                  extra_data[tag] = z
                                  break
                      # extra data
                      else:
                          extra_data[tag] = extra_data[tag][:-1]

              i += len(m.group(0)) - 1
              is_tag = True
              break

      if not is_tag:
          tex = tex + st[i]
          pat.append(f)
          extra_pat.append(dict(extra_data))
      i += 1

  # no tags
  if len(st) == len(tex):
      pat = None
      extra_pat = None

  return tex.replace('\uE000''<'), pat, extra_pat

def text(shape, orig_st):
    if shape:
        _.doc.lockControllers()
        # analyse HTML
        st, formatting, extra_data = __get_HTML_format__(orig_st)
        shape.setString(__string__(st, _.decimal))
        c = shape.createTextCursor()
        c.gotoStart(False)
        c.gotoEnd(True)
        c.CharColor, c.CharTransparence = __splitcolor__(_.textcolor)
        c.CharHeight = _.fontheight
        c.CharWeight = __fontweight__(_.fontweight)
        c.CharPosture = __fontstyle__(_.fontstyle)
        c.CharFontName = _.fontfamily

        # has HTML-like formatting
        if formatting is not None:
            _.fixSVG = True
            prev_format = 0
            prev_extra_data = extra_data[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 or (len(extra_data) > 0 and extra_data[0] != prev_extra_data):
                    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__
                        if prev_format & (1 << 3):
                            c.CharStrikeout = __Strikeout_SINGLE__
                        if prev_format & (1 << 4):
                            c.CharEscapement = 14000 # magic number for default superscript, see DFLT_ESC_AUTO_SUPER
                            c.CharEscapementHeight = 58
                        if prev_format & (1 << 5):
                            c.CharEscapement = -14000 # magic number for default subscript, see DFLT_ESC_AUTO_SUB
                            c.CharEscapementHeight = 58
                        if prev_format & (1 << 6):
                            c.CharColor, c.CharTransparence = __splitcolor__(__color__(prev_extra_data['fontcolor'][-1]))
                        if prev_format & (1 << 7):
                            c.CharBackColor = __color__(prev_extra_data['fillcolor'][-1])
                        if prev_format & (1 << 8):
                            c.CharFontName = prev_extra_data['fontfamily'][-1]
                        if prev_format & (1 << 9):
                            # font features uses the following syntax: font_name:feat1&feat2&feat3=value&etc.
                            if ":" in c.CharFontName:
                                c.CharFontName = c.CharFontName + "&" + "&".join(prev_extra_data['fontfeature'])
                            else:
                                c.CharFontName = c.CharFontName + ":" + "&".join(prev_extra_data['fontfeature'])
                        if prev_format & (1 << 10):
                            c.CharHeight = prev_extra_data['fontheight'][-1]

                    c.collapseToEnd()
                    n = 0
                n += 1
                prev_format = i
                if len(extra_data) > 0:
                    prev_extra_data = extra_data.pop(0)
        _.doc.unlockControllers()

def sleep(t):
    # lock shape repaint, if SLEEP argument is negative
    if t < 0:
        _.doc.lockControllers()
        # hide turtle during locking
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=95 H=93 G=93

¤ Dauer der Verarbeitung: 0.29 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.