Joeri Exelmans преди 2 години
родител
ревизия
b777df7874
променени са 15 файла, в които са добавени 127 реда и са изтрити 107 реда
  1. 1 2
      .gitignore
  2. 31 3
      README.md
  3. 12 0
      default.nix
  4. 0 21
      pyproject.toml
  5. 16 0
      setup.py
  6. 0 15
      shell.nix
  7. 0 0
      src/xopp2oml/__init__.py
  8. 22 0
      src/xopp2oml/convert.py
  9. 23 23
      src/xopp2py_oml/oml_writer.template
  10. 1 1
      src/xopp2py_oml/oml_writer.py
  11. 0 25
      src/xopp2py/main.py
  12. 21 0
      test/run_tests.py
  13. 0 0
      test/test_data/SmallXournalFile.xopp
  14. 0 0
      test/test_data/TwoHiddenLayers.xopp
  15. 0 17
      tests/test_xopp2py.py

+ 1 - 2
.gitignore

@@ -1,2 +1 @@
-__pycache__/
-dist/
+__pycache__/

+ 31 - 3
README.md

@@ -1,5 +1,33 @@
-# xopp2py
+# Python interface to Xournal++ (.xopp) file format
 
-Python interface to .xopp (Xournal++) files.
+## Packages
 
-The only dependency is Python 3. (developed with Python 3.10)
+This project contains the following packages, under `src`:
+ - xopp2py
+ - xopp2oml
+
+### xopp2py
+
+Python interface to .xopp (Xournal++) 
+
+Dependencies: Python3
+
+### xopp2oml
+
+XOPP to OML converter
+
+Dependencies: Python3, Jinja2, xopp2py
+
+#### Entry point: xopp2oml.convert
+
+Python script that takes as input as .xopp file and produces as output an .oml file.
+
+
+## Running the tests
+
+The tests are not included in the packages themselves, but as a separate script.
+
+To run the tests, make sure the packages are installed, and run:
+```
+python test/run_tests.py
+```

+ 12 - 0
default.nix

@@ -0,0 +1,12 @@
+{ pkgs ? import <nixpkgs> {} }:
+
+pkgs.python3Packages.buildPythonPackage rec {
+  pname = "xopp2py";
+  version = "1.0.0";
+
+  src = ./.;
+
+  propagatedBuildInputs = [
+    pkgs.python3Packages.jinja2
+  ];
+}

+ 0 - 21
pyproject.toml

@@ -1,21 +0,0 @@
-[project]
-name = "xopp2py"
-description = "A Python interface to the Xournal++ file format"
-version = "1.0.0"
-authors = [
-  { name="Joeri Exelmans", email="joeri.exelmans@uantwerpen.be" },
-]
-readme = "README.md"
-requires-python = ">=3.10"
-classifiers = [
-    "Programming Language :: Python :: 3",
-    "Operating System :: OS Independent",
-]
-
-[build-system]
-requires = ["hatchling"]
-build-backend = "hatchling.build"
-
-[project.urls]
-"Homepage" = "https://msdl.uantwerpen.be/git/jexelmans/xopp2py"
-"Bug Tracker" = "https://msdl.uantwerpen.be/git/jexelmans/xopp2py/issues"

+ 16 - 0
setup.py

@@ -0,0 +1,16 @@
+from setuptools import setup, find_packages
+
+setup(
+    name='xopp2oml',
+    version='1.0.0',
+
+    install_requires=[
+        'jinja2',
+    ],
+
+    package_dir={"":"src"},
+    packages=['xopp2py', 'xopp2oml'],
+
+    include_package_data=True,
+    package_data={"xopp2oml": ["template.oml"]},
+)

+ 0 - 15
shell.nix

@@ -1,15 +0,0 @@
-# Generates a shell from where all the dependencies can be found.
-
-{ pkgs ? import <nixpkgs> {} }:
-
-let
-  SOURCE_DIR = builtins.toString ./src;
-in
-  pkgs.mkShell {
-    buildInputs = [
-      pkgs.python3
-      pkgs.python3Packages.jinja2
-    ];
-
-     PYTHONPATH = SOURCE_DIR;
-  }

