# -*- 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 importNONEas __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 importNONEas __FillStyle_NONE__ from com.sun.star.drawing.FillStyle import GRADIENT as __FillStyle_GRADIENT__ from com.sun.star.drawing.LineStyle importNONEas __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 importNONEas __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
# 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__() returnNone
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'(b|strong)>', r'<(i|em)>', r'(i|em)>', '', '', r'<(s|del)>', r'(s|del)>', '', '', '', '', r'<(fontcolor) ([^<>]*)>', r'(fontcolor)>', r'<(fillcolor) ([^<>]*)>', r'(fillcolor)>', r'<(fontfamily) ([^<>]*)>', r'(fontfamily)>', r'<(fontfeature) ([^<>]*)>', r'(fontfeature) ?([^<>]*)>', r'<(fontheight) ([^<>]*)>', r'(fontheight)>']]
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
# 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)
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) ifnot lang:
lang = __l12n__(guess.Language) ifnot lang:
lang = __l12n__(_.lng) ifnot 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")
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
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 __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 notin locs:
loc = locs[0]
_.lng = loc.Language + '_' + loc.Country ifnot __l12n__(_.lng):
_.lng = loc.Language ifnot __l12n__(_.lng):
_.lng = "en_US"
def run(arg=None, arg2 = -1): global _, __thread__, __halt__, _, __prevcode__, __prevlang__, __prevcompiledcode__ if __thread__: returnNone with __lock__:
__thread__ = 1 try:
__getdocument__()
_.origcursor = [None, None] 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 returnNone 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__() returnNone
def __unlock__(all_levels): while _.doc.hasControllersLocked(): # show turtle which was hidden by locking if _.lockturtle:
showturtle()
_.doc.unlockControllers() ifnot all_levels: break ifnot _.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) returnNone
def ellipse(l): if type(l) isnot 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) isnot 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) isnot 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) isnot 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') ifnot ('<'in st and'>'in st): return st.replace('\uE000', '<'), None, None
# 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'%s>' % i.lower(), st, flags=re.I)
# expand localized color names if _.lng notin __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]
# has HTML-like formatting if formatting isnotNone:
_.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
--> --------------------
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.