1 # -*- encoding: UTF-8 -*-
2 # -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
4 # This file is part of the LibreOffice project.
6 # This Source Code Form is subject to the terms of the Mozilla Public
7 # License, v. 2.0. If a copy of the MPL was not distributed with this
8 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 from __future__
import unicode_literals
11 import sys
, os
, uno
, unohelper
12 import re
, random
, traceback
, itertools
13 import threading
, time
as __time__
17 next
= lambda l
: l
.next() # python 2
19 unicode, long = str, int # support python 3
21 urebootstrap
= os
.environ
["URE_BOOTSTRAP"]
22 if "vnd.sun.star.pathname" in urebootstrap
:
23 __lngpath__
= re
.sub(r
"^vnd.sun.star.pathname:(.*)program(/|\\)fundamental([.]ini|rc)$", "\\1", urebootstrap
)
25 __lngpath__
= unohelper
.fileUrlToSystemPath(re
.sub("program/(fundamental.ini|fundamentalrc)$", "", urebootstrap
))
26 __lngpath__
= __lngpath__
+ "share/Scripts/python/LibreLogo/".replace("/", os
.sep
)
27 __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
32 __prevcompiledcode__
= None
34 __lock__
= threading
.Lock()
43 __COLORS__
= ['BLACK', 0x000000], ['SILVER', 0xc0c0c0], ['GRAY', 0x808080], \
44 ['WHITE', 0xffffff], ['MAROON', 0x800000], ['RED', 0xff0000], \
45 ['PURPLE', 0x800080], ['FUCHSIA', 0xff00ff], ['GREEN', 0x008000], \
46 ['LIME', 0x00ff00], ['OLIVE', 0x808000], ['YELLOW', 0xffff00], \
47 ['NAVY', 0x000080], ['BLUE', 0x0000ff], ['TEAL', 0x008080], \
48 ['AQUA', 0x00ffff], ['PINK', 0xffc0cb], ['TOMATO', 0xff6347], \
49 ['ORANGE', 0xffa500], ['GOLD', 0xffd700], ['VIOLET', 0x9400d3], \
50 ['SKYBLUE', 0x87ceeb], ['CHOCOLATE', 0xd2691e], ['BROWN', 0xa52a2a], \
51 ['INVISIBLE', 0xffffffff]
52 __STRCONST__
= [i
[0] for i
in __COLORS__
] + ['NONE', 'BEVEL', 'MITER', 'ROUNDED', 'SOLID', 'DASH', 'DOTTED', 'BOLD', 'ITALIC', 'UPRIGHT', 'NORMAL', "HOUR", "PT", "INCH", "MM", "CM"]
53 __SLEEP_SLICE_IN_MILLISECONDS__
= 500
55 __MM_TO_PT__
= 1/(25.4/72)
56 __MM10_TO_TWIP__
= 1/(2540.0/72/20) # 0.01 mm to twentieth point
57 __FILLCOLOR__
= 0x8000ff00
58 __LINEWIDTH__
= 0.5 * __PT_TO_TWIP__
59 __ENCODED_STRING__
= "_s_%s___"
60 __DECODE_STRING_REGEX__
= "_s_([0-9]+)___"
61 __LINEBREAK__
= "#_@L_i_N_e@_#"
64 __BASEFONTFAMILY__
= "Linux Biolinum G"
65 __LineStyle_DOTTED__
= 2
68 def __init__(self
, doc
):
71 self
.drawpage
= doc
.DrawPage
# Writer
73 self
.drawpage
= doc
.DrawPages
.getByIndex(0) # Draw, Impress
75 self
.shapecount
= itertools
.count()
83 self
.pensize
= __LINEWIDTH__
84 self
.linestyle
= __LineStyle_SOLID__
85 self
.linejoint
= __ROUNDED__
86 self
.linecap
= __Cap_NONE__
89 self
.oldls
= __LineStyle_SOLID__
90 self
.oldlj
= __ROUNDED__
91 self
.continuous
= True
92 self
.areacolor
= __FILLCOLOR__
95 self
.fontfamily
= __BASEFONTFAMILY__
100 from math
import pi
, sin
, cos
, asin
, sqrt
102 from com
.sun
.star
.awt
import Point
as __Point__
103 from com
.sun
.star
.drawing
import LineDash
as __LineDash__
104 from com
.sun
.star
.drawing
import Hatch
as __Hatch__
105 from com
.sun
.star
.drawing
import PolyPolygonBezierCoords
as __Bezier__
106 from com
.sun
.star
.text
.TextContentAnchorType
import AT_PAGE
as __AT_PAGE__
107 from com
.sun
.star
.text
.WrapTextMode
import THROUGHT
as __THROUGHT__
108 from com
.sun
.star
.drawing
.LineCap
import BUTT
as __Cap_NONE__
109 from com
.sun
.star
.drawing
.LineCap
import ROUND
as __Cap_ROUND__
110 from com
.sun
.star
.drawing
.LineCap
import SQUARE
as __Cap_SQUARE__
111 from com
.sun
.star
.drawing
.LineJoint
import NONE
as __Joint_NONE__
112 from com
.sun
.star
.drawing
.LineJoint
import BEVEL
as __BEVEL__
113 from com
.sun
.star
.drawing
.LineJoint
import MITER
as __MITER__
114 from com
.sun
.star
.drawing
.LineJoint
import ROUND
as __ROUNDED__
115 from com
.sun
.star
.drawing
.FillStyle
import NONE
as __FillStyle_NONE__
116 from com
.sun
.star
.drawing
.LineStyle
import NONE
as __LineStyle_NONE__
117 from com
.sun
.star
.drawing
.LineStyle
import SOLID
as __LineStyle_SOLID__
118 from com
.sun
.star
.drawing
.LineStyle
import DASH
as __LineStyle_DASHED__
119 from com
.sun
.star
.drawing
.DashStyle
import RECT
as __DashStyle_RECT__
120 from com
.sun
.star
.drawing
.DashStyle
import ROUND
as __DashStyle_ROUND__
121 from com
.sun
.star
.drawing
.DashStyle
import ROUNDRELATIVE
as __DashStyle_ROUNDRELATIVE__
122 from com
.sun
.star
.drawing
.CircleKind
import FULL
as __FULL__
123 from com
.sun
.star
.drawing
.CircleKind
import SECTION
as __SECTION__
124 from com
.sun
.star
.drawing
.CircleKind
import CUT
as __CUT__
125 from com
.sun
.star
.drawing
.CircleKind
import ARC
as __ARC__
126 from com
.sun
.star
.awt
.FontSlant
import NONE
as __Slant_NONE__
127 from com
.sun
.star
.awt
.FontSlant
import ITALIC
as __Slant_ITALIC__
128 from com
.sun
.star
.awt
import Size
as __Size__
129 from com
.sun
.star
.awt
import WindowDescriptor
as __WinDesc__
130 from com
.sun
.star
.awt
.WindowClass
import MODALTOP
as __MODALTOP__
131 from com
.sun
.star
.awt
.VclWindowPeerAttribute
import OK
as __OK__
132 from com
.sun
.star
.awt
.VclWindowPeerAttribute
import OK_CANCEL
as __OK_CANCEL__
133 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
134 from com
.sun
.star
.awt
.PushButtonType
import OK
as __Button_OK__
135 from com
.sun
.star
.awt
.PushButtonType
import CANCEL
as __Button_CANCEL__
136 from com
.sun
.star
.util
.MeasureUnit
import APPFONT
as __APPFONT__
137 from com
.sun
.star
.beans
import PropertyValue
as __property__
138 from com
.sun
.star
.lang
import Locale
140 def __getprop__(name
, value
):
141 p
, p
.Name
, p
.Value
= __property__(), name
, value
144 __uilocale__
= uno
.getComponentContext().ServiceManager
.createInstance("com.sun.star.configuration.ConfigurationProvider").\
145 createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess",\
146 (__getprop__("nodepath", "/org.openoffice.Setup/L10N"),)).getByName("ooLocale") + '-' # handle missing Country of locale 'eo'
153 __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
])
159 # dot for dotted line (implemented as an array of dot-headed arrows, because PostScript dot isn't supported by Writer)
161 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
)]
162 __bezierdot__
= __Bezier__()
163 __bezierdot__
.Coordinates
= (tuple(__gendots__(32)),)
164 __bezierdot__
.Flags
= ((0,) * 32,)
167 __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), )] +
168 [(i
,) for i
in __gendots__(32)] + # single points for wider selection
169 [(__Point__(0, 0),)]), # last point for position handling
170 ((__Point__(0, 0),),)] # hidden turtle (single point to draw at the left border of the page area)
172 def __getdocument__():
174 doc
= XSCRIPTCONTEXT
.getDocument()
176 _
= __docs__
[doc
.Title
]
177 _
.doc
.Title
# Is existing instance (not the garbage of the previous instance of a reopened document or a new "Untitled 1")?
180 __docs__
[doc
.Title
] = _
182 # input function, result: input string or 0
186 ctx
= uno
.getComponentContext()
187 smgr
= ctx
.ServiceManager
191 d
= smgr
.createInstanceWithContext("com.sun.star.awt.UnoControlDialogModel", ctx
)
192 ps
= _
.doc
.CurrentController
.Frame
.ContainerWindow
.getPosSize()
193 lo
= _
.doc
.CurrentController
.Frame
.ContainerWindow
.convertSizeToLogic(__Size__(ps
.Width
, ps
.Height
), __APPFONT__
)
194 d
.PositionX
, d
.PositionY
, d
.Width
, d
.Height
= lo
.Width
/2 - 75, lo
.Height
/2 - 25, 150, 50
197 l
= d
.createInstance("com.sun.star.awt.UnoControlFixedTextModel" )
202 l
.PositionX
, l
.PositionY
, l
.Width
, l
.Height
, l
.Name
, l
.TabIndex
, l
.Label
= 5, 4, 140, 14, "l1", 2, s
204 # textbox or combobox
205 e
= d
.createInstance("com.sun.star.awt.UnoControlEditModel")
206 e
.PositionX
, e
.PositionY
, e
.Width
, e
.Height
, e
.Name
, e
.TabIndex
= 5, 14, 140, 12, "e1", 0
209 b
= d
.createInstance( "com.sun.star.awt.UnoControlButtonModel" )
210 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
211 b2
= d
.createInstance( "com.sun.star.awt.UnoControlButtonModel" )
212 b2
.PositionX
, b2
.PositionY
, b2
.Width
, b2
.Height
, b2
.Name
, b2
.TabIndex
, b2
.PushButtonType
= 100, 32, 45, 14, "b2", 1, __Button_CANCEL__
214 # insert the control models into the dialog model
215 d
.insertByName( "l1", l
)
216 d
.insertByName( "b1", b
)
217 d
.insertByName( "b2", b2
)
218 d
.insertByName( "e1", e
)
220 # create the dialog control and set the model
221 controlContainer
= smgr
.createInstanceWithContext("com.sun.star.awt.UnoControlDialog", ctx
)
222 controlContainer
.setModel(d
)
225 toolkit
= smgr
.createInstanceWithContext("com.sun.star.awt.ExtToolkit", ctx
)
226 controlContainer
.setVisible(False)
227 controlContainer
.createPeer(toolkit
, None)
230 inputtext
= controlContainer
.execute()
237 controlContainer
.dispose()
242 def __string__(s
, decimal
= None): # convert decimal sign, localized BOOL and SET
245 if decimal
== ',' and type(s
) == float:
246 return str(s
).replace(".", ",")
247 if type(s
) in [list, tuple, dict, set]:
249 s
= re
.sub("(?u)(['\"])(([^'\"]|\\['\"])*)(?<!\\\\)\\1", __encodestring__
, str(s
)) # XXX fix double '\'\"'
251 s
= s
.replace(".", ",")
252 return re
.sub(__DECODE_STRING_REGEX__
, __decodestring__
, \
253 s
.replace('set', __locname__('SET')).replace('True', __locname__('TRUE')).replace('False', __locname__('FALSE')))
254 if type(s
) in [str, unicode]:
256 elif type(s
) == bool:
257 return __locname__(str(s
).upper())
262 s
= __string__(s
, _
.decimal
)
263 if not MessageBox(_
.doc
.CurrentController
.Frame
.ContainerWindow
, s
[:500] + s
[500:5000].replace('\n', ' '), "", "messbox", __OK_CANCEL__
):
266 def MessageBox(parent
, message
, title
, msgtype
= "messbox", buttons
= __OK__
):
267 msgtypes
= ("messbox", "infobox", "errorbox", "warningbox", "querybox")
268 if not (msgtype
in msgtypes
):
271 d
.Type
= __MODALTOP__
272 d
.WindowServiceName
= msgtype
275 d
.WindowAttributes
= buttons
276 tk
= parent
.getToolkit()
277 msgbox
= tk
.createWindow(d
)
278 msgbox
.setMessageText(message
)
280 msgbox
.setCaptionText(title
)
281 return msgbox
.execute()
285 return r
* random
.random()
287 return list(r
)[int(random
.random() * len(r
))]
290 return s
.encode("unicode-escape").decode("utf-8").replace("\\u", "__u__").replace(r
"\x", "__x__")
293 return bytes(s
.replace("__x__", r
"\x").replace("__u__", "\\u"), "ascii").decode("unicode-escape")
296 if 'PYUNO_LOGLEVEL' in os
.environ
:
297 print(traceback
.format_exc())
299 def __locname__(name
, l
= -1):
302 for i
in __l12n__(l
):
303 if i
== name
.upper():
304 return __l12n__(l
)[i
].split("|")[0] # return with the first localized name
305 return to_unicode(name
)
307 def __getcursor__(fulltext
):
309 text
= _
.doc
.getCurrentController().getViewCursor().getText().createTextCursor() # copy selection (also in frames)
310 text
.gotoRange(_
.doc
.getCurrentController().getViewCursor(), False)
312 1/len(text
.getString()) # exception, if zero length
314 text
= _
.doc
.getText().createTextCursorByRange(_
.doc
.getText().getStart())
318 def __translate__(arg
= None):
321 selection
= __getcursor__(True)
325 text
= selection
.getString()
326 # remove comments and strings
327 text
= re
.sub(r
"[ ]*;[^\n]*", "", re
.sub(r
"['„“‘«»「][^\n'”“‘’«»」]*['”“‘’«»」]", "", re
.sub(r
"^[ \t]*[;#][^\n]*", "", text
)))
328 text
= " ".join(set(re
.findall("(?u)\w+", text
)) - set(re
.findall("(?u)\w*\d+\w*", text
))).lower() # only words
329 ctx
= uno
.getComponentContext()
330 guess
= ctx
.ServiceManager
.createInstanceWithContext("com.sun.star.linguistic2.LanguageGuessing", ctx
)
331 guess
.disableLanguages(guess
.getEnabledLanguages())
332 guess
.enableLanguages(tuple([Locale(i
, "", "") for i
in __translang__
.split("|")]))
333 guess
= guess
.guessPrimaryLanguage(text
, 0, len(text
))
335 l
= {'cs': 'cs_CZ', 'el': 'el_GR', 'en': 'en_US', 'pt': 'pt_BR'}[guess
.Language
]
337 l
= guess
.Language
+ '_' + guess
.Language
.upper()
340 lang
= __l12n__(guess
.Language
)
342 lang
= __l12n__(_
.lng
)
344 lang
= __l12n__("en_US")
345 lq
= '\'' + lang
['LEFTSTRING'].replace("|", "")
346 rq
= '\'' + lang
['RIGHTSTRING'].replace("|", "")
349 text
= re
.sub("(?u)([%s])([^\n%s]*)(?<!\\\\)[%s]" % (lq
, rq
, rq
), __encodestring__
, selection
.getString())
350 text
= re
.sub('(?u)(?<![0-9])(")(~?\w*)', __encodestring__
, text
)
352 # translate the program to the language of the document FIXME space/tab
353 exception
= ['DECIMAL']
354 in1
= lang
['IN'].upper()
355 in2
= __l12n__(_
.lng
)['IN'].split("|")[0].upper()
356 if in1
[0] == '-' and in2
[0] != '-': # "for x y-in" -> "for x in y"
358 text
= re
.sub(r
"(?ui)\b((?:%s) +:?\w+) +([^\n]+)(?:%s) +(?=[[] |[[]\n)" % (lang
['FOR'], in1
), "\\1 %s \\2 " % in2
, text
)
359 text
= re
.sub(r
"(?ui)(:?\b\w+|[[][^[\n]*])\b(?:%s)\b" % in1
, "%s \\1" % in2
, text
)
360 elif in1
[0] != '-' and in2
[0] == '-': # "for x in y" -> "for x y-in"
362 text
= re
.sub(r
"(?ui)(?<=\n)((?:%s)\b +:?\w+) +(?:%s) +([^\n]+?) +(?=[[] |[[]\n)" % (lang
['FOR'], in1
), "\\1 \\2%s " % in2
, text
)
363 text
= re
.sub(r
"(?ui)(?<!:)\b(?:%s) +(:?\b\w+|[[][^[\n]*])\b" % in1
, "\\1%s" % in2
, text
)
364 for i
in set(lang
) - set(exception
):
365 text
= re
.sub(r
'(?ui)(?<!:)\b(%s)\b' % lang
[i
], __l12n__(_
.lng
)[i
].split("|")[0].upper(), text
)
366 text
= re
.sub(r
"(?<=\d)[%s](?=\d)" % lang
['DECIMAL'], __l12n__(_
.lng
)['DECIMAL'], text
)
369 quoted
= u
"(?ui)(?<=%s)(%%s)(?=%s)" % (__l12n__(_
.lng
)['LEFTSTRING'][0], __l12n__(_
.lng
)['RIGHTSTRING'][0])
370 text
= re
.sub(__DECODE_STRING_REGEX__
, __decodestring2__
, text
)
371 for i
in __STRCONST__
:
372 text
= re
.sub(quoted
% lang
[i
], __l12n__(_
.lng
)[i
].split("|")[0].upper(), text
)
373 selection
.setString(text
)
374 # convert to paragraphs
375 __dispatcher__(".uno:ExecuteSearch", (__getprop__("SearchItem.SearchString", r
"\n"), __getprop__("SearchItem.ReplaceString", r
"\n"), \
376 __getprop__("Quiet", True), __getprop__("SearchItem.Command", 3), __getprop__("SearchItem.StyleFamily", 2), \
377 __getprop__("SearchItem.AlgorithmType", 1), __getprop__("SearchItem.RowDirection", 1), __getprop__("SearchItem.SearchFlags", 65536)))
379 class LogoProgram(threading
.Thread
):
380 def __init__(self
, code
):
382 threading
.Thread
.__init
__(self
)
389 __dispatcher__(".uno:Escape")
391 _
.doc
.CurrentController
.getViewCursor().gotoRange(_
.origcursor
, False)
393 _
.doc
.CurrentController
.getViewCursor().gotoRange(_
.origcursor
.getStart(), False)
394 except Exception as e
:
396 TRACEPATTERN
= '"<string>", line '
397 message
= traceback
.format_exc()
398 l
= re
.findall(TRACEPATTERN
+ '[0-9]+', message
)
399 if len(l
) > 0 and not "SystemExit" in message
:
400 line
= len(re
.findall(__LINEBREAK__
, ''.join(self
.code
.split("\n")[:int(l
[-1][len(TRACEPATTERN
):])]))) + 1
401 caption
= __l12n__(_
.lng
)['LIBRELOGO']
402 if __prevcode__
and "\n" in __prevcode__
:
404 caption
= __l12n__(_
.lng
)['ERROR'] % line
405 parent
= _
.doc
.CurrentController
.Frame
.ContainerWindow
406 if "maximum recursion" in message
:
407 MessageBox(parent
, __l12n__(_
.lng
)['ERR_STOP'] + " " + __l12n__(_
.lng
)['ERR_MAXRECURSION'] % sys
.getrecursionlimit(), __l12n__(_
.lng
)['LIBRELOGO'])
408 elif "cannot initialize memory" in message
or "Couldn't instantiate" in message
:
409 MessageBox(parent
, __l12n__(_
.lng
)['ERR_STOP'] + " " + __l12n__(_
.lng
)['ERR_MEMORY'], __l12n__(_
.lng
)['LIBRELOGO'])
410 elif "ZeroDivisionError" in message
:
411 MessageBox(parent
, __l12n__(_
.lng
)['ERR_ZERODIVISION'], caption
, "errorbox")
412 elif "IndexError" in message
:
413 MessageBox(parent
, __l12n__(_
.lng
)['ERR_INDEX'], caption
, "errorbox")
414 elif "KeyError" in message
:
415 MessageBox(parent
, __l12n__(_
.lng
)['ERR_KEY'] % eval(re
.search("KeyError: ([^\n]*)", message
).group(1)), caption
, "errorbox")
416 elif "NameError" in message
:
417 if "__repeat__" in message
:
418 MessageBox(parent
, __l12n__(_
.lng
)['ERR_ARGUMENTS'] % (__locname__('REPEAT'), 1, 0), caption
, "errorbox")
420 MessageBox(parent
, __l12n__(_
.lng
)['ERR_NAME'] % \
421 to_unicode(re
.search("(?<=name ')[\w_]*(?=')", message
).group(0)), caption
, "errorbox")
422 elif "TypeError" in message
and "argument" in message
and "given" in message
:
423 r
= re
.search("([\w_]*)[(][)][^\n]* (\w+) arguments? [(](\d+)", message
) # XXX later: handle 'no arguments' + plural
424 MessageBox(parent
, __l12n__(_
.lng
)['ERR_ARGUMENTS'] % (__locname__(r
.group(1)), r
.group(2), r
.group(3)), caption
, "errorbox")
426 origline
= __compiled__
.split("\n")[line
-1]
427 if not "com.sun.star" in message
and not "__repeat__" in message
and not "*)" in message
and ("[" in origline
or "]" in origline
):
428 MessageBox(parent
, __l12n__(_
.lng
)['ERR_BLOCK'], caption
, "errorbox")
430 MessageBox(parent
, __l12n__(_
.lng
)['ERROR'] %line
, __l12n__(_
.lng
)['LIBRELOGO'], "errorbox")
438 def __encodestring__(m
):
439 __strings__
.append(re
.sub("\\[^\\]", "", m
.group(2)))
440 return __ENCODED_STRING__
% (len(__strings__
) - 1)
442 def __decodestring__(m
):
443 return "u'%s'" % __strings__
[int(m
.group(1))]
445 def __decodestring2__(m
):
446 return __l12n__(_
.lng
)['LEFTSTRING'][0] + __strings__
[int(m
.group(1))] + __l12n__(_
.lng
)['RIGHTSTRING'][0]
448 def __initialize__():
449 global __halt__
, __thread__
451 _
.zoomvalue
= _
.doc
.CurrentController
.getViewSettings().ZoomValue
452 shape
= __getshape__(__TURTLE__
)
454 shape
= _
.doc
.createInstance( "com.sun.star.drawing.PolyPolygonShape" )
455 shape
.AnchorType
= __AT_PAGE__
456 shape
.TextWrap
= __THROUGHT__
458 _
.drawpage
.add(shape
)
459 shape
.PolyPolygon
= __TURTLESHAPE__
[0]
460 _
.shapecache
[__TURTLE__
] = shape
461 shape
.Name
= __TURTLE__
464 _
.doc
.CurrentController
.select(shape
)
465 shape
.FillColor
, transparence
= __splitcolor__(_
.areacolor
)
466 shape
.LineColor
, shape
.LineTransparence
= __splitcolor__(_
.pencolor
)
468 if shape
.FillStyle
== __FillStyle_NONE__
:
469 _
.areacolor
= 0xffffffff
471 _
.areacolor
= shape
.FillColor
+ (int(255.0 * shape
.FillTransparence
/100) << 24)
472 if shape
.LineWidth
!= round((1 + _
.pen
* 2) * __PT_TO_TWIP__
/ __MM10_TO_TWIP__
) and shape
.LineWidth
!= round(__LINEWIDTH__
/ __MM10_TO_TWIP__
):
473 _
.pensize
= shape
.LineWidth
* __MM10_TO_TWIP__
474 if shape
.LineStyle
== __LineStyle_NONE__
: # - none -
477 if shape
.LineStyle
== __LineStyle_SOLID__
:
479 _
.pencolor
= shape
.LineColor
+ (int(255.0 * shape
.LineTransparence
/100) << 24)
480 shape
.LineJoint
= __ROUNDED__
482 shape
.FillColor
, transparence
= __splitcolor__(_
.areacolor
)
483 shape
.FillTransparence
= min(95, transparence
)
484 shape
.ShadowColor
, shape
.ShadowTransparence
, shape
.ShadowXDistance
, shape
.ShadowYDistance
= (0, 20, 0, 0)
485 shape
.LineWidth
= min(_
.pensize
, (1 + _
.pen
* 2) * __PT_TO_TWIP__
) / __MM10_TO_TWIP__
486 shape
.SizeProtect
= True
488 def pagesize(n
= -1):
490 ps
= _
.doc
.CurrentController
.getViewCursor().PageStyleName
491 page
= _
.doc
.StyleFamilies
.getByName("PageStyles").getByName(ps
)
492 return [page
.Width
* __MM10_TO_TWIP__
/ __PT_TO_TWIP__
, page
.Height
* __MM10_TO_TWIP__
/ __PT_TO_TWIP__
]
496 turtle
= __getshape__(__TURTLE__
)
498 ps
= _
.doc
.CurrentController
.getViewCursor().PageStyleName
499 page
= _
.doc
.StyleFamilies
.getByName("PageStyles").getByName(ps
)
500 turtle
.setPosition(__Point__((page
.Width
- turtle
.BoundRect
.Width
)/2, (page
.Height
- turtle
.BoundRect
.Height
)/2))
501 turtle
.LineStyle
= __LineStyle_SOLID__
502 turtle
.LineJoint
= __MITER__
503 turtle
.LineWidth
= min(_
.pensize
, (1 + _
.pen
* 2) * __PT_TO_TWIP__
) / __MM10_TO_TWIP__
504 turtle
.LineColor
, none
= __splitcolor__(_
.pencolor
)
505 turtle
.LineTransparence
= 25
506 turtle
.RotateAngle
= 0
511 turtle
= __getshape__(__TURTLE__
)
514 turtle
.LineStyle
= __LineStyle_SOLID__
515 turtle
.LineWidth
= min(_
.pensize
, 3 * __PT_TO_TWIP__
) / __MM10_TO_TWIP__
517 turtle
.LineStyle
= __LineStyle_DASHED__
518 turtle
.LineDash
= __LineDash__(__DashStyle_RECT__
, 0, 0, 1, __PT_TO_TWIP__
, __PT_TO_TWIP__
)
519 turtle
.LineWidth
= min(_
.pensize
, __PT_TO_TWIP__
) / __MM10_TO_TWIP__
522 def __visible__(shape
, visible
= -1): # for OOo 3.2 compatibility
526 shape
.Visible
= visible
531 turtle
= __getshape__(__TURTLE__
)
532 if turtle
and turtle
.Visible
:
533 z
= turtle
.getPosition()
534 z
= __Point__(z
.X
+ turtle
.BoundRect
.Width
/ 2.0, z
.Y
+ turtle
.BoundRect
.Height
/ 2.0)
535 turtle
.PolyPolygon
= __TURTLESHAPE__
[1]
536 __visible__(turtle
, False)
537 turtle
.LineTransparence
, turtle
.FillTransparence
= 100, 100 # for saved files
538 turtle
.setPosition(z
)
539 __dispatcher__(".uno:Escape")
542 turtle
= __getshape__(__TURTLE__
)
543 if turtle
and not turtle
.Visible
:
544 if not turtle
.Parent
:
545 _
.drawpage
.add(turtle
)
546 z
= turtle
.getPosition()
547 r
, turtle
.RotateAngle
= turtle
.RotateAngle
, 0
548 turtle
.PolyPolygon
, turtle
.RotateAngle
= __TURTLESHAPE__
[0], r
549 z
= __Point__(z
.X
- turtle
.BoundRect
.Width
/ 2.0, z
.Y
- turtle
.BoundRect
.Height
/ 2.0)
550 turtle
.setPosition(z
)
551 __visible__(turtle
, True)
553 fillcolor(_
.areacolor
)
554 pensize(_
.pensize
/__PT_TO_TWIP__
)
555 _
.doc
.CurrentController
.select(__getshape__(__TURTLE__
))
563 turtle
= uno
.getComponentContext().ServiceManager
.createInstance('com.sun.star.drawing.ShapeCollection')
564 turtle
.add(__getshape__(__TURTLE__
))
565 _
.doc
.CurrentController
.select(turtle
)
566 rotate(__TURTLE__
, 1500)
573 turtle
= uno
.getComponentContext().ServiceManager
.createInstance('com.sun.star.drawing.ShapeCollection')
574 turtle
.add(__getshape__(__TURTLE__
))
575 _
.doc
.CurrentController
.select(turtle
)
576 rotate(__TURTLE__
, -1500)
579 def goforward(arg
=None):
583 turtle
= uno
.getComponentContext().ServiceManager
.createInstance('com.sun.star.drawing.ShapeCollection')
584 turtle
.add(__getshape__(__TURTLE__
))
585 _
.doc
.CurrentController
.select(turtle
)
589 def gobackward(arg
=None):
593 turtle
= uno
.getComponentContext().ServiceManager
.createInstance('com.sun.star.drawing.ShapeCollection')
594 turtle
.add(__getshape__(__TURTLE__
))
595 _
.doc
.CurrentController
.select(turtle
)
599 def commandline(arg
=None, arg2
=None):
604 c
= _
.doc
.CurrentController
.getViewCursor()
605 locs
= [i
for i
in [c
.CharLocale
, c
.CharLocaleAsian
, c
.CharLocaleComplex
] if i
.Language
!= 'zxx'] # not None language
606 # FIXME-BCP47: this needs adaption to language tags, a simple split on
607 # '-' and assuming second field would be country would already fail if
608 # a script tag was present.
609 loc
= Locale(__uilocale__
.split('-')[0], __uilocale__
.split('-')[1], '')
610 if locs
and loc
not in locs
:
612 _
.lng
= loc
.Language
+ '_' + loc
.Country
613 if not __l12n__(_
.lng
):
615 if not __l12n__(_
.lng
):
618 def run(arg
=None, arg2
= -1):
619 global _
, __thread__
, __halt__
, _
, __prevcode__
, __prevlang__
, __prevcompiledcode__
628 _
.origcursor
, _
.cursor
= __getcursor__(False), __getcursor__(True)
629 __dispatcher__(".uno:Escape")
630 c
= _
.doc
.Text
.createTextCursor() # go to the first page
632 _
.doc
.CurrentController
.getViewCursor().gotoRange(c
, False)
635 arg2
= _
.cursor
.getString()
636 if len(arg2
) > 20000:
637 if MessageBox(_
.doc
.CurrentController
.Frame
.ContainerWindow
, __l12n__(_
.lng
)['ERR_NOTAPROGRAM'], __l12n__(_
.lng
)['LIBRELOGO'], "querybox", __YES_NO_CANCEL__
) != 2:
644 if __prevcode__
and __prevcode__
== arg2
and __prevlang__
== _
.lng
:
645 __thread__
= LogoProgram(__prevcompiledcode__
)
649 __prevcompiledcode__
= __compil__(arg2
)
650 __thread__
= LogoProgram(__prevcompiledcode__
)
652 turtle
= uno
.getComponentContext().ServiceManager
.createInstance('com.sun.star.drawing.ShapeCollection')
653 turtle
.add(__getshape__(__TURTLE__
))
654 _
.doc
.CurrentController
.select(turtle
)
656 except Exception as e
:
671 turtle
= __getshape__(__TURTLE__
)
673 __removeshape__(__TURTLE__
)
674 _
.drawpage
.remove(turtle
)
676 __dispatcher__(".uno:Escape")
680 _
.pensize
= __LINEWIDTH__
681 _
.areacolor
= __FILLCOLOR__
683 __removeshape__(__ACTUAL__
)
685 def clearscreen(arg
=None):
689 turtle
= __getshape__(__TURTLE__
)
695 __dispatcher__(".uno:Escape")
698 global __thread__
, __halt__
704 def __cs__(select
= True):
705 turtle
= __getshape__(__TURTLE__
)
707 if turtle
and turtle
.Visible
:
708 __visible__(turtle
, False)
710 if _
.doc
.CurrentController
.select(_
.drawpage
) and \
711 _
.doc
.CurrentController
.getSelection().ImplementationName
== "com.sun.star.drawing.SvxShapeCollection":
712 __dispatcher__(".uno:Delete")
713 if turtle
and visible
:
714 __visible__(turtle
, True)
716 _
.doc
.CurrentController
.select(_
.drawpage
)
718 def __dispatcher__(s
, properties
= (), doc
= 0):
719 ctx
= XSCRIPTCONTEXT
.getComponentContext()
720 d
= ctx
.ServiceManager
.createInstanceWithContext("com.sun.star.frame.DispatchHelper", ctx
)
722 d
.executeDispatch(doc
.CurrentController
.Frame
, s
, "", 0, properties
)
724 d
.executeDispatch(_
.doc
.CurrentController
.Frame
, s
, "", 0, properties
)
726 def __getshape__(shapename
):
728 if _
.shapecache
[shapename
].Parent
:
729 return _
.shapecache
[shapename
]
730 _
.shapecache
.pop(shapename
)
737 return random
.random() * 36000
741 rotate(__TURTLE__
, __angle__(deg
))
744 rotate(__TURTLE__
, -__angle__(deg
))
746 def heading(deg
= -1, go
= False):
747 turtle
= __getshape__(__TURTLE__
)
749 return -turtle
.RotateAngle
/ 100 + 360
752 turtle
.RotateAngle
= random
.random() * 36000
753 elif type(deg
) == list:
754 pos
= turtle
.getPosition()
755 px
, py
= pos
.X
+ turtle
.BoundRect
.Width
/ 2.0, pos
.Y
+ turtle
.BoundRect
.Height
/ 2.0
756 dx
= px
* __MM10_TO_TWIP__
- deg
[0] * __PT_TO_TWIP__
757 dy
= deg
[1] * __PT_TO_TWIP__
- py
* __MM10_TO_TWIP__
758 n
= sqrt(dx
**2 + dy
**2)
760 turtle
.RotateAngle
= a
= -(180 + asin(dx
/ n
) / (pi
/180)) * 100 + 72000 # +720 for max(angle, preciseAngle) of __go__()
762 turtle
.RotateAngle
= a
= asin(dx
/ n
) / (pi
/180) * 100 + 72000
764 __go__(__TURTLE__
, -n
, False, a
)
766 turtle
.RotateAngle
= -deg
* 100
768 def rotate(shapename
, deg
):
769 shape
= __getshape__(shapename
)
771 shape
.RotateAngle
= shape
.RotateAngle
+ deg
777 dx
= n
[1] * sin((pi
/180) * angle
) + n
[0] * sin((pi
/180)*(angle
+ 90))
778 dy
= n
[1] * cos((pi
/180) * angle
) + n
[0] * cos((pi
/180)*(angle
+ 90))
779 position([pos
[0] + dx
, pos
[1] - dy
])
781 __go__(__TURTLE__
, -n
* __PT_TO_TWIP__
)
785 forward([-n
[0], -n
[1]])
788 __go__(__TURTLE__
, n
* __PT_TO_TWIP__
)
790 def __dots__(n
, pos
, dx
, dy
, r
= -1, q
= 0): # dots for dotted polyline or circle
791 f
= [1, 4, 4, 4, 4][q
]
792 k
= abs(int(1.0 * n
/ max(20, _
.pensize
) / 2.0 / f
))
794 px
, py
= pos
.X
, pos
.Y
795 for i
in range(k
+ 1):
798 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]
800 px
, py
= pos
.X
+ round(i
* dx
/k
), pos
.Y
+ round(i
* dy
/k
)
801 dots
+= [(__Point__(px
, py
), __Point__(px
+ 7, py
+ 7))]
804 def __draw__(d
, count
= True):
805 shape
= _
.doc
.createInstance( "com.sun.star.drawing." + d
)
806 shape
.AnchorType
= __AT_PAGE__
807 shape
.TextWrap
= __THROUGHT__
808 __visible__(shape
, False)
809 while __zoom__(): # temporary fix program halt with continuous zoom
813 _
.drawpage
.add(shape
)
817 _
.shapecache
[next(_
.shapecount
)] = str(_
.time
)
821 z
= _
.doc
.CurrentController
.getViewSettings().ZoomValue
827 def __lefthang__(shape
):
828 global __grouplefthang__
830 p
= shape
.getPosition()
831 if p
.X
< __grouplefthang__
:
832 __grouplefthang__
= p
.X
834 def __go__(shapename
, n
, dot
= False, preciseAngle
= -1):
835 turtle
= __getshape__(shapename
)
837 if shapename
== __TURTLE__
:
839 turtlepos
= turtle
.PolyPolygon
[-1][-1]
842 pos
= turtle
.getPosition()
843 dx
= n
* sin((pi
/180)*(max(turtle
.RotateAngle
, preciseAngle
)/100))
844 dy
= n
* cos((pi
/180)*(max(turtle
.RotateAngle
, preciseAngle
)/100))
845 turtle
.setPosition(__Point__(pos
.X
+ dx
/ __MM10_TO_TWIP__
, pos
.Y
+ dy
/ __MM10_TO_TWIP__
))
846 if (_
.pencolor
!= _
.oldlc
or _
.pensize
!= _
.oldlw
or _
.linestyle
!= _
.oldls
or _
.linejoint
!= _
.oldlj
or _
.linecap
!= _
.oldlcap
):
847 __removeshape__(__ACTUAL__
)
850 shape
= __getshape__(__ACTUAL__
)
853 _
.oldls
= _
.linestyle
854 _
.oldlj
= _
.linejoint
855 _
.oldlcap
= _
.linecap
856 if shape
and not _
.pen
and not dot
:
859 c
, c2
= __Point__(pos
.X
+ turtle
.BoundRect
.Width
/ 2.0, pos
.Y
+ turtle
.BoundRect
.Height
/ 2.0), __Point__(round(dx
), round(dy
))
860 if shape
and "LineShape" in shape
.ShapeType
:
861 if _
.continuous
or dot
:
862 last
= shape
.PolyPolygon
[-1][-1]
863 if not (turtlepos
and (abs(last
.X
- turtlepos
.X
) > 100 or abs(last
.Y
- turtlepos
.Y
) > 100) and
864 (not __group__
or (shape
.getPosition().X
> 0 and turtle
.getPosition().X
> 0))): # picture [ ] keeps hanging shapes
865 if dot
or _
.linestyle
== __LineStyle_DOTTED__
:
866 shape
.PolyPolygon
= tuple( list(shape
.PolyPolygon
) + __dots__(n
, turtlepos
, dx
, dy
))
868 last
.X
= last
.X
+ c2
.X
869 last
.Y
= last
.Y
+ c2
.Y
870 shape
.PolyPolygon
= tuple( list(shape
.PolyPolygon
[:-1]) + [tuple( list(shape
.PolyPolygon
[-1]) + [last
])])
874 shape
.PolyPolygon
= tuple( list(shape
.PolyPolygon
) + [(turtlepos
, __Point__(turtlepos
.X
+ c2
.X
, turtlepos
.Y
+ c2
.Y
))])
878 if not _
.pen
and not dot
:
880 shape
= __draw__("PolyLineShape")
881 shape
.RotateAngle
= 0
882 shape
.PolyPolygon
= tuple([tuple([__Point__(0, 0)])])
884 last
= shape
.PolyPolygon
[-1][-1]
885 last2
= __Point__(last
.X
+ c2
.X
, last
.Y
+ c2
.Y
)
886 shape
.LineStyle
, shape
.LineDash
= __linestyle__(_
.linestyle
)
887 shape
.LineJoint
= _
.linejoint
888 shape
.LineCap
= _
.linecap
889 if dot
or _
.linestyle
== __LineStyle_DOTTED__
:
890 shape
.PolyPolygon
= tuple( list(shape
.PolyPolygon
) + __dots__(n
, last
, c2
.X
, c2
.Y
))
891 shape
.LineStart
= __bezierdot__
892 shape
.LineStartCenter
= True
893 shape
.LineStartWidth
= max(20, _
.pensize
) / __MM10_TO_TWIP__
896 shape
.PolyPolygon
= tuple([tuple( list(shape
.PolyPolygon
[-1]) + [last2
])])
897 shape
.LineWidth
= _
.pensize
/ __MM10_TO_TWIP__
898 shape
.LineColor
, shape
.LineTransparence
= __splitcolor__(_
.pencolor
)
899 if shape
.LineTransparence
== 100:
901 __visible__(shape
, True)
902 shape
.Name
= __ACTUAL__
903 _
.shapecache
[__ACTUAL__
] = shape
906 _
.oldls
= _
.linestyle
907 _
.oldlj
= _
.linejoint
908 _
.oldlcap
= _
.linecap
912 def __fillit__(filled
= True):
913 oldshape
= __getshape__(__ACTUAL__
)
914 if oldshape
and oldshape
.LineStartCenter
:
915 __removeshape__(__ACTUAL__
) # FIXME close dotted polyline
917 if oldshape
and "LineShape" in oldshape
.ShapeType
:
918 shape
= __draw__("PolyPolygonShape", False)
919 shape
.PolyPolygon
= oldshape
.PolyPolygon
920 shape
.setPosition(oldshape
.getPosition())
921 shape
.LineStyle
, shape
.LineDash
= __linestyle__(_
.linestyle
)
922 shape
.LineJoint
= _
.linejoint
923 shape
.LineCap
= _
.linecap
924 shape
.LineWidth
= _
.pensize
/ __MM10_TO_TWIP__
925 shape
.LineColor
, shape
.LineTransparence
= __splitcolor__(_
.pencolor
)
926 shape
.FillColor
, shape
.FillTransparence
= __splitcolor__(_
.areacolor
)
928 shape
.FillBackground
= True if shape
.FillTransparence
!= 100 else False
929 shape
.FillHatch
= _
.hatch
932 shape
.FillStyle
= int(filled
)
933 if shape
.LineTransparence
== 100:
935 if shape
.FillTransparence
== 100:
936 shape
.FillTransparence
= 0 # for hatching and better modifications on UI
939 shape
.setString(oldshape
.getString())
941 shape
.Name
= __ACTUAL__
942 _
.shapecache
[__ACTUAL__
] = shape
944 __group__
.remove(oldshape
)
945 __visible__(shape
, True)
946 _
.drawpage
.remove(oldshape
)
947 elif oldshape
and "PolyPolygon" in oldshape
.ShapeType
:
948 oldshape
.LineStyle
= int(_
.pen
)
949 oldshape
.LineJoint
= _
.linejoint
950 oldshape
.LineCap
= _
.linecap
952 oldshape
.FillBackground
= True
953 oldshape
.FillHatch
= _
.hatch
954 oldshape
.FillStyle
= 3
956 oldshape
.FillStyle
= int(filled
)
957 oldshape
.LineWidth
= _
.pensize
/ __MM10_TO_TWIP__
958 oldshape
.LineColor
, oldshape
.LineTransparence
= __splitcolor__(_
.pencolor
)
959 oldshape
.FillColor
, oldshape
.FillTransparence
= __splitcolor__(_
.areacolor
)
962 oldpen
, _
.pen
= _
.pen
, 1
963 oldstyle
, _
.linestyle
= _
.linestyle
, __LineStyle_DOTTED__
964 __go__(__TURTLE__
, 0, True)
965 _
.pen
, _
.linestyle
= oldpen
, oldstyle
967 def __boxshape__(shapetype
, l
):
968 turtle
= __getshape__(__TURTLE__
)
969 shape
= __draw__(shapetype
+ "Shape")
970 pos
= turtle
.getPosition()
971 pos
.X
= pos
.X
- (l
[0] * __PT_TO_TWIP__
/ __MM10_TO_TWIP__
/ 2) + turtle
.BoundRect
.Width
/ 2.0
972 pos
.Y
= pos
.Y
- (l
[1] * __PT_TO_TWIP__
/ __MM10_TO_TWIP__
/ 2) + turtle
.BoundRect
.Height
/ 2.0
973 shape
.setPosition(pos
)
974 shape
.setSize(__Size__(l
[0] * __PT_TO_TWIP__
/ __MM10_TO_TWIP__
, l
[1] * __PT_TO_TWIP__
/ __MM10_TO_TWIP__
))
975 shape
.LineStyle
, shape
.LineDash
= __linestyle__(_
.linestyle
)
976 shape
.LineWidth
= _
.pensize
/ __MM10_TO_TWIP__
977 shape
.LineJoint
= _
.linejoint
978 shape
.LineCap
= _
.linecap
979 shape
.LineColor
, shape
.LineTransparence
= __splitcolor__(_
.pencolor
)
980 shape
.FillColor
, shape
.FillTransparence
= __splitcolor__(_
.areacolor
)
982 shape
.FillBackground
= True if shape
.FillTransparence
!= 100 else False
983 shape
.FillHatch
= _
.hatch
987 if shape
.LineTransparence
== 100:
989 if shape
.FillTransparence
== 100:
990 shape
.FillTransparence
= 0 # for hatching and better modifications on UI
993 shape
.RotateAngle
= turtle
.RotateAngle
994 if shapetype
== "Rectangle" and len(l
) > 2:
995 shape
.CornerRadius
= (l
[2] * __PT_TO_TWIP__
) / __MM10_TO_TWIP__
996 elif shapetype
== "Ellipse" and len(l
) > 2:
998 shape
.CircleKind
= __SECTION__
999 shape
.CircleStartAngle
= (-l
[3] - 270) * 100
1000 shape
.CircleEndAngle
= (-l
[2] - 270) * 100
1001 shape
.CircleKind
= [__FULL__
, __SECTION__
, __CUT__
, __ARC__
][l
[4]]
1004 __visible__(shape
, True)
1005 __removeshape__(__ACTUAL__
)
1006 _
.shapecache
[__ACTUAL__
] = shape
1010 if type(l
) != type([]): # default for circle and square
1012 if _
.linestyle
== __LineStyle_DOTTED__
:
1014 _
.linestyle
= __LineStyle_SOLID__
1015 pc
, _
.pencolor
= _
.pencolor
, 0xff000000
1017 _
.pencolor
, _
.linestyle
= pc
, __LineStyle_DOTTED__
1019 shape
= __getshape__(__ACTUAL__
)
1020 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
]))
1021 turtle
= __getshape__(__TURTLE__
)
1022 shape
.RotateAngle
= turtle
.RotateAngle
1025 __boxshape__("Ellipse", l
)
1028 if type(l
) != type([]): # default for circle and square
1030 if _
.linestyle
== __LineStyle_DOTTED__
:
1032 _
.linestyle
= __LineStyle_SOLID__
1033 pc
, _
.pencolor
= _
.pencolor
, 0xff000000
1035 _
.pencolor
, _
.linestyle
= pc
, __LineStyle_DOTTED__
1037 shape
= __getshape__(__ACTUAL__
)
1038 if type(l
) != type([]):
1042 l
= [i
* __PT_TO_TWIP__
for i
in l
]
1043 c
= shape
.PolyPolygon
[0][0]
1044 k
= [min(l
[0] / 2.0, l
[2]), min(l
[1] / 2.0, l
[2])]
1045 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)
1046 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])
1047 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)
1048 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])
1050 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:]
1051 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:]
1052 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:]
1053 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:]
1054 shape
.PolyPolygon
= tuple(p
)
1055 turtle
= __getshape__(__TURTLE__
)
1056 shape
.RotateAngle
= turtle
.RotateAngle
1059 __boxshape__("Rectangle", l
)
1062 if type(st
) != type([]):
1065 shape
= _
.doc
.createInstance( "com.sun.star.drawing.TextShape")
1066 shape
.TextAutoGrowWidth
= True
1067 shape
.Visible
= False
1068 actual
= __getshape__(__ACTUAL__
)
1069 _
.drawpage
.add(shape
)
1072 # show text using RectangleShape (for correct SVG export)
1073 ac
, pc
= _
.areacolor
, _
.pencolor
1074 _
.areacolor
, _
.pencolor
= 0xff000000, 0xff000000 # invisible
1075 rectangle([z
.Width
/ (__PT_TO_TWIP__
/ __MM10_TO_TWIP__
), z
.Height
/ (__PT_TO_TWIP__
/ __MM10_TO_TWIP__
)])
1076 _
.drawpage
.remove(shape
)
1077 _
.pencolor
, _
.areacolor
= pc
, ac
1078 lab
= __getshape__(__ACTUAL__
)
1080 if st
[0] != 0 or st
[1] != 0:
1083 n
= [st
[0] * z
.Width
/2, st
[1] * z
.Height
/2]
1084 dx
= n
[1] * sin((pi
/180) * angle
) + n
[0] * sin((pi
/180)*(angle
+ 90))
1085 dy
= n
[1] * cos((pi
/180) * angle
) + n
[0] * cos((pi
/180)*(angle
+ 90))
1086 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)))
1087 _
.shapecache
[__ACTUAL__
] = actual
1089 def text(shape
, st
):
1091 shape
.setString(__string__(st
, _
.decimal
))
1092 c
= shape
.createTextCursor()
1095 c
.CharColor
, none
= __splitcolor__(_
.textcolor
)
1096 c
.CharHeight
= _
.fontheight
1097 c
.CharWeight
= __fontweight__(_
.fontweight
)
1098 c
.CharPosture
= __fontstyle__(_
.fontstyle
)
1099 c
.CharFontName
= _
.fontfamily
1103 __removeshape__(__ACTUAL__
)
1104 for i
in range(int(t
/__SLEEP_SLICE_IN_MILLISECONDS__
)):
1108 __time__
.sleep(t
%__SLEEP_SLICE_IN_MILLISECONDS__
/1000.0)
1110 def __removeshape__(shapename
):
1112 _
.shapecache
.pop(shapename
).Name
= ""
1116 def __fontweight__(w
):
1119 elif re
.match(__l12n__(_
.lng
)['BOLD'], w
, flags
= re
.I
):
1121 elif re
.match(__l12n__(_
.lng
)['NORMAL'], w
, flags
= re
.I
):
1125 def __fontstyle__(w
):
1128 elif re
.match(__l12n__(_
.lng
)['ITALIC'], w
, flags
= re
.I
):
1129 return __Slant_ITALIC__
1130 elif re
.match(__l12n__(_
.lng
)['UPRIGHT'], w
, flags
= re
.I
):
1131 return __Slant_NONE__
1132 return __Slant_NONE__
1135 if type(c
) in [int, float, long]:
1137 if type(c
) == unicode:
1139 return int(random
.random() * 2**31) # max. 50% transparency
1141 c
= __componentcolor__(__colors__
[_
.lng
][c
[1:].lower()])
1143 c
[i
] = max(min(c
[i
] + int(random
.random() * 64) - 32, 255), 0)
1145 return __colors__
[_
.lng
][c
.lower()]
1148 return __COLORS__
[int(c
[0])][1]
1150 return (int(c
[0])%256 << 16) + (int(c
[1])%256 << 8) + int(c
[2])%256
1151 return (int(c
[3])%256 << 24) + (int(c
[0])%256 << 16) + (int(c
[1])%256 << 8) + int(c
[2])%256
1153 def __linestyle__(s
):
1155 return 0, __LineDash__()
1156 if _
.linestyle
== __LineStyle_DASHED__
:
1157 return _
.linestyle
, __LineDash__(__DashStyle_RECT__
, 0, 0, 1, 100, 100)
1158 elif _
.linestyle
== __LineStyle_DOTTED__
:
1159 return __LineStyle_DASHED__
, __LineDash__(__DashStyle_RECT__
, 1, 1, 0, 0, 100000)
1160 elif type(s
) == list:
1161 return __LineStyle_DASHED__
, __LineDash__((s
[5:6] or [0])[0], s
[0], s
[1] * __PT_TO_TWIP__
, s
[2], s
[3] * __PT_TO_TWIP__
, s
[4] * __PT_TO_TWIP__
)
1162 return s
, __LineDash__()
1166 color
, null
= __splitcolor__(__color__(s
[1]))
1167 _
.hatch
= __Hatch__(s
[0] - 1, color
, s
[2] * __PT_TO_TWIP__
, s
[3] * 10)
1170 elif s
<= 10: # using hatching styles of Writer
1171 fillstyle([[1, 0, 5, 0], [1, 0, 5, 45], [1, 0, 5, -45], [1, 0, 5, 90], [2, [127, 0, 0], 5, 45], [2, [127, 0, 0], 5, 0], [2, [0, 0, 127], 5, 45], [2, [0, 0, 127], 5, 0], [3, [0, 0, 127], 5, 0], [1, 0, 25, 45]][s
-1])
1173 def __splitcolor__(c
):
1174 """Split color constants to RGB (3-byte) + transparency (%)"""
1175 return int(c
) & 0xffffff, (int(c
) >> 24) / (255.0/100)
1177 def __componentcolor__(c
):
1178 a
= [ (c
& 0xff0000) >> 16, (c
& 0xff00) >> 8, c
& 0xff ]
1180 a
.append((c
& 0xff000000) >> 24)
1183 def pencolor(n
= -1):
1185 _
.pencolor
= __color__(n
)
1186 turtle
= __getshape__(__TURTLE__
)
1187 if turtle
and __visible__(turtle
):
1188 turtle
.LineColor
, turtle
.LineTransparence
= __splitcolor__(_
.pencolor
)
1190 return __componentcolor__(_
.pencolor
)
1192 def pensize(n
= -1):
1195 _
.pensize
= random
.random() * 10 * __PT_TO_TWIP__
1197 _
.pensize
= n
* __PT_TO_TWIP__
1198 turtle
= __getshape__(__TURTLE__
)
1199 if turtle
and __visible__(turtle
):
1200 turtle
.LineWidth
= min(_
.pensize
, (1 + _
.pen
* 2) * __PT_TO_TWIP__
) / __MM10_TO_TWIP__
1201 return _
.pensize
/ __PT_TO_TWIP__
1203 def penstyle(n
= -1):
1206 return __locname__(_
.linestyle
.value
)
1208 return __locname__('DOTTED')
1209 if type(n
) == list and len(n
) >= 5:
1211 elif re
.match(__l12n__(_
.lng
)['SOLID'], n
, flags
= re
.I
):
1212 _
.linestyle
= __LineStyle_SOLID__
1213 elif re
.match(__l12n__(_
.lng
)['DASH'], n
, flags
= re
.I
):
1214 _
.linestyle
= __LineStyle_DASHED__
1215 elif re
.match(__l12n__(_
.lng
)['DOTTED'], n
, flags
= re
.I
):
1216 _
.linestyle
= __LineStyle_DOTTED__
1218 def penjoint(n
= -1):
1220 return __locname__(_
.linejoint
.value
)
1221 if re
.match(__l12n__(_
.lng
)['NONE'], n
, flags
= re
.I
):
1222 _
.linejoint
= __Joint_NONE__
1223 elif re
.match(__l12n__(_
.lng
)['BEVEL'], n
, flags
= re
.I
):
1224 _
.linejoint
= __BEVEL__
1225 elif re
.match(__l12n__(_
.lng
)['MITER'], n
, flags
= re
.I
):
1226 _
.linejoint
= __MITER__
1227 elif re
.match(__l12n__(_
.lng
)['ROUNDED'], n
, flags
= re
.I
):
1228 _
.linejoint
= __ROUNDED__
1232 return __locname__(_
.linecap
.value
.replace('BUTT', 'NONE'))
1233 if re
.match(__l12n__(_
.lng
)['NONE'], n
, flags
= re
.I
):
1234 _
.linecap
= __Cap_NONE__
1235 elif re
.match(__l12n__(_
.lng
)['ROUNDED'], n
, flags
= re
.I
):
1236 _
.linecap
= __Cap_ROUND__
1237 elif re
.match(__l12n__(_
.lng
)['SQUARE'], n
, flags
= re
.I
):
1238 _
.linecap
= __Cap_SQUARE__
1240 def fillcolor(n
= -1):
1242 _
.areacolor
= __color__(n
)
1243 turtle
= __getshape__(__TURTLE__
)
1244 if turtle
and __visible__(turtle
):
1245 turtle
.FillColor
, transparence
= __splitcolor__(_
.areacolor
)
1246 turtle
.FillTransparence
= min(95, transparence
)
1248 return __componentcolor__(_
.areacolor
)
1250 def fontcolor(n
= -1):
1252 _
.textcolor
= __color__(n
)
1254 return __componentcolor__(_
.textcolor
)
1256 def position(n
= -1):
1257 turtle
= __getshape__(__TURTLE__
)
1262 heading([random
.random() * ps
[0], random
.random() * ps
[1]], True)
1266 pos
= turtle
.getPosition()
1267 pos
.X
, pos
.Y
= pos
.X
+ turtle
.BoundRect
.Width
/ 2.0, pos
.Y
+ turtle
.BoundRect
.Height
/ 2.0
1268 return [ pos
.X
* __MM10_TO_TWIP__
/ __PT_TO_TWIP__
, pos
.Y
* __MM10_TO_TWIP__
/ __PT_TO_TWIP__
]
1270 def __groupstart__(name
= ""):
1271 global __group__
, __grouplefthang__
, __groupstack__
1272 __removeshape__(__ACTUAL__
)
1273 __groupstack__
.append(__group__
)
1274 if name
!= "": # store pic name (for correct repcount)
1275 __groupstack__
.append(name
)
1276 if ".SVG" == name
[-4:].upper():
1278 _
.shapecount
= itertools
.count()
1279 __groupstack__
.append(__grouplefthang__
)
1280 __group__
= uno
.getComponentContext().ServiceManager
.createInstance('com.sun.star.drawing.ShapeCollection')
1281 __grouplefthang__
= 0
1283 def create_svg_animation(m
):
1285 id = int(m
.group(1))
1286 if id - 3 in _
.shapecache
:
1287 t
= _
.shapecache
[id-3]
1288 opacity
= "100" if t
== "0" else "0"
1289 name
= "" if id != 3 else "id=\"first\""
1290 start
= "%sms;last.end+%sms" % (t
, t
) if id == 3 else "first.end+%dms" % (int(t
) - int(_
.shapecache
[0]))
1291 return '<g id="id%s" opacity="0"><animate %s attributeName="opacity" from="100" to="100" begin="%s" dur="1ms" fill="freeze"/><animate attributeName="opacity" from="100" to="%s" begin="last.end" dur="1ms" fill="freeze"/>' % (m
.group(1), name
, start
, opacity
)
1294 def create_valid_svg_file(filename
):
1295 with
open(filename
, "r") as f
:
1297 s
= re
.sub('(?s)(<g\\sid="[^"]*)\(([^"]*)\)', '\\1\\2', s
) # bad "(", ")" in xml:id
1298 s
= re
.sub('(?s)<g\\sooo:[^>]*>', '', s
) # remove non standard attributes
1299 s
= re
.sub('(?s)<defs class="EmbeddedBulletChars">.*(?=<defs class="TextEmbeddedBitmaps")', '', s
) # remove unused parts
1300 s
= re
.sub('(?s)(<path stroke-width="[^"]*"[^<]*)stroke-width="[^"]*"', '\\1', s
) # double stroke-width
1301 s
= re
.sub('(?s)<svg\\s+version="1.2"', '<svg version="1.1"', s
) # for W3C Validator
1303 s
= re
.sub('<g id="id([0-9]+)">', create_svg_animation
, s
)
1304 m
= re
.match('(?s)(.*<animate[^>]*first[.]end.([0-9]+)[^>]* dur=")1ms"', s
)
1305 lasttime
= _
.time
- int(m
.group(2)) - int(_
.shapecache
[0]) + 1
1307 s
= re
.sub('(?s)(.*<animate[^>]*first[.]end.([0-9]+)[^>]* dur=")1ms"', m
.group(1) + str(lasttime
) + 'ms" id="last"', s
)
1308 with
open(filename
, 'w') as f
:
1311 def __groupend__(name
= ""):
1312 global __group__
, __grouplefthang__
, __groupstack__
, __halt__
1314 if __group__
.getCount() > 1:
1315 if __grouplefthang__
< 0:
1316 for i
in range(__group__
.Count
):
1317 s
= __group__
.getByIndex(i
)
1319 p
.X
= p
.X
+ -__grouplefthang__
1321 g
= _
.drawpage
.group(__group__
)
1323 p
.X
= p
.X
+ __grouplefthang__
1326 g
= _
.drawpage
.group(__group__
)
1327 g
.TextWrap
= __THROUGHT__
1328 elif __group__
.getCount() == 1:
1329 g
= __group__
.getByIndex(0)
1330 __grouplefthang__
= min(__groupstack__
.pop(), __grouplefthang__
)
1332 name
= __groupstack__
.pop()
1333 if name
and ".SVG" == name
[-4:].upper() and g
:
1334 _
.doc
.CurrentController
.select(g
)
1335 __dispatcher__(".uno:Copy")
1336 ctx
= XSCRIPTCONTEXT
.getComponentContext()
1337 d
= ctx
.ServiceManager
.createInstanceWithContext("com.sun.star.frame.Desktop", ctx
)
1338 draw
= d
.loadComponentFromURL("private:factory/sdraw", "_blank", 0, ())
1339 drawpage
= draw
.getDrawPages().getByIndex(0)
1340 while XSCRIPTCONTEXT
.getDocument() != draw
:
1341 if XSCRIPTCONTEXT
.getDocument() not in [draw
, _
.doc
, None]:
1345 __dispatcher__(".uno:Paste", (), draw
)
1346 __dispatcher__(".uno:FormatGroup", (), draw
)
1347 pic
= drawpage
.getByIndex(0)
1348 pic
.setPosition(__Point__((g
.BoundRect
.Width
- g
.Size
.Width
)//2, (g
.BoundRect
.Height
- g
.Size
.Height
)//2))
1349 drawpage
.Height
, drawpage
.Width
= g
.BoundRect
.Height
, g
.BoundRect
.Width
1350 if not os
.path
.isabs(name
):
1351 name
= os
.path
.expanduser('~') + os
.path
.sep
+ name
1352 __dispatcher__(".uno:ExportTo", (__getprop__("URL", unohelper
.systemPathToFileUrl(name
)), __getprop__("FilterName", "draw_svg_Export")), draw
)
1354 while XSCRIPTCONTEXT
.getDocument() != _
.doc
:
1355 if XSCRIPTCONTEXT
.getDocument() not in [draw
, _
.doc
, None]:
1359 create_valid_svg_file(name
)
1360 __group__
= __groupstack__
.pop()
1363 __removeshape__(__ACTUAL__
)
1365 def __int__(x
): # handle eg. int("10cm")
1366 if type(x
) == str or type(x
) == unicode:
1370 def __float__(x
): # handle eg. float("10,5cm")
1371 if type(x
) == str or type(x
) == unicode:
1372 for i
in __comp__
[_
.lng
]:
1373 x
= re
.sub(u
"(?iu)" + i
[0], i
[1], x
)
1377 def fontheight(n
= -1):
1383 def fontweight(n
= -1):
1389 def fontfamily(s
= -1):
1395 def fontstyle(n
= -1):
1401 def __loadlang__(lang
, a
):
1402 global comp
, __colors__
1403 __colors__
[lang
] = {}
1404 for i
in __COLORS__
:
1405 for j
in a
[i
[0]].split("|"):
1406 __colors__
[lang
][j
] = i
[1]
1408 if not i
[0:3] in ["LIB", "ERR", "PT", "INC", "MM", "CM", "HOU", "DEG"] and not i
in __STRCONST__
: # uppercase native commands
1410 repcount
= a
['REPCOUNT'].split('|')[0]
1411 loopi
= itertools
.count()
1412 loop
= lambda r
: "%(i)s = 1\n%(orig)s%(j)s = %(i)s\n%(i)s += 1\n" % \
1413 { "i": repcount
+ str(next(loopi
)), "j": repcount
, "orig": re
.sub( r
"(?ui)(?<!:)\b%s\b" % repcount
, repcount
+ str(next(loopi
)-1), r
.group(0)) }
1415 [r
"(?i)(?<!:)(\b|(?=[-:]))(?:%s)\b" % "|".join([a
[i
].lower() for i
in a
if not "_" in i
and i
!= "DECIMAL"]), lambda s
: s
.group().upper()], # uppercase all native commands in the source code
1416 [r
"(?<!:)\b(?:%s) \[(?= |\n)" % a
['GROUP'], "\n__groupstart__()\nfor __groupindex__ in range(2):\n[\nif __groupindex__ == 1:\n[\n__groupend__()\nbreak\n]\n"],
1417 [r
"(?<!:)\b(?:%s) (%s[^[]*)\[(?= |\n)" % (a
['GROUP'], __DECODE_STRING_REGEX__
), "\n__groupstart__(\\1)\nfor __groupindex__ in range(2):\n[\nif __groupindex__ == 1:\n[\n__groupend__(\\1)\nbreak\n]\n"],
1418 [r
"(?<!:)\b(?:%s)\b" % a
['GROUP'], "\n__removeshape__(__ACTUAL__)\n"],
1419 [r
"(\n| )][ \n]*\[(\n| )", "\n]\nelse:\n[\n"], # if/else block
1420 [r
"(?<!\n)\[(?= |\n)", ":\n[\n"], # start block
1421 [r
"( ]|\n]$)", "\n]\n"], # finish block
1422 [r
"(?<!:)\b(?:%s)\b" % a
['FOR'], "\nfor"],
1423 [r
"(?<!:)\b(?:%s)\b" % a
['REPEAT'], "\n__repeat__"],
1424 [r
"(?<!:)\b(?:%s)\b" % a
['BREAK'], "\nbreak"],
1425 [r
"(?<!:)\b(?:%s)\b" % a
['CONTINUE'], "\ncontinue"],
1426 [r
"(?<!:)\b(?:%s)\b" % a
['REPCOUNT'], repcount
],
1427 [r
"(?<!:)\b(?:%s)\b" % a
['IF'], "\nif"],
1428 [r
"(?<!:)\b(?:%s)\b" % a
['WHILE'], "\nwhile"],
1429 [r
"(?<!:)\b(?:%s)\b" % a
['OUTPUT'], "\nreturn"],
1430 [r
"\n(if|while|return) [^\n]*", lambda r
: re
.sub("(?<![=!<>])=(?!=)", "==", r
.group(0))], # = -> ==, XXX x = y = 1?
1431 [r
"(?<=\n)(for\b :?\w+) ([^\n]+)(?<=\w|]|}|\))(?=-|:)(?:%s)\b" % a
['IN'], "\\1 in \\2"], # "for x y-in" -> "for x in y"
1432 [r
"(:?\b\w+|[[][^[\n]*])\b(?:%s)\b" % a
['IN'], "in \\1"], # "x y-in" -> "x in y"
1433 [r
"(?<!:)\b(?:%s)\b" % a
['IN'], "in"],
1434 [r
"(?<!:)\b(?:%s)\b[ \t]+(:?\w+)\b(?! in\b)" % a
['FOR'], "\nfor \\1 in"],
1435 [r
"(?<=\n)__repeat__ :\n", "while True:\n"], # infinite loop
1436 [r
"(?<=\n)(for|while) (?!__groupindex__)[^\n]*:\n\[\n", loop
], # loop variables for repcount (not groupindex loop)
1437 [r
"(?<=\n)__repeat__([^\n]*\w[^\n]*):(?=\n)", "for %s in range(1, 1+int(\\1)):" % repcount
], # repeat block
1438 [r
"(?<=\d)[%s](?=\d)" % a
['DECIMAL'], "."], # decimal sign
1439 [r
"(?<!/)/(?!/)", "*1.0/"], # fix division: /1 -> /1.0, but not with //
1440 [r
"\b([0-9]+([,.][0-9]+)?)(%s)\b" % a
['HOUR'], lambda r
: str(float(r
.group(1).replace(",", "."))*30)], # 12h = 12*30°
1441 [r
"(?<=\d)(%s)" % a
['DEG'], ""], # 1° -> 1
1442 [r
"(?<!:)\b(?:__def__)[ \t]+(\w+)\b[ \t]*([:]?\w[^\n]*)", "\ndef \\1(\\2):\n["],
1443 [r
"(?<!:)\b(?:__def__)\s+(\w+)", "\ndef \\1():\n["],
1444 [r
"(?<!:)\b(?:%s)\b" % a
['END'], "\n]"],
1445 [r
"(?<!:)\b(?:%s)\b" % a
['GLOBAL'], "global"],
1446 [r
"(?<!:)\b(?:%s)\b" % a
['TRUE'], "True"],
1447 [r
"(?<!:)\b(?:%s)\b" % a
['FALSE'], "False"],
1448 [r
"(?<!:)\b(?:%s)\b" % a
['NOT'], "not"],
1449 [r
"(?<!:)\b(?:%s)\b" % a
['AND'], "and"],
1450 [r
"(?<!:)\b(?:%s)\b" % a
['OR'], "or"],
1451 [r
"(?<!:)\b(?:%s)\b" % a
['INT'], "__int__"],
1452 [r
"(?<!:)\b(?:%s)\b" % a
['FLOAT'], "__float__"],
1453 [r
"(?<!:)\b(?:%s)\b" % a
['STR'], "__string__"],
1454 [r
"(?<!:)\b(?:%s)\b" % a
['COUNT'], "len"],
1455 [r
"(?<!:)\b(?:%s)\b" % a
['ROUND'], "round"],
1456 [r
"(?<!:)\b(?:%s)\b" % a
['ABS'], "abs"],
1457 [r
"(?<!:)\b(?:%s)\b" % a
['SIN'], "sin"],
1458 [r
"(?<!:)\b(?:%s)\b" % a
['COS'], "cos"],
1459 [r
"(?<!:)\b(?:%s)\b" % a
['PI'], "pi"],
1460 [r
"(?<!:)\b(?:%s)\b" % a
['SQRT'], "sqrt"],
1461 [r
"(?<!:)\b(?:%s)\b" % a
['MIN'], "min"],
1462 [r
"(?<!:)\b(?:%s)\b" % a
['MAX'], "max"],
1463 [r
"(?<!:)\b(?:%s)\b" % a
['STOP'], "\nreturn None"],
1464 [r
"(?<!:)\b(?:%s)\b" % a
['CLEARSCREEN'], "\n__cs__()"],
1465 [r
"(?<!:)\b(?:%s)(\s+|$)" % a
['PENCOLOR'], "\n)pencolor("],
1466 [r
"(?<!:)\b(?:%s)(\s+|$)" % a
['PENSTYLE'], "\n)penstyle("],
1467 [r
"(?<!:)\b(?:%s)(\s+|$)" % a
['PENJOINT'], "\n)penjoint("],
1468 [r
"(?<!:)\b(?:%s)(\s+|$)" % a
['PENCAP'], "\n)pencap("],
1469 [r
"(?<!:)\b(?:%s)(\s+|$)" % a
['FILLCOLOR'], "\n)fillcolor("],
1470 [r
"(?<!:)\b(?:%s)(\s+|$)" % a
['FILLSTYLE'], "\n)fillstyle("],
1471 [r
"(?<!:)\b(?:%s)(\s+|$)" % a
['FONTCOLOR'], "\n)fontcolor("],
1472 [r
"(?<!:)\b(?:%s)(\s+|$)" % a
['FONTFAMILY'], "\n)fontfamily("],
1473 [r
"(?<!:)\b(?:%s)(\s+|$)" % a
['FONTHEIGHT'], "\n)fontheight("],
1474 [r
"(?<!:)\b(?:%s)(\s+|$)" % a
['FONTWEIGHT'], "\n)fontweight("],
1475 [r
"(?<!:)\b(?:%s)(\s+|$)" % a
['FONTSTYLE'], "\n)fontstyle("],
1476 [r
"(?<!:)\b(?:%s)(\s+|$)" % a
['PENWIDTH'], "\n)pensize("],
1477 [r
"(?<!:)\b(?:%s)\b" % a
['PENDOWN'], "\n__pen__(1)"],
1478 [r
"(?<!:)\b(?:%s)\b" % a
['PENUP'], "\n__pen__(0)"],
1479 [r
"(?<!:)\b(?:%s)\b" % a
['HIDETURTLE'], "\nhideturtle()"],
1480 [r
"(?<!:)\b(?:%s)\b" % a
['SHOWTURTLE'], "\nshowturtle()"],
1481 [r
"(?<!:)\b(?:%s)\b\[" % a
['POSITION'], "position()["],
1482 [r
"(?<!:)\b(?:%s)\b(?!\()" % a
['POSITION'], "\n)position("],
1483 [r
"(?<!:)\b(?:%s)\b" % a
['HEADING'], "\n)heading("],
1484 [r
"(?<!:)\b(?:%s)\b" % a
['PAGESIZE'], "pagesize()"],
1485 [r
"(?<!:)\b(?:%s)\b" % a
['POINT'], "\npoint()"],
1486 [r
"(?<!:)\b(?:%s)\b" % (a
['ELLIPSE'] + "|" + a
['CIRCLE']), "\n)ellipse("],
1487 [r
"(?<!:)\b(?:%s)\b" % (a
['RECTANGLE'] + "|" + a
['SQUARE']), "\n)rectangle("],
1488 [r
"(?<!:)\b(?:%s)\b" % a
['CLOSE'], "\n__fillit__(False)"],
1489 [r
"(?<!:)\b(?:%s)\b" % a
['FILL'], "\n__fillit__()"],
1490 [r
"(?<!:)\b(?:%s)\b" % a
['LABEL'], "\n)label("],
1491 [r
"(?<!:)\b(?:%s)\b" % a
['TEXT'], "\n)text(__getshape__(__ACTUAL__),"],
1492 [r
"(text\([ \t]*\"[^
\"\n\
)]*)", "\\1\"\n"],
1493 [r"(?
<!:)\b(?
:%s)\b" % a['HOME'], "\nturtlehome
()"],
1494 [r"(?
<!:)\b(?
:%s)\b" % a['SLEEP'], "\n)sleep("],
1495 [r"(?
<!:)\b(?
:%s)\b" % a['FORWARD'], "\n)forward("],
1496 [r"(?
<!:)\b(?
:%s)\b" % a['BACKWARD'], "\n)backward("],
1497 [r"(?
<!:)\b(?
:%s)\b" % a['TURNRIGHT'], "\n)turnright("],
1498 [r"(?
<!:)\b(?
:%s)\b" % a['RANDOM'], "Random
"],
1499 [r"(?
<!:)\b(?
:%s)\b(?
= \d
)" % 'Random', "random
.random()*"],
1500 [r"(?
<!:)\b(?
:%s)\b" % a['SET'], "set"],
1501 [r"(?
<!:)\b(?
:%s)\b" % a['RANGE'], "range"],
1502 [r"(?
<!:)\b(?
:%s)\b" % a['LIST'], "list"],
1503 [r"(?
<!:)\b(?
:%s)\b" % a['TUPLE'], "tuple"],
1504 [r"(?
<!:)\b(?
:%s)\b" % a['SORTED'], "sorted"],
1505 [r"(?
<!:)\b(?
:%s)\b ?\
(" % a['RESEARCH'], "re
.search('(?u)'+"],
1506 [r"(?
<!:)\b(?
:%s)\b ?\
(" % a['RESUB'], "re
.sub('(?u)'+"],
1507 [r"(?
<!:)\b(?
:%s)\b ?\
(" % a['REFINDALL'], "re
.findall('(?u)'+"],
1508 [r"(?
<!:)\b(?
:%s)\b" % a['ANY'], "u
'any'"],
1509 [r"(?
<!:)\b(?
:%s) (\w
+|
[[][^\
]]*])\b" % a['INPUT'], " Input(\\1)"],
1510 [r"(?
<!:)\b(?
:%s)\b" % a['PRINT'], "\n)Print("],
1511 [r"(?
<!:)\b(?
:%s)\b" % a['TURNLEFT'], "\n)turnleft("],
1512 [r"\b([0-9]+([,.][0-9]+)?
)(%s)\b" % a['PT'], "\\1"],
1513 [r"\b([0-9]+([,.][0-9]+)?
)(%s)(?
!\w
)" % a['INCH'], lambda r: str(float(r.group(1).replace(",", "."))*72)],
1514 [r"\b([0-9]+([,.][0-9]+)?
)(%s)\b" % a['MM'], lambda r: str(float(r.group(1).replace(",", "."))*__MM_TO_PT__)],
1515 [r"\b([0-9]+([,.][0-9]+)?
)(%s)\b" % a['CM'], lambda r: str(float(r.group(1).replace(",", "."))*__MM_TO_PT__*10)],
1516 [r"\b(__(?
:int|
float|string
)__len|
round|
abs|sin|cos|sqrt|
set|
list|
tuple|
sorted)\b ((?
:\w|\d
+([,.]\d
+)?|
0[xX
][0-9a
-fA
-F
]+|
[-+*/]|
)+)\
)" , "\\1(\\2))" ], # fix parsing: (1 + sqrt x) -> (1 + sqrt(x))
1517 [r"(?
<=[-*/=+,]) ?
\n\
)(\w
+)\
(", "\\1()"], # read attributes, eg. x = fillcolor
1518 [r"(?
<=return) ?
\n\
)(\w
+)\
(", "\\1()"], # return + user function
1519 [r"(?
<=(?
:Print|label
)\
() ?
\n\
)(\w
+)\
(", "\\1()\n"] # Print/label + user function
1522 def __concatenation__(r): # keep line positions with extra line breaks
1523 s = re.subn("~
[ \t]*\n", " ", r.group(0))
1524 return s[0] + "\n" * s[1]
1527 global _, comp, __strings__, __compiled__
1529 c = _.doc.CurrentController.getViewCursor()
1530 locs = [i for i in [c.CharLocale, c.CharLocaleAsian, c.CharLocaleComplex] if i.Language != 'zxx'] # not None language
1531 loc = Locale(__uilocale__.split('-')[0], __uilocale__.split('-')[1], '')
1532 if locs and loc not in locs:
1535 _.lng = loc.Language + '_' + loc.Country
1536 __loadlang__(_.lng, __l12n__(_.lng))
1539 _.lng = loc.Language
1540 __loadlang__(_.lng, __l12n__(_.lng))
1544 if not _.lng in __comp__:
1545 __loadlang__(_.lng, __l12n__(_.lng))
1547 _.decimal = __l12n__(_.lng)['DECIMAL']
1550 rmsp = re.compile(r"[ ]*([=+*/]|
==|
<=|
>=|
<>|
!=|
-[ ]+)[ ]*")
1551 chsp = re.compile(r"[ \t]+")
1552 chch = re.compile(r"(?u
)(?
<!\w
):(?
=\w
)")
1553 parenfix = re.compile(r"(?ui
)(\
([^\
(\
[\
]\
)]+)]\
)")
1555 # remove CR characters and split lines
1556 s = re.sub(r'[ \t\r]*(?=\n)', '', s)
1558 # remove full line comments
1559 s = re.sub(r"^
[ \t]*[;#][^\n]*", "", s)
1560 s
= re
.sub(r
"(?<=\n)[ \t]*[;#][^\n]*", "", s
)
1563 __compiled__
= re
.sub(r
'([^\n]*~[ \t]*\n)+[^\n]*', __concatenation__
, s
)
1565 # sign original line breaks
1566 s
= re
.sub("(?<=\n)", __LINEBREAK__
+ "\n", __compiled__
)
1569 lq
= '\'' + __l12n__(_
.lng
)['LEFTSTRING'].replace("|", "")
1570 rq
= '\'' + __l12n__(_
.lng
)['RIGHTSTRING'].replace("|", "")
1572 s
= re
.sub("(?u)([%s])([^\n%s]*)(?<!\\\\)[%s]" % (lq
, rq
, rq
), __encodestring__
, s
)
1573 s
= re
.sub('(?u)(?<![0-9])(")(~?\w*)', __encodestring__
, s
)
1575 # remove extra spaces
1576 s
= chsp
.sub(" ", s
)
1578 # remove inline comments
1579 s
= re
.sub(r
"[ ]*;[^\n]*", "", s
)
1581 # n-dash and m-dash as minus signs
1582 s
= re
.sub(r
"(?u)[–—]", "-", s
)
1584 # replace procedure names
1585 s
= re
.sub(r
"(?i)^[ ]*(%s)[ ]+" % __l12n__(_
.lng
)['TO'], "__def__ ", s
)
1586 s
= re
.sub(r
"(?i)\n[ ]*(%s)[ ]+" % __l12n__(_
.lng
)['TO'], "\n__def__ ", s
)
1587 subnames
= re
.findall(u
"(?iu)(?<=__def__ )\w+", s
)
1589 functions
= ["range", "__int__", "__float__", "Random", "Input", "__string__", "len", "round", "abs", "sin", "cos", "sqrt", "set", "list", "tuple", "re.sub", "re.search", "re.findall", "sorted", "min", "max"]
1591 if len(subnames
) > 0:
1592 globs
= "global %s" % ", ".join(subnames
)
1593 # search user functions (function calls with two or more arguments need explicite Python parentheses)
1594 functions
+= [ re
.findall("(?u)\w+",i
[0])[0] for i
in re
.findall(r
"""(?iu)(?<=__def__ )([^\n]*)\n # beginning of a procedure
1595 (?:[^\n]*(?<!\b(%(END)s))\n)* # 0 or more lines (not END)
1596 [^\n]*\b(?:%(OUTPUT)s)\b[^\n]*\n # line with OUTPUT (functions = procedures with OUTPUT)
1597 (?:[^\n]*(?<!\b(?:%(END)s))\n)* # 0 or more lines (not END)
1598 [ \t]*\b(?:%(END)s)\b""" % __l12n__(_
.lng
), s
, re
.X
) ] # final END (XXX multiple names of "END" doesn't supported)
1599 # add line breaks before procedure calls
1600 procedures
= set(subnames
) - set(functions
)
1601 if len(procedures
) > 0:
1602 s
= re
.sub(r
"(?<!__def__)(?<![-+=*/])(?<!%s)(?:^|[ \t]+)(" % ")(?<!".join(functions
) + "|".join(procedures
) + ")(?!\w)", r
"\n\1", s
)
1604 # compile native Logo
1605 for i
in __comp__
[_
.lng
]:
1606 s
= re
.sub(u
"(?u)" + i
[0], i
[1], s
)
1609 func
= re
.compile("(?iu)(def (\w+))(\(.*\):)")
1610 expr
= r
"""(?iu)(?<!def[ ])(?<![:\w])%(name)s(?!\w)(?!\()(?![ ]\()
1612 ([ ]+\[*([-+]|\([ ]?)*((%(functions)s)\b[ ]*\(*)*
1613 (?:0x[0-9a-f]+|[0-9]+([,.][0-9]+)?|:?\w+(?:[.]\w+[\(]?[\)]?)?]*|\[])]*[\)]*
1615 (?:[ ]*([+*/,<>]|//|==|<=|>=|<>|!=)[ ]*|[ ]*-[ ]+|-|[ ]*[*][*][ ]*) # operators, eg. "**", " - ", "-", "- "
1616 \[*([-+]|\([ ]?)* # minus sign, parenthesis
1617 ((%(functions)s)\b[ ]*\(*)*(0x[0-9a-f]+|[0-9]+([.,][0-9]+)?|:?\w+(?:[.]\w+[\(]?[\)]?)?)]*
1622 chargsp
= re
.compile(r
"(?<![\(,])(?<!%s) (?!\)|,)" % ")(?<!".join(functions
))
1625 joinfunc
= "|".join(functions
)
1628 for i
in s
.split("\n"):
1630 if i
[0:4] == 'def ':
1632 if s
.group(3) == '():':
1633 names
[s
.group(2)] = (0, "")
1635 s2
= len(chsp
.findall(s
.group(3))) + 1
1636 i
= s
.group(1) + chsp
.sub(", ", s
.group(3))
1637 names
[s
.group(2)] = (s2
, re
.compile(expr
% {"name": s
.group(2), "functions": joinfunc
, "repeat": s2
}, re
.X
))
1640 if not j
in funcnames
:
1641 funcnames
[j
] = (1, re
.compile(expr
% {"name": j
, "functions": joinfunc
, "repeat": 1 + 2 * int(j
== 'range')}, re
.X
))
1642 r
= funcnames
[j
][1].search(i
)
1644 i
= i
[:r
.start()] + j
+ '(' + chargsp
.sub(", ", rmsp
.sub(lambda l
: l
.group(1).strip(), r
.group(1).strip())) + ')' + i
[r
.end():]
1645 i
= parenfix
.sub("\\1)]", i
)
1646 r
= funcnames
[j
][1].search(i
)
1649 if names
[j
][0] == 0:
1650 if not j
in functions
:
1651 i
= re
.sub(r
"(?iu)(?<!def )(?<![_\w])\b%s\b(?!\w)" %j
, j
+'()', i
)
1653 r
= names
[j
][1].search(i
)
1655 i
= i
[:r
.start()] + j
+ '(' + chargsp
.sub(", ", rmsp
.sub(lambda l
: l
.group(1).strip(), r
.group(1).strip())) + ')' + i
[r
.end():]
1656 i
= parenfix
.sub("\\1)]", i
)
1660 result
= result
+ "\n" + " " * indent
+ "__checkhalt__()\n"
1663 result
= result
+ "\n" + " " * indent
+ i
1665 result
= result
[:-1]
1668 # colon_to_underline in Logo variables
1669 result
= chch
.sub("_", result
)
1671 # character encoding
1672 result
= to_ascii(result
).replace(r
"\n", "\n")
1675 result
= re
.sub(__DECODE_STRING_REGEX__
, __decodestring__
, result
)
1676 return to_ascii(globs
) + "\n" + result
1678 def __gotoline__(n
):
1679 _
.cursor
.collapseToStart()
1680 for i
in range(1, n
):
1681 _
.cursor
.gotoNextParagraph(False)
1683 _
.doc
.CurrentController
.getViewCursor().gotoRange(_
.cursor
, False)
1685 __dispatcher__(".uno:Escape")
1686 _
.doc
.CurrentController
.getViewCursor().gotoRange(_
.cursor
.getStart(), False)
1688 g_exportedScripts
= left
, right
, goforward
, gobackward
, run
, stop
, home
, clearscreen
, commandline
, __translate__
1689 g_ImplementationHelper
= unohelper
.ImplementationHelper()
1690 g_ImplementationHelper
.addImplementation( \
1691 None,"org.openoffice.script.LibreLogo", \
1692 ("org.openoffice.script.ServiceLibreLogo",),)
1694 # vim: set noet sw=4 ts=4: