From e9e83da78bb5e9491b8613f56fadd70b09611bb9 Mon Sep 17 00:00:00 2001 From: Joeri Exelmans Date: Mon, 20 Mar 2023 16:22:33 +0100 Subject: [PATCH] Update OML generator to use DTDesign namespaces + simplify OML template --- src/xopp2oml/template.oml | 97 +++++++++++++++++---------------------- src/xopp2oml/writer.py | 41 +++++++++++++++-- 2 files changed, 80 insertions(+), 58 deletions(-) diff --git a/src/xopp2oml/template.oml b/src/xopp2oml/template.oml index 5c6f511..488ad88 100644 --- a/src/xopp2oml/template.oml +++ b/src/xopp2oml/template.oml @@ -1,69 +1,58 @@ -{%- macro attributes(pageindex, page, layerindex, layer, elementindex, element) -%} -{%- for key,value in element.attributes.items() %} - ci p{{pageindex}}l{{layerindex}}e{{elementindex}}a{{loop.index}} : xopp:XMLAttribute [ - dict:hasKey "{{key}}" - dict:hasValue "{{value}}" - xopp:ofLayerElement p{{pageindex}}l{{layerindex}}e{{elementindex}} - object_diagram:inModel model - ] -{% endfor %} -{%- endmacro -%} - -{%- macro elements(pageindex, page, layerindex, layer) -%} -{% for el in layer.elements %} - ci p{{pageindex}}l{{layerindex}}e{{loop.index}} : xopp:{{el.__class__.__name__}} [ - xopp:hasText "{{el.text}}" - xopp:inLayer p{{pageindex}}l{{layerindex}} - object_diagram:inModel model - ] - {{ attributes(pageindex, page, layerindex, layer, loop.index, el) -}} -{% endfor %} -{%- endmacro -%} - -{%- macro layers(pageindex, page) -%} -{% for layer in page.layers %} - ci p{{pageindex}}l{{loop.index}} : xopp:Layer [ - xopp:inPage p{{pageindex}} - object_diagram:inModel model - ] - {{ elements(pageindex, page, loop.index, layer) -}} -{% endfor %} -{%- endmacro -%} - -{%- macro pages(file) -%} -{% for page in file.pages -%} - ci p{{loop.index}} : xopp:Page [ - xopp:hasWidth {{ page.width }} - xopp:hasHeight {{ page.height }} - xopp:hasBackgroundType "{{ page.background_type }}" - xopp:hasBackgroundColor "{{ page.background_color }}" - xopp:hasBackgroundStyle "{{ page.background_style }}" - xopp:inFile file - object_diagram:inModel model - ] - {{ layers(loop.index, page) -}} -{%- endfor %} -{%- endmacro -%} // Warning: Generated code! Do not edit! // Input file: '{{inputfile}}' // Generator: https://msdl.uantwerpen.be/git/jexelmans/xopp2py -description as {{namespace}} { - uses as xopp - uses as object_diagram - uses as dict +description <{{namespaces.description}}#> as {{namespaces.shorthand}} { + + uses <{{namespaces.xopp}}#> as xopp + uses <{{namespaces.object_diagram}}#> as object_diagram + uses <{{namespaces.dict}}#> as dict ci model : xopp:Model [] ci file : xopp:File [ - xopp:hasCreator "{{ file.creator }}" + xopp:hasCreator {{ file.creator | to_oml_string_literal }} xopp:hasFileVersion {{ file.fileversion }} - xopp:hasTitle "{{ file.title }}" + xopp:hasTitle {{ file.title | to_oml_string_literal }} {%- if file.preview != None %} - xopp:hasPreview "{{ toBase64(file.preview).decode('utf-8') }}" + xopp:hasPreview {{ file.preview | to_base64_string }} {%- endif %} object_diagram:inModel model ] - {{ pages(file) }} + {% for page_index, page in enumerate(file.pages) %} + ci p{{page_index}} : xopp:Page [ + xopp:hasWidth {{ page.width }} + xopp:hasHeight {{ page.height }} + xopp:hasBackgroundType {{ page.background_type | to_oml_string_literal }} + xopp:hasBackgroundColor {{ page.background_color | to_oml_string_literal }} + xopp:hasBackgroundStyle {{ page.background_style | to_oml_string_literal }} + xopp:inFile file + object_diagram:inModel model + ] + + {%- for layer_index, layer in enumerate(page.layers) %} + ci p{{page_index}}l{{layer_index}} : xopp:Layer [ + xopp:inPage p{{page_index}} + object_diagram:inModel model + ] + + {%- for el_index, el in enumerate(layer.elements) %} + ci p{{page_index}}l{{layer_index}}e{{el_index}} : xopp:{{el.__class__.__name__}} [ + xopp:hasText {{el.text | to_oml_string_literal}} + xopp:inLayer p{{page_index}}l{{layer_index}} + object_diagram:inModel model + ] + + {%- for key, value in el.attributes.items() %} + ci p{{page_index}}l{{layer_index}}e{{el_index}}a{{loop.index}} : xopp:XMLAttribute [ + dict:hasKey {{key | to_oml_string_literal}} + dict:hasValue {{value | to_oml_string_literal}} + xopp:ofLayerElement p{{page_index}}l{{layer_index}}e{{el_index}} + object_diagram:inModel model + ] + {% endfor %} + {% endfor %} + {% endfor %} + {% endfor %} } diff --git a/src/xopp2oml/writer.py b/src/xopp2oml/writer.py index ad13c8f..7608c71 100644 --- a/src/xopp2oml/writer.py +++ b/src/xopp2oml/writer.py @@ -1,18 +1,51 @@ from xopp2py import abstract_syntax import io +import base64 + +CDF_NAMESPACES = { + # namespace of generated description + "description": "http://flandersmake.be/cdf/description/my_xopp", + "shorthand": "my_xopp", + + # vocabulary namespaces + "xopp": "http://flandersmake.be/cdf/vocabulary/xopp", + "object_diagram": "http://flandersmake.be/cdf/vocabulary/object_diagram", + "dict": "http://flandersmake.be/cdf/vocabulary/dict", +} + +DTDESIGN_NAMESPACES = { + # namespace of generated description + "description": "http://ua.be/sdo2l/description/artifacts/my_xopp", + "shorthand": "my_xopp", + + # vocabulary namespaces + "xopp": "http://ua.be/sdo2l/vocabulary/formalisms/xopp", + "object_diagram": "http://ua.be/sdo2l/vocabulary/formalisms/object_diagram", + "dict": "http://ua.be/sdo2l/vocabulary/formalisms/dict", +} + +def to_oml_string_literal(python_string): + # Not sure which characters to escape in OML. + # At the very least, quotes should be escaped: + return '"' + python_string.replace('"', '\\"') + '"' + +def to_base64_string(bytes): + return '"' + base64.b64encode(bytes).decode('utf-8') + '"' def writeOML(xournalFile: abstract_syntax.XournalFile, inputfile:str, namespace:str, ostream: io.TextIOBase): import jinja2 import os - import base64 environment = jinja2.Environment( loader=jinja2.FileSystemLoader(os.path.dirname(__file__))) + environment.filters['to_oml_string_literal'] = to_oml_string_literal + environment.filters['to_base64_string'] = to_base64_string + template = environment.get_template("template.oml") for piece in template.generate( file=xournalFile, - toBase64=base64.b64encode, inputfile=inputfile, - namespace=namespace): - ostream.write(piece) + enumerate=enumerate, + namespaces=DTDESIGN_NAMESPACES): + ostream.write(piece)