src/xopp2py_oml/__init__.py → src/xopp2oml/__init__.py


+ 22 - 0
src/xopp2oml/convert.py

@@ -0,0 +1,22 @@
+# Command-line tool that demonstrates how to use this library.
+
+if __name__ == "__main__":
+    import argparse
+    argparser = argparse.ArgumentParser(
+        description = "Python interface for Xournal++ (.xopp) files.")
+    argparser.add_argument('inputfile')
+    argparser.add_argument('-o', '--output', metavar='FILE', nargs=1, help="OML output file. If not specified, output will be printed to stdout.")
+    args = argparser.parse_args() # exits on error
+
+    # Parse .xopp
+    from xopp2py import parser
+    asyntax = parser.parseFile(args.inputfile)
+
+    # Generate OML
+    from xopp2oml import writer
+    if args.output == None:
+        import sys
+        writer.writeOML(asyntax, args.inputfile, "my_xopp", sys.stdout)
+    else:
+        with open(args.output[0], 'wt') as f:
+            writer.writeOML(asyntax, args.inputfile, "my_xopp", f)

+ 23 - 23
src/xopp2py_oml/oml_writer.template

@@ -1,9 +1,9 @@
 {%- 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}} : xournalpp:XMLAttribute [
-    xournalpp:hasKey "{{key}}"
-    xournalpp:hasValue "{{value}}"
-    xournalpp:ofLayerElement p{{pageindex}}l{{layerindex}}e{{elementindex}}
+  ci p{{pageindex}}l{{layerindex}}e{{elementindex}}a{{loop.index}} : xopp:XMLAttribute [
+    xopp:hasKey "{{key}}"
+    xopp:hasValue "{{value}}"
+    xopp:ofLayerElement p{{pageindex}}l{{layerindex}}e{{elementindex}}
     object_diagram:inModel model
   ]
 {% endfor %}
@@ -11,9 +11,9 @@
 
 {%- macro elements(pageindex, page, layerindex, layer) -%}
 {% for el in layer.elements %}
-  ci p{{pageindex}}l{{layerindex}}e{{loop.index}} : xournalpp:{{el.__class__.__name__}} [
-    xournalpp:hasText "{{el.text}}"
-    xournalpp:inLayer p{{pageindex}}l{{layerindex}}
+  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) -}}
@@ -22,8 +22,8 @@
 
 {%- macro layers(pageindex, page) -%}
 {% for layer in page.layers %}
-  ci p{{pageindex}}l{{loop.index}} : xournalpp:Layer [
-    xournalpp:inPage p{{pageindex}}
+  ci p{{pageindex}}l{{loop.index}} : xopp:Layer [
+    xopp:inPage p{{pageindex}}
     object_diagram:inModel model
   ]
   {{ elements(pageindex, page, loop.index, layer) -}}
@@ -32,13 +32,13 @@
 
 {%- macro pages(file) -%}
 {% for page in file.pages -%}
-  ci p{{loop.index}} : xournalpp:Page [
-    xournalpp:hasWidth {{ page.width }}
-    xournalpp:hasHeight {{ page.height }}
-    xournalpp:hasBackgroundType "{{ page.background_type }}"
-    xournalpp:hasBackgroundColor "{{ page.background_color }}"
-    xournalpp:hasBackgroundStyle "{{ page.background_style }}"
-    xournalpp:inFile file
+  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) -}}
@@ -49,17 +49,17 @@
 // Generator: https://msdl.uantwerpen.be/git/jexelmans/xopp2py
 description <http://flandersmake.be/cdf/description/{{namespace}}#> as {{namespace}} {
 
-  uses <http://flandersmake.be/cdf/vocabulary/xournalpp#> as xournalpp
+  uses <http://flandersmake.be/cdf/vocabulary/xopp#> as xopp
   uses <http://flandersmake.be/cdf/vocabulary/object_diagram#> as object_diagram
 
