Browse Source

Update OML generator to use DTDesign namespaces + simplify OML template

Joeri Exelmans 2 years ago
parent
commit
e9e83da78b
2 changed files with 80 additions and 58 deletions
  1. 43 54
      src/xopp2oml/template.oml
  2. 37 4
      src/xopp2oml/writer.py

+ 43 - 54
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 <http://flandersmake.be/cdf/description/{{namespace}}#> as {{namespace}} {
 
-  uses <http://flandersmake.be/cdf/vocabulary/xopp#> as xopp
-  uses <http://flandersmake.be/cdf/vocabulary/object_diagram#> as object_diagram
-  uses <http://flandersmake.be/cdf/vocabulary/dict#> 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 %}
 }

+ 37 - 4
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)