You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
441 lines
12 KiB
441 lines
12 KiB
#!/usr/bin/env python3
|
|
|
|
# ~ This file is part of ZAZ.
|
|
|
|
# ~ ZAZ is free software: you can redistribute it and/or modify
|
|
# ~ it under the terms of the GNU General Public License as published by
|
|
# ~ the Free Software Foundation, either version 3 of the License, or
|
|
# ~ (at your option) any later version.
|
|
|
|
# ~ ZAZ is distributed in the hope that it will be useful,
|
|
# ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# ~ GNU General Public License for more details.
|
|
|
|
# ~ You should have received a copy of the GNU General Public License
|
|
# ~ along with ZAZ. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
import logging
|
|
|
|
|
|
# ~ Type extension:
|
|
# ~ 1 = normal extension
|
|
# ~ 2 = new component
|
|
# ~ 3 = Calc addin
|
|
TYPE_EXTENSION = 1
|
|
|
|
# ~ https://semver.org/
|
|
VERSION = '0.2.0'
|
|
|
|
# ~ Your great extension name, not used spaces or "-_"
|
|
NAME = 'ZAZLaTex2SVG'
|
|
|
|
# ~ Should be unique, used URL inverse
|
|
ID = 'net.elmau.zaz.latex2svg'
|
|
|
|
# ~ If you extension will be multilanguage set: True
|
|
# ~ This feature used gettext, set pythonpath and easymacro in True
|
|
# ~ You can used PoEdit for edit PO files and generate MO files.
|
|
# ~ https://poedit.net/
|
|
USE_LOCALES = True
|
|
DOMAIN = 'base'
|
|
PATH_LOCALES = 'locales'
|
|
PATH_PYGETTEXT = '/usr/lib/python3.8/Tools/i18n/pygettext.py'
|
|
PATH_MSGMERGE = 'msgmerge'
|
|
|
|
|
|
# ~ Show in extension manager
|
|
PUBLISHER = {
|
|
'en': {'text': 'El Mau', 'link': 'https://gitlab.com/mauriciobaeza'},
|
|
'es': {'text': 'El Mau', 'link': 'https://gitlab.com/mauriciobaeza'},
|
|
}
|
|
|
|
# ~ Name in this folder for copy
|
|
ICON = 'images/logo.png'
|
|
# ~ Name inside extensions
|
|
ICON_EXT = f'{NAME.lower()}.png'
|
|
|
|
# ~ For example
|
|
# ~ DEPENDENCIES_MINIMAL = '6.0'
|
|
DEPENDENCIES_MINIMAL = ''
|
|
|
|
# ~ Change for you favorite license
|
|
LICENSE_EN = f"""This file is part of {NAME}.
|
|
|
|
{NAME} is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
{NAME} is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with {NAME}. If not, see <https://www.gnu.org/licenses/>.
|
|
"""
|
|
LICENSE_ES = LICENSE_EN
|
|
|
|
INFO = {
|
|
'en': {
|
|
'display_name': NAME,
|
|
'description': 'Generate equations in SVG from LaTex',
|
|
'license': LICENSE_EN,
|
|
},
|
|
'es': {
|
|
'display_name': NAME,
|
|
'description': 'Genera ecuaciones en SVG desde LaTex',
|
|
'license': LICENSE_ES,
|
|
},
|
|
}
|
|
|
|
|
|
# ~ Menus, only for TYPE_EXTENSION = 1
|
|
# ~ Parent can be: AddonMenu or OfficeMenuBar
|
|
# ~ For icons con name: NAME_16.bmp, used only NAME
|
|
# ~ PARENT = ''
|
|
# ~ MENU_MAIN = {}
|
|
# ~ Shortcut: Key + "Modifier Keys"
|
|
# ~ Important: Not used any shortcuts used for LibreOffice
|
|
# ~ SHIFT is mapped to Shift on all platforms.
|
|
# ~ MOD1 is mapped to Ctrl on Windows/Linux, while it is mapped to Cmd on Mac.
|
|
# ~ MOD2 is mapped to Alt on all platforms.
|
|
# ~ For example: Shift+Ctrl+Alt+T -> T_SHIFT_MOD1_MOD2
|
|
PARENT = 'OfficeMenuBar'
|
|
MENU_MAIN = {
|
|
'en': 'ZAZ LaTex2Svg',
|
|
'es': 'ZAZ LaTex2Svg',
|
|
}
|
|
MENUS = (
|
|
{
|
|
'title': {'en': 'From selection', 'es': 'Desde selección'},
|
|
'argument': 'from_selection',
|
|
'context': 'calc,writer,draw,impress',
|
|
'icon': 'icon1',
|
|
'toolbar': False,
|
|
'shortcut': '',
|
|
},
|
|
{
|
|
'title': {'en': 'Insert...', 'es': 'Insertar...'},
|
|
'argument': 'from_dialog',
|
|
'context': 'calc,writer,draw,impress',
|
|
'icon': 'icon1',
|
|
'toolbar': False,
|
|
'shortcut': '',
|
|
},
|
|
{
|
|
'title': {'en': 'Validate applications', 'es': 'Validar aplicaciones'},
|
|
'argument': 'validate_app',
|
|
'context': 'calc,writer,draw,impress',
|
|
'icon': 'icon2',
|
|
'toolbar': False,
|
|
'shortcut': '',
|
|
},
|
|
)
|
|
|
|
|
|
# ~ Functions, only for TYPE_EXTENSION = 3
|
|
FUNCTIONS = {
|
|
'test': {
|
|
'displayname': {'en': 'test', 'es': 'prueba'},
|
|
'description': {'en': 'My test', 'es': 'Mi prueba'},
|
|
'parameters': {
|
|
'value': {
|
|
'displayname': {'en': 'value', 'es': 'valor'},
|
|
'description': {'en': 'The value', 'es': 'El valor'},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
# ~ FUNCTIONS = {}
|
|
|
|
EXTENSION = {
|
|
'version': VERSION,
|
|
'name': NAME,
|
|
'id': ID,
|
|
'icon': (ICON, ICON_EXT),
|
|
'languages': tuple(INFO.keys())
|
|
}
|
|
|
|
|
|
# ~ If used more libraries set python path in True and copy inside
|
|
# ~ If used easymacro pythonpath always is True, recommended
|
|
DIRS = {
|
|
'meta': 'META-INF',
|
|
'source': 'source',
|
|
'description': 'description',
|
|
'images': 'images',
|
|
'registration': 'registration',
|
|
'files': 'files',
|
|
'office': 'Office',
|
|
'locales': PATH_LOCALES,
|
|
'pythonpath': True,
|
|
}
|
|
|
|
|
|
FILES = {
|
|
'oxt': f'{NAME}_v{VERSION}.oxt',
|
|
'py': f'{NAME}.py',
|
|
'ext_desc': 'desc_{}.txt',
|
|
'manifest': 'manifest.xml',
|
|
'description': 'description.xml',
|
|
'idl': f'X{NAME}.idl',
|
|
'addons': 'Addons.xcu',
|
|
'urd': f'X{NAME}.urd',
|
|
'rdb': f'X{NAME}.rdb',
|
|
'update': f'{NAME.lower()}.update.xml',
|
|
'addin': 'CalcAddIn.xcu',
|
|
'shortcut': 'Accelerators.xcu',
|
|
'easymacro': True,
|
|
}
|
|
|
|
|
|
# ~ URLs for update for example
|
|
# ~ URL_XML_UPDATE = 'https://gitlab.com/USER/PROYECT/raw/BRANCH/FOLDERs/FILE_NAME'
|
|
URL_XML_UPDATE = ''
|
|
URL_OXT = ''
|
|
|
|
|
|
# ~ Default program for test: --calc, --writer, --draw
|
|
PROGRAM = '--calc'
|
|
# ~ Path to file for test
|
|
FILE_TEST = ''
|
|
|
|
PATHS = {
|
|
'idlc': '/usr/lib/libreoffice/sdk/bin/idlc',
|
|
'include': '/usr/share/idl/libreoffice',
|
|
'regmerge': '/usr/lib/libreoffice/program/regmerge',
|
|
'soffice': ('soffice', PROGRAM, FILE_TEST),
|
|
'install': ('unopkg', 'add', '-v', '-f', '-s'),
|
|
'profile': '/home/mau/.config/libreoffice/4/user',
|
|
'gettext': PATH_PYGETTEXT,
|
|
'msgmerge': PATH_MSGMERGE,
|
|
}
|
|
|
|
|
|
SERVICES = {
|
|
'job': "('com.sun.star.task.Job',)",
|
|
'addin': "('com.sun.star.sheet.AddIn',)",
|
|
}
|
|
|
|
|
|
FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
|
|
DATE = '%d/%m/%Y %H:%M:%S'
|
|
LEVEL_ERROR = logging.getLevelName(logging.ERROR)
|
|
LEVEL_INFO = logging.getLevelName(logging.INFO)
|
|
logging.addLevelName(logging.ERROR, f'\033[1;41m{LEVEL_ERROR}\033[1;0m')
|
|
logging.addLevelName(logging.INFO, f'\x1b[32m{LEVEL_INFO}\033[1;0m')
|
|
logging.basicConfig(level=logging.DEBUG, format=FORMAT, datefmt=DATE)
|
|
log = logging.getLogger(NAME)
|
|
|
|
|
|
def _methods():
|
|
template = """ def {0}(self, {1}):
|
|
print({1})
|
|
return 'ok'\n"""
|
|
functions = ''
|
|
for k, v in FUNCTIONS.items():
|
|
args = ','.join(v['parameters'].keys())
|
|
functions += template.format(k, args)
|
|
return functions
|
|
|
|
|
|
SRV = SERVICES['job']
|
|
XSRV = 'XJobExecutor'
|
|
SRV_IMPORT = f'from com.sun.star.task import {XSRV}'
|
|
METHODS = """ def trigger(self, args='pyUNO'):
|
|
print('Hello World', args)
|
|
return\n"""
|
|
|
|
if TYPE_EXTENSION > 1:
|
|
MENUS = ()
|
|
XSRV = f'X{NAME}'
|
|
SRV_IMPORT = f'from {ID} import {XSRV}'
|
|
if TYPE_EXTENSION == 2:
|
|
SRV = f"('{ID}',)"
|
|
METHODS = """ def test(self, args='pyUNO'):
|
|
print('Hello World', args)
|
|
return\n"""
|
|
elif TYPE_EXTENSION == 3:
|
|
SRV = SERVICES['addin']
|
|
METHODS = _methods()
|
|
|
|
|
|
DATA_PY = f"""import uno
|
|
import unohelper
|
|
{SRV_IMPORT}
|
|
|
|
|
|
ID_EXTENSION = '{ID}'
|
|
SERVICE = {SRV}
|
|
|
|
|
|
class {NAME}(unohelper.Base, {XSRV}):
|
|
|
|
def __init__(self, ctx):
|
|
self.ctx = ctx
|
|
|
|
{METHODS}
|
|
|
|
g_ImplementationHelper = unohelper.ImplementationHelper()
|
|
g_ImplementationHelper.addImplementation({NAME}, ID_EXTENSION, SERVICE)
|
|
"""
|
|
|
|
def _functions():
|
|
a = '[in] any {}'
|
|
t = ' any {}({});'
|
|
f = ''
|
|
for k, v in FUNCTIONS.items():
|
|
args = ','.join([a.format(k) for k, v in v['parameters'].items()])
|
|
f += t.format(k, args)
|
|
return f
|
|
|
|
|
|
FILE_IDL = ''
|
|
if TYPE_EXTENSION > 1:
|
|
id_ext = ID.replace('.', '_')
|
|
interface = f'X{NAME}'
|
|
module = ''
|
|
for i, P in enumerate(ID.split('.')):
|
|
module += f'module {P} {{ '
|
|
close_module = '}; ' * (i + 1)
|
|
functions = ' void test([in] any argument);'
|
|
if TYPE_EXTENSION == 3:
|
|
functions = _functions()
|
|
|
|
FILE_IDL = f"""#ifndef __{id_ext}_idl__
|
|
#define __{id_ext}_idl__
|
|
|
|
#include <com/sun/star/uno/XInterface.idl>
|
|
|
|
{module}
|
|
|
|
interface {interface} : com::sun::star::uno::XInterface
|
|
{{
|
|
{functions}
|
|
}};
|
|
|
|
service {P} {{
|
|
interface {interface};
|
|
}};
|
|
|
|
{close_module}
|
|
#endif
|
|
"""
|
|
|
|
|
|
def _parameters(args):
|
|
NODE = """ <node oor:name="{name}" oor:op="replace">
|
|
<prop oor:name="DisplayName">
|
|
{displayname}
|
|
</prop>
|
|
<prop oor:name="Description">
|
|
{description}
|
|
</prop>
|
|
</node>"""
|
|
line = '{}<value xml:lang="{}">{}</value>'
|
|
node = ''
|
|
for k, v in args.items():
|
|
displayname = '\n'.join(
|
|
[line.format(' ' * 16, k, v) for k, v in v['displayname'].items()])
|
|
description = '\n'.join(
|
|
[line.format(' ' * 16, k, v) for k, v in v['description'].items()])
|
|
values = {
|
|
'name': k,
|
|
'displayname': displayname,
|
|
'description': description,
|
|
}
|
|
node += NODE.format(**values)
|
|
return node
|
|
|
|
|
|
NODE_FUNCTIONS = ''
|
|
if TYPE_EXTENSION == 3:
|
|
tmp = '{}<value xml:lang="{}">{}</value>'
|
|
NODE_FUNCTION = """ <node oor:name="{name}" oor:op="replace">
|
|
<prop oor:name="DisplayName">
|
|
{displayname}
|
|
</prop>
|
|
<prop oor:name="Description">
|
|
{description}
|
|
</prop>
|
|
<prop oor:name="Category">
|
|
<value>Add-In</value>
|
|
</prop>
|
|
<prop oor:name="CompatibilityName">
|
|
<value xml:lang="en">AutoAddIn.{name}</value>
|
|
</prop>
|
|
<node oor:name="Parameters">
|
|
{parameters}
|
|
</node>
|
|
</node>"""
|
|
|
|
for k, v in FUNCTIONS.items():
|
|
displayname = '\n'.join(
|
|
[tmp.format(' ' * 12, k, v) for k, v in v['displayname'].items()])
|
|
description = '\n'.join(
|
|
[tmp.format(' ' * 12, k, v) for k, v in v['description'].items()])
|
|
parameters = _parameters(v['parameters'])
|
|
values = {
|
|
'name': k,
|
|
'displayname': displayname,
|
|
'description': description,
|
|
'parameters': parameters,
|
|
}
|
|
NODE_FUNCTIONS += NODE_FUNCTION.format(**values)
|
|
|
|
|
|
FILE_ADDIN = f"""<?xml version="1.0" encoding="UTF-8"?>
|
|
<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:name="CalcAddIns" oor:package="org.openoffice.Office">
|
|
<node oor:name="AddInInfo">
|
|
<node oor:name="{ID}" oor:op="replace">
|
|
<node oor:name="AddInFunctions">
|
|
{NODE_FUNCTIONS}
|
|
</node>
|
|
</node>
|
|
</node>
|
|
</oor:component-data>"""
|
|
|
|
|
|
DATA_MANIFEST = [FILES['py'], f"Office/{FILES['shortcut']}", 'Addons.xcu']
|
|
if TYPE_EXTENSION > 1:
|
|
DATA_MANIFEST.append(FILES['rdb'])
|
|
if TYPE_EXTENSION == 3:
|
|
DATA_MANIFEST.append('CalcAddIn.xcu')
|
|
|
|
DATA_DESCRIPTION = {
|
|
'identifier': {'value': ID},
|
|
'version': {'value': VERSION},
|
|
'display-name': {k: v['display_name'] for k, v in INFO.items()},
|
|
'icon': ICON_EXT,
|
|
'publisher': PUBLISHER,
|
|
'update': URL_XML_UPDATE,
|
|
}
|
|
|
|
DATA_ADDONS = {
|
|
'parent': PARENT,
|
|
'images': DIRS['images'],
|
|
'main': MENU_MAIN,
|
|
'menus': MENUS,
|
|
}
|
|
|
|
DATA = {
|
|
'py': DATA_PY,
|
|
'manifest': DATA_MANIFEST,
|
|
'description': DATA_DESCRIPTION,
|
|
'addons': DATA_ADDONS,
|
|
'update': URL_OXT,
|
|
'idl': FILE_IDL,
|
|
'addin': FILE_ADDIN,
|
|
}
|
|
|
|
|
|
with open('VERSION', 'w') as f:
|
|
f.write(VERSION)
|
|
|
|
|
|
# ~ LICENSE_ACCEPT_BY = 'user' # or admin
|
|
# ~ LICENSE_SUPPRESS_ON_UPDATE = True
|