-  ci model : xournalpp:Model []
+  ci model : xopp:Model []
 
-  ci file : xournalpp:File [
-    xournalpp:hasCreator "{{ file.creator }}"
-    xournalpp:hasFileVersion {{ file.fileversion }}
-    xournalpp:hasTitle "{{ file.title }}"
+  ci file : xopp:File [
+    xopp:hasCreator "{{ file.creator }}"
+    xopp:hasFileVersion {{ file.fileversion }}
+    xopp:hasTitle "{{ file.title }}"
     {%- if file.preview != None %}
-    xournalpp:hasPreview "{{ toBase64(file.preview).decode('utf-8') }}"
+    xopp:hasPreview "{{ toBase64(file.preview).decode('utf-8') }}"
     {%- endif %}
     object_diagram:inModel model
   ]

+ 1 - 1
src/xopp2py_oml/oml_writer.py

@@ -9,7 +9,7 @@ def writeOML(xournalFile: abstract_syntax.XournalFile, inputfile:str, namespace:
     environment = jinja2.Environment(
         loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
 
-    template = environment.get_template("oml_writer.template")
+    template = environment.get_template("template.oml")
     for piece in template.generate(
         file=xournalFile,
         toBase64=base64.b64encode,

+ 0 - 25
src/xopp2py/main.py

@@ -1,25 +0,0 @@
-# Command-line tool that demonstrates how to use this library.
-
-import argparse
-
-if __name__ == "__main__":
-    argparser = argparse.ArgumentParser(
-        description = "Python interface for Xournal++ (.xopp) files.")
-    argparser.add_argument('filename')
-    argparser.add_argument('--print-oml', action='store_true', help="Convert to OML and print")
-    argparser.add_argument('--write-oml', metavar='FILE', nargs=1, help="Convert to OML and write to file")
-    args = argparser.parse_args() # exits on error
-
-    print(args)
-
-    from xopp2py import parser
-
-    asyntax = parser.parseFile(args.filename)
-    if args.print_oml:
-        from xopp2py_oml import oml_writer
-        import sys
-        oml_writer.writeOML(asyntax, args.filename, "my_xopp", sys.stdout)
-    elif args.write_oml != None:
-        from xopp2py_oml import oml_writer
-        with open(args.write_oml[0], 'wt') as f:
-            oml_writer.writeOML(asyntax, args.filename, "my_xopp", f)

+ 21 - 0
test/run_tests.py

@@ -0,0 +1,21 @@
+from xopp2py import parser, abstract_syntax
+from xopp2oml import writer
+import os
+
+if __name__ == "__main__":
+    DATADIR = os.path.join(os.path.dirname(__file__), "test_data")
+
+    class DummyOutput:
+        def write(self, text: str):
+            pass
+
+    def parse(filename):
+        asyntax = parser.parseFile(os.path.join(DATADIR, filename))
+        writer.writeOML(asyntax, filename, "my_xopp", DummyOutput())
+
+    # Just see if these files parse without throwing an exception :)
+    parse("SmallXournalFile.xopp")
+    parse("TwoHiddenLayers.xopp")
+
+
+    print("Tests passed.")

tests/data/SmallXournalFile.xopp → test/test_data/SmallXournalFile.xopp


tests/data/TwoHiddenLayers.xopp → test/test_data/TwoHiddenLayers.xopp


+ 0 - 17
tests/test_xopp2py.py

@@ -1,17 +0,0 @@
-from xopp2py import parser, abstract_syntax
-from xopp2py_oml import oml_writer
-import os
-
-DATADIR = os.path.join(os.path.dirname(__file__), "data")
-
-class DummyOutput:
-    def write(self, text: str):
-        pass
-
-def parse(filename):
-    asyntax = parser.parseFile(os.path.join(DATADIR, filename))
-    oml_writer.writeOML(asyntax, filename, "my_xopp", DummyOutput())
-
-# Just see if these files parse without throwing an exception :)
-parse("SmallXournalFile.xopp")
-parse("TwoHiddenLayers.xopp")