aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.clang-format34
-rw-r--r--.clang-tidy6
-rw-r--r--.gitignore2
-rw-r--r--.gitlab-ci.yml229
-rw-r--r--.gitmodules3
-rw-r--r--.stylelintrc.json8
-rw-r--r--INSTALL.md72
-rw-r--r--README.md93
-rw-r--r--doc/c/doxy-style.css (renamed from doc/doxy-style.css)235
-rw-r--r--doc/c/footer.html (renamed from doc/footer.html)0
-rw-r--r--doc/c/header.html (renamed from doc/header.html)0
-rw-r--r--doc/c/layout.xml (renamed from doc/layout.xml)58
-rw-r--r--doc/c/mainpage.md (renamed from doc/mainpage.md)0
-rw-r--r--doc/c/meson.build41
-rw-r--r--doc/c/reference.doxygen.in (renamed from doc/reference.doxygen.in)386
-rw-r--r--doc/index.html.in6
-rw-r--r--doc/ns/ext/meson.build67
-rw-r--r--doc/ns/extensions/meson.build48
-rw-r--r--doc/ns/meson.build80
-rw-r--r--doc/pygments.css61
-rw-r--r--doc/style/asciidoc.css (renamed from doc/asciidoc.css)0
-rw-r--r--doc/style/meson.build16
-rw-r--r--doc/style/pygments.css558
-rw-r--r--doc/style/style.css (renamed from doc/style.css)176
-rw-r--r--include/lv2/atom/atom.h (renamed from lv2/atom/atom.h)2
-rw-r--r--include/lv2/atom/forge.h (renamed from lv2/atom/forge.h)14
-rw-r--r--include/lv2/atom/util.h (renamed from lv2/atom/util.h)12
-rw-r--r--include/lv2/buf-size/buf-size.h (renamed from lv2/buf-size/buf-size.h)0
-rw-r--r--include/lv2/core/attributes.h (renamed from lv2/core/attributes.h)4
-rw-r--r--include/lv2/core/lv2.h (renamed from lv2/core/lv2.h)0
-rw-r--r--include/lv2/core/lv2_util.h (renamed from lv2/core/lv2_util.h)0
-rw-r--r--include/lv2/data-access/data-access.h (renamed from lv2/data-access/data-access.h)0
-rw-r--r--include/lv2/dynmanifest/dynmanifest.h (renamed from lv2/dynmanifest/dynmanifest.h)0
-rw-r--r--include/lv2/event/event-helpers.h (renamed from lv2/event/event-helpers.h)2
-rw-r--r--include/lv2/event/event.h (renamed from lv2/event/event.h)16
-rw-r--r--include/lv2/instance-access/instance-access.h (renamed from lv2/instance-access/instance-access.h)0
-rw-r--r--include/lv2/log/log.h (renamed from lv2/log/log.h)0
-rw-r--r--include/lv2/log/logger.h (renamed from lv2/log/logger.h)0
-rw-r--r--include/lv2/midi/midi.h (renamed from lv2/midi/midi.h)4
-rw-r--r--include/lv2/morph/morph.h (renamed from lv2/morph/morph.h)0
-rw-r--r--include/lv2/options/options.h (renamed from lv2/options/options.h)10
-rw-r--r--include/lv2/parameters/parameters.h (renamed from lv2/parameters/parameters.h)0
-rw-r--r--include/lv2/patch/patch.h (renamed from lv2/patch/patch.h)0
-rw-r--r--include/lv2/port-groups/port-groups.h (renamed from lv2/port-groups/port-groups.h)0
-rw-r--r--include/lv2/port-props/port-props.h (renamed from lv2/port-props/port-props.h)0
-rw-r--r--include/lv2/presets/presets.h (renamed from lv2/presets/presets.h)0
-rw-r--r--include/lv2/resize-port/resize-port.h (renamed from lv2/resize-port/resize-port.h)0
-rw-r--r--include/lv2/state/state.h (renamed from lv2/state/state.h)6
-rw-r--r--include/lv2/time/time.h (renamed from lv2/time/time.h)0
-rw-r--r--include/lv2/ui/ui.h (renamed from lv2/ui/ui.h)0
-rw-r--r--include/lv2/units/units.h (renamed from lv2/units/units.h)0
-rw-r--r--include/lv2/uri-map/uri-map.h (renamed from lv2/uri-map/uri-map.h)0
-rw-r--r--include/lv2/urid/urid.h (renamed from lv2/urid/urid.h)0
-rw-r--r--include/lv2/worker/worker.h (renamed from lv2/worker/worker.h)0
-rw-r--r--lv2.pc.in7
-rw-r--r--lv2/atom.lv2/atom.meta.ttl (renamed from lv2/atom/atom.meta.ttl)10
-rw-r--r--lv2/atom.lv2/atom.ttl (renamed from lv2/atom/atom.ttl)5
-rw-r--r--lv2/atom.lv2/manifest.ttl (renamed from lv2/atom/manifest.ttl)2
-rw-r--r--lv2/buf-size.lv2/buf-size.meta.ttl (renamed from lv2/buf-size/buf-size.meta.ttl)0
-rw-r--r--lv2/buf-size.lv2/buf-size.ttl (renamed from lv2/buf-size/buf-size.ttl)3
-rw-r--r--lv2/buf-size.lv2/manifest.ttl (renamed from lv2/buf-size/manifest.ttl)0
-rw-r--r--lv2/core.lv2/lv2core.meta.ttl (renamed from lv2/core/lv2core.meta.ttl)19
-rw-r--r--lv2/core.lv2/lv2core.ttl (renamed from lv2/core/lv2core.ttl)10
-rw-r--r--lv2/core.lv2/manifest.ttl (renamed from lv2/core/manifest.ttl)2
-rw-r--r--lv2/core.lv2/meta.ttl (renamed from lv2/core/meta.ttl)56
-rw-r--r--lv2/core.lv2/people.ttl (renamed from lv2/core/people.ttl)0
-rw-r--r--lv2/data-access.lv2/data-access.meta.ttl (renamed from lv2/data-access/data-access.meta.ttl)1
-rw-r--r--lv2/data-access.lv2/data-access.ttl (renamed from lv2/data-access/data-access.ttl)3
-rw-r--r--lv2/data-access.lv2/manifest.ttl (renamed from lv2/data-access/manifest.ttl)0
-rw-r--r--lv2/dynmanifest.lv2/dynmanifest.meta.ttl (renamed from lv2/dynmanifest/dynmanifest.meta.ttl)0
-rw-r--r--lv2/dynmanifest.lv2/dynmanifest.ttl (renamed from lv2/dynmanifest/dynmanifest.ttl)3
-rw-r--r--lv2/dynmanifest.lv2/manifest.ttl (renamed from lv2/dynmanifest/manifest.ttl)0
-rw-r--r--lv2/event.lv2/event.meta.ttl (renamed from lv2/event/event.meta.ttl)10
-rw-r--r--lv2/event.lv2/event.ttl (renamed from lv2/event/event.ttl)4
-rw-r--r--lv2/event.lv2/manifest.ttl (renamed from lv2/event/manifest.ttl)2
-rw-r--r--lv2/instance-access.lv2/instance-access.meta.ttl (renamed from lv2/instance-access/instance-access.meta.ttl)0
-rw-r--r--lv2/instance-access.lv2/instance-access.ttl (renamed from lv2/instance-access/instance-access.ttl)3
-rw-r--r--lv2/instance-access.lv2/manifest.ttl (renamed from lv2/instance-access/manifest.ttl)0
-rw-r--r--lv2/log.lv2/log.meta.ttl (renamed from lv2/log/log.meta.ttl)0
-rw-r--r--lv2/log.lv2/log.ttl (renamed from lv2/log/log.ttl)3
-rw-r--r--lv2/log.lv2/manifest.ttl (renamed from lv2/log/manifest.ttl)0
-rw-r--r--lv2/midi.lv2/manifest.ttl (renamed from lv2/midi/manifest.ttl)0
-rw-r--r--lv2/midi.lv2/midi.meta.ttl (renamed from lv2/midi/midi.meta.ttl)0
-rw-r--r--lv2/midi.lv2/midi.ttl (renamed from lv2/midi/midi.ttl)3
-rw-r--r--lv2/morph.lv2/manifest.ttl (renamed from lv2/morph/manifest.ttl)0
-rw-r--r--lv2/morph.lv2/morph.meta.ttl (renamed from lv2/morph/morph.meta.ttl)0
-rw-r--r--lv2/morph.lv2/morph.ttl (renamed from lv2/morph/morph.ttl)3
-rw-r--r--lv2/options.lv2/manifest.ttl (renamed from lv2/options/manifest.ttl)0
-rw-r--r--lv2/options.lv2/options.meta.ttl (renamed from lv2/options/options.meta.ttl)0
-rw-r--r--lv2/options.lv2/options.ttl (renamed from lv2/options/options.ttl)3
-rw-r--r--lv2/parameters.lv2/manifest.ttl (renamed from lv2/parameters/manifest.ttl)0
-rw-r--r--lv2/parameters.lv2/parameters.meta.ttl (renamed from lv2/parameters/parameters.meta.ttl)0
-rw-r--r--lv2/parameters.lv2/parameters.ttl (renamed from lv2/parameters/parameters.ttl)0
-rw-r--r--lv2/patch.lv2/manifest.ttl (renamed from lv2/patch/manifest.ttl)2
-rw-r--r--lv2/patch.lv2/patch.meta.ttl (renamed from lv2/patch/patch.meta.ttl)14
-rw-r--r--lv2/patch.lv2/patch.ttl (renamed from lv2/patch/patch.ttl)3
-rw-r--r--lv2/port-groups.lv2/manifest.ttl (renamed from lv2/port-groups/manifest.ttl)0
-rw-r--r--lv2/port-groups.lv2/port-groups.meta.ttl (renamed from lv2/port-groups/port-groups.meta.ttl)0
-rw-r--r--lv2/port-groups.lv2/port-groups.ttl (renamed from lv2/port-groups/port-groups.ttl)2
-rw-r--r--lv2/port-props.lv2/manifest.ttl (renamed from lv2/port-props/manifest.ttl)0
-rw-r--r--lv2/port-props.lv2/port-props.meta.ttl (renamed from lv2/port-props/port-props.meta.ttl)0
-rw-r--r--lv2/port-props.lv2/port-props.ttl (renamed from lv2/port-props/port-props.ttl)0
-rw-r--r--lv2/presets.lv2/manifest.ttl (renamed from lv2/presets/manifest.ttl)0
-rw-r--r--lv2/presets.lv2/presets.meta.ttl (renamed from lv2/presets/presets.meta.ttl)0
-rw-r--r--lv2/presets.lv2/presets.ttl (renamed from lv2/presets/presets.ttl)0
-rw-r--r--lv2/resize-port.lv2/manifest.ttl (renamed from lv2/resize-port/manifest.ttl)0
-rw-r--r--lv2/resize-port.lv2/resize-port.meta.ttl (renamed from lv2/resize-port/resize-port.meta.ttl)0
-rw-r--r--lv2/resize-port.lv2/resize-port.ttl (renamed from lv2/resize-port/resize-port.ttl)3
-rw-r--r--lv2/state.lv2/manifest.ttl (renamed from lv2/state/manifest.ttl)2
-rw-r--r--lv2/state.lv2/state.meta.ttl (renamed from lv2/state/state.meta.ttl)10
-rw-r--r--lv2/state.lv2/state.ttl (renamed from lv2/state/state.ttl)3
-rw-r--r--lv2/time.lv2/manifest.ttl (renamed from lv2/time/manifest.ttl)0
-rw-r--r--lv2/time.lv2/time.meta.ttl (renamed from lv2/time/time.meta.ttl)0
-rw-r--r--lv2/time.lv2/time.ttl (renamed from lv2/time/time.ttl)3
-rw-r--r--lv2/ui.lv2/manifest.ttl (renamed from lv2/ui/manifest.ttl)2
-rw-r--r--lv2/ui.lv2/ui.meta.ttl (renamed from lv2/ui/ui.meta.ttl)12
-rw-r--r--lv2/ui.lv2/ui.ttl (renamed from lv2/ui/ui.ttl)3
-rw-r--r--lv2/units.lv2/manifest.ttl (renamed from lv2/units/manifest.ttl)0
-rw-r--r--lv2/units.lv2/units.meta.ttl (renamed from lv2/units/units.meta.ttl)0
-rw-r--r--lv2/units.lv2/units.ttl (renamed from lv2/units/units.ttl)3
-rw-r--r--lv2/uri-map.lv2/manifest.ttl (renamed from lv2/uri-map/manifest.ttl)0
-rw-r--r--lv2/uri-map.lv2/uri-map.meta.ttl (renamed from lv2/uri-map/uri-map.meta.ttl)0
-rw-r--r--lv2/uri-map.lv2/uri-map.ttl (renamed from lv2/uri-map/uri-map.ttl)3
-rw-r--r--lv2/urid.lv2/manifest.ttl (renamed from lv2/urid/manifest.ttl)0
-rw-r--r--lv2/urid.lv2/urid.meta.ttl (renamed from lv2/urid/urid.meta.ttl)0
-rw-r--r--lv2/urid.lv2/urid.ttl (renamed from lv2/urid/urid.ttl)3
-rw-r--r--lv2/worker.lv2/manifest.ttl (renamed from lv2/worker/manifest.ttl)0
-rw-r--r--lv2/worker.lv2/worker.meta.ttl (renamed from lv2/worker/worker.meta.ttl)0
-rw-r--r--lv2/worker.lv2/worker.ttl (renamed from lv2/worker/worker.ttl)3
-rw-r--r--lv2specgen/DTD/xhtml-rdfa-1.dtd42
-rwxr-xr-xlv2specgen/lv2docgen.py91
-rwxr-xr-xlv2specgen/lv2specgen.py351
-rw-r--r--lv2specgen/meson.build41
l---------lv2specgen/style.css1
-rw-r--r--lv2specgen/template.html14
-rw-r--r--meson.build373
-rw-r--r--meson/library/meson.build30
-rw-r--r--meson/suppressions/meson.build130
-rw-r--r--meson/warnings/meson.build256
-rw-r--r--meson_options.txt23
-rw-r--r--plugins/eg-amp.lv2/meson.build41
l---------plugins/eg-amp.lv2/waf1
-rw-r--r--plugins/eg-amp.lv2/wscript51
-rw-r--r--plugins/eg-fifths.lv2/meson.build41
l---------plugins/eg-fifths.lv2/waf1
-rw-r--r--plugins/eg-fifths.lv2/wscript49
-rw-r--r--plugins/eg-metro.lv2/meson.build41
-rw-r--r--plugins/eg-metro.lv2/metro.c13
l---------plugins/eg-metro.lv2/waf1
-rw-r--r--plugins/eg-metro.lv2/wscript50
-rw-r--r--plugins/eg-midigate.lv2/meson.build41
-rw-r--r--plugins/eg-midigate.lv2/midigate.c6
l---------plugins/eg-midigate.lv2/waf1
-rw-r--r--plugins/eg-midigate.lv2/wscript49
-rw-r--r--plugins/eg-params.lv2/meson.build41
-rw-r--r--plugins/eg-params.lv2/params.c11
-rw-r--r--plugins/eg-params.lv2/state_map.h2
-rw-r--r--plugins/eg-params.lv2/wscript49
-rw-r--r--plugins/eg-sampler.lv2/manifest.ttl.in2
-rw-r--r--plugins/eg-sampler.lv2/meson.build48
-rw-r--r--plugins/eg-sampler.lv2/peaks.h4
-rw-r--r--plugins/eg-sampler.lv2/sampler.c121
-rw-r--r--plugins/eg-sampler.lv2/sampler_ui.c8
l---------plugins/eg-sampler.lv2/waf1
-rw-r--r--plugins/eg-sampler.lv2/wscript64
-rw-r--r--plugins/eg-scope.lv2/examploscope.c5
-rw-r--r--plugins/eg-scope.lv2/examploscope_ui.c4
-rw-r--r--plugins/eg-scope.lv2/manifest.ttl.in2
-rw-r--r--plugins/eg-scope.lv2/meson.build41
-rw-r--r--plugins/eg-scope.lv2/wscript56
-rwxr-xr-xplugins/literasc.py158
-rw-r--r--plugins/meson.build82
-rw-r--r--plugins/wscript45
-rw-r--r--schemas.lv2/dcs.ttl277
-rw-r--r--schemas.lv2/dcterms.ttl (renamed from schemas.lv2/dct.ttl)1
-rw-r--r--schemas.lv2/doap.ttl4
-rw-r--r--schemas.lv2/foaf.ttl919
-rw-r--r--schemas.lv2/manifest.ttl5
-rw-r--r--schemas.lv2/meson.build16
-rw-r--r--schemas.lv2/owl.ttl884
-rw-r--r--schemas.lv2/rdf.ttl184
-rw-r--r--schemas.lv2/rdfs.ttl178
-rwxr-xr-xscripts/lv2_build_index.py256
-rwxr-xr-xscripts/lv2_check_specification.py248
-rwxr-xr-xscripts/lv2_check_syntax.py85
-rwxr-xr-xscripts/lv2_write_news.py258
-rw-r--r--scripts/meson.build9
-rw-r--r--test/.clang-tidy20
-rw-r--r--test/atom_test_utils.c (renamed from lv2/atom/atom-test-utils.c)0
-rw-r--r--test/meson.build137
-rw-r--r--test/test_atom.c (renamed from lv2/atom/atom-test.c)6
-rw-r--r--test/test_build.c52
-rw-r--r--test/test_build.cpp67
-rw-r--r--test/test_forge_overflow.c (renamed from lv2/atom/forge-overflow-test.c)7
-rwxr-xr-xutil/lv2_validate.in2
-rw-r--r--util/meson.build12
-rwxr-xr-xwaf27
m---------waflib0
-rw-r--r--wscript849
199 files changed, 5791 insertions, 3666 deletions
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..2ded658
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,34 @@
+---
+AlignConsecutiveAssignments: true
+AlignConsecutiveDeclarations: true
+AlignEscapedNewlinesLeft: true
+BasedOnStyle: Mozilla
+BraceWrapping:
+ AfterNamespace: false
+ AfterClass: true
+ AfterEnum: false
+ AfterExternBlock: false
+ AfterFunction: true
+ AfterStruct: false
+ SplitEmptyFunction: false
+ SplitEmptyRecord: false
+BreakBeforeBraces: Custom
+Cpp11BracedListStyle: true
+IndentCaseLabels: false
+IndentPPDirectives: AfterHash
+KeepEmptyLinesAtTheStartOfBlocks: false
+SpacesInContainerLiterals: false
+StatementMacros:
+ - LV2_DEPRECATED
+ - LV2_DISABLE_DEPRECATION_WARNINGS
+ - LV2_RESTORE_WARNINGS
+ - LV2_SYMBOL_EXPORT
+ - _Pragma
+ForEachMacros:
+ - LV2_ATOM_OBJECT_BODY_FOREACH
+ - LV2_ATOM_OBJECT_FOREACH
+ - LV2_ATOM_SEQUENCE_BODY_FOREACH
+ - LV2_ATOM_SEQUENCE_FOREACH
+ - LV2_ATOM_TUPLE_BODY_FOREACH
+ - LV2_ATOM_TUPLE_FOREACH
+...
diff --git a/.clang-tidy b/.clang-tidy
index 66a8005..342cf5a 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -3,9 +3,12 @@ Checks: >
-*-else-after-return,
-*-magic-numbers,
-*-uppercase-literal-suffix,
+ -altera-*,
+ -bugprone-easily-swappable-parameters,
-bugprone-macro-parentheses,
-bugprone-suspicious-include,
-bugprone-suspicious-string-compare,
+ -cert-err33-c,
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
-clang-diagnostic-empty-translation-unit,
-clang-diagnostic-unused-function,
@@ -16,6 +19,9 @@ Checks: >
-misc-unused-parameters,
-modernize-redundant-void-arg,
-modernize-use-trailing-return-type,
+ -performance-no-int-to-ptr,
+ -readability-function-cognitive-complexity,
+ -readability-identifier-length,
WarningsAsErrors: '*'
HeaderFilterRegex: '.*'
FormatStyle: file
diff --git a/.gitignore b/.gitignore
index 9a895df..b532cce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,4 @@
# generated files and folders
-.waf-*
-.lock-waf*
/build
*.pyc
NEWS
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d6014f1..92ff3ef 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,156 +1,165 @@
-stages: [build, test, deploy]
-
-variables:
- GIT_SUBMODULE_STRATEGY: normal
-
-.build_template: &build_definition
- stage: build
- artifacts:
- paths: ["build/", ".lock-waf*"]
-
-.test_template: &test_definition
- stage: test
- artifacts:
- paths: [build/coverage]
-
-
arm32_dbg:
- <<: *build_definition
- image: lv2plugin/debian-arm32
- script: python ./waf configure build -dST --werror
- variables:
- CC: "arm-linux-gnueabihf-gcc"
- CXX: "arm-linux-gnueabihf-g++"
-
-test:arm32_dbg:
- <<: *test_definition
image: lv2plugin/debian-arm32
- script: python ./waf test --wrapper=qemu-arm
- needs: [arm32_dbg]
-
+ script:
+ - meson setup build --cross-file=/usr/share/meson/cross/arm-linux-gnueabihf.ini -Dbuildtype=debug -Dstrict=true -Dwerror=true -Ddocs=disabled
+ - ninja -C build test
arm32_rel:
- <<: *build_definition
image: lv2plugin/debian-arm32
- script: python ./waf configure build -ST --werror
- variables:
- CC: "arm-linux-gnueabihf-gcc"
- CXX: "arm-linux-gnueabihf-g++"
-
-test:arm32_rel:
- <<: *test_definition
- image: lv2plugin/debian-arm32
- script: python ./waf test --wrapper=qemu-arm
- needs: [arm32_rel]
+ script:
+ - meson setup build --cross-file=/usr/share/meson/cross/arm-linux-gnueabihf.ini -Dbuildtype=release -Dstrict=true -Dwerror=true -Ddocs=disabled
+ - ninja -C build test
arm64_dbg:
- <<: *build_definition
image: lv2plugin/debian-arm64
- script: python ./waf configure build -dST --werror
- variables:
- CC: "aarch64-linux-gnu-gcc"
- CXX: "aarch64-linux-gnu-g++"
+ script:
+ - meson setup build --cross-file=/usr/share/meson/cross/aarch64-linux-gnu.ini -Dbuildtype=debug -Dstrict=true -Dwerror=true -Ddocs=disabled
+ - ninja -C build test
-test:arm64_dbg:
- <<: *test_definition
+arm64_rel:
image: lv2plugin/debian-arm64
- script: python ./waf test --wrapper=qemu-aarch64
- needs: [arm64_dbg]
+ script:
+ - meson setup build --cross-file=/usr/share/meson/cross/aarch64-linux-gnu.ini -Dbuildtype=release -Dstrict=true -Dwerror=true -Ddocs=disabled
+ - ninja -C build test
-arm64_rel:
- <<: *build_definition
- image: lv2plugin/debian-arm64
- script: python ./waf configure build -ST --werror
- variables:
- CC: "aarch64-linux-gnu-gcc"
- CXX: "aarch64-linux-gnu-g++"
+x32_dbg:
+ image: lv2plugin/debian-x32
+ script:
+ - meson setup build --cross-file=/usr/share/meson/cross/i686-linux-gnu.ini -Dbuildtype=debug -Dstrict=true -Dwerror=true -Ddocs=disabled
+ - ninja -C build test
-test:arm64_rel:
- <<: *test_definition
- image: lv2plugin/debian-arm64
- script: python ./waf test --wrapper=qemu-aarch64
- needs: [arm64_rel]
+x32_rel:
+ image: lv2plugin/debian-x32
+ script:
+ - meson setup build --cross-file=/usr/share/meson/cross/i686-linux-gnu.ini -Dbuildtype=release -Dstrict=true -Dwerror=true -Ddocs=disabled
+ - ninja -C build test
x64_dbg:
- <<: *build_definition
image: lv2plugin/debian-x64
- script: python ./waf configure build -dST --werror
+ script:
+ - meson setup build -Dbuildtype=debug -Dstrict=true -Dwerror=true -Db_coverage=true
+ - ninja -C build test
+ - ninja -C build coverage-html
+ coverage: '/ *lines\.*: \d+\.\d+.*/'
+ artifacts:
+ paths:
+ - build/meson-logs/coveragereport
-test:x64_dbg:
- <<: *test_definition
+x64_rel:
image: lv2plugin/debian-x64
- script: python ./waf test
- needs: [x64_dbg]
+ script:
+ - meson setup build -Dbuildtype=release -Dstrict=true -Dwerror=true -Ddocs=disabled
+ - ninja -C build test
-x64_rel:
- <<: *build_definition
+x64_static:
image: lv2plugin/debian-x64
- script: python ./waf configure build -ST --werror
+ script:
+ - meson setup build -Ddefault_library=static -Dstrict=true -Dwerror=true -Ddocs=disabled
+ - ninja -C build test
-test:x64_rel:
- <<: *test_definition
- image: lv2plugin/debian-x64
- script: python ./waf test
- needs: [x64_rel]
+
+x64_sanitize:
+ image: lv2plugin/debian-x64-clang
+ script:
+ - meson setup build -Db_lundef=false -Dbuildtype=plain -Dstrict=true -Dwerror=true -Ddocs=disabled
+ - ninja -C build test
+ variables:
+ CC: "clang"
+ CFLAGS: "-fno-sanitize-recover=all -fsanitize=address -fsanitize=undefined -fsanitize=float-divide-by-zero -fsanitize=unsigned-integer-overflow -fsanitize=implicit-conversion -fsanitize=local-bounds -fsanitize=nullability"
+ LDFLAGS: "-fno-sanitize-recover=all -fsanitize=address -fsanitize=undefined -fsanitize=float-divide-by-zero -fsanitize=unsigned-integer-overflow -fsanitize=implicit-conversion -fsanitize=local-bounds -fsanitize=nullability"
-mac_dbg:
- <<: *build_definition
- script: python ./waf configure build -dST --werror --no-coverage
- tags: [macos]
+freebsd_dbg:
+ tags: [freebsd,meson]
+ script:
+ - meson setup build -Dbuildtype=debug -Dstrict=true -Dwerror=true -Ddocs=disabled
+ - ninja -C build test
-test:mac_dbg:
- <<: *test_definition
- script: python ./waf test
- needs: [mac_dbg]
- tags: [macos]
+freebsd_rel:
+ tags: [freebsd,meson]
+ script:
+ - meson setup build -Dbuildtype=release -Dstrict=true -Dwerror=true -Ddocs=disabled
+ - ninja -C build test
-mac_rel:
- <<: *build_definition
- script: python ./waf configure build -ST --werror --no-coverage
+mingw32_dbg:
+ image: lv2plugin/debian-mingw32
+ script:
+ - meson setup build --cross-file=/usr/share/meson/cross/i686-w64-mingw32.ini -Dbuildtype=debug -Dstrict=true -Dwerror=true -Ddocs=disabled
+ - ninja -C build test
+
+mingw32_rel:
+ image: lv2plugin/debian-mingw32
+ script:
+ - meson setup build --cross-file=/usr/share/meson/cross/i686-w64-mingw32.ini -Dbuildtype=release -Dstrict=true -Dwerror=true -Ddocs=disabled
+ - ninja -C build test
+
+
+mingw64_dbg:
+ image: lv2plugin/debian-mingw64
+ script:
+ - meson setup build --cross-file=/usr/share/meson/cross/x86_64-w64-mingw32.ini -Dbuildtype=debug -Dstrict=true -Dwerror=true -Ddocs=disabled
+ - ninja -C build test
+
+mingw64_rel:
+ image: lv2plugin/debian-mingw64
+ script:
+ - meson setup build --cross-file=/usr/share/meson/cross/x86_64-w64-mingw32.ini -Dbuildtype=release -Dstrict=true -Dwerror=true -Ddocs=disabled
+ - ninja -C build test
+
+
+mac_dbg:
tags: [macos]
+ script:
+ - meson setup build -Dbuildtype=debug -Dstrict=true -Dwerror=true
+ - ninja -C build test
-test:mac_rel:
- <<: *test_definition
- script: python ./waf test
- needs: [mac_rel]
+mac_rel:
tags: [macos]
+ script:
+ - meson setup build -Dbuildtype=release -Dstrict=true -Dwerror=true
+ - ninja -C build test
win_dbg:
- <<: *build_definition
- script: python ./waf configure build -dST --werror --no-coverage
- tags: [windows,msvc,python]
+ tags: [windows,meson]
+ script:
+ - meson setup build -Dbuildtype=debug -Dstrict=true -Dwerror=true -Ddocs=disabled
+ - ninja -C build test
-test:win_dbg:
- <<: *test_definition
- script: python ./waf test
- needs: [win_dbg]
- tags: [windows,msvc,python]
+win_rel:
+ tags: [windows,meson]
+ script:
+ - meson setup build -Dbuildtype=release -Dstrict=true -Dwerror=true -Ddocs=disabled
+ - ninja -C build test
-win_rel:
- <<: *build_definition
- script: python ./waf configure build -ST --werror --no-coverage
- tags: [windows,msvc,python]
+wasm_dbg:
+ image: lv2plugin/debian-wasm
+ script:
+ - meson setup build --cross-file=/usr/share/meson/cross/wasm.ini -Dbuildtype=debug -Dstrict=true -Dwerror=true -Ddefault_library=static -Ddocs=disabled -Dplugins=disabled
+ - ninja -C build test
-test:win_rel:
- <<: *test_definition
- script: python ./waf test
- needs: [win_rel]
- tags: [windows,msvc,python]
+wasm_rel:
+ image: lv2plugin/debian-wasm
+ script:
+ - meson setup build --cross-file=/usr/share/meson/cross/wasm.ini -Dbuildtype=release -Dstrict=true -Dwerror=true -Ddefault_library=static -Ddocs=disabled -Dplugins=disabled
+ - ninja -C build test
pages:
stage: deploy
- script: mv build/coverage/ public/
- dependencies: ["test:x64_dbg"]
+ script:
+ - mkdir -p public
+ - mv build/meson-logs/coveragereport/ public/coverage
+ dependencies:
+ - x64_dbg
artifacts:
- paths: [public]
+ paths:
+ - public
only:
- master
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index cc8b569..0000000
--- a/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "waflib"]
- path = waflib
- url = ../../drobilla/autowaf.git
diff --git a/.stylelintrc.json b/.stylelintrc.json
new file mode 100644
index 0000000..473a3da
--- /dev/null
+++ b/.stylelintrc.json
@@ -0,0 +1,8 @@
+{
+ "extends": "/usr/lib/node_modules/stylelint-config-standard",
+ "rules": {
+ "color-hex-case": "upper",
+ "selector-list-comma-newline-after": "always-multi-line",
+ "no-descending-specificity": "off"
+ }
+}
diff --git a/INSTALL.md b/INSTALL.md
new file mode 100644
index 0000000..400391f
--- /dev/null
+++ b/INSTALL.md
@@ -0,0 +1,72 @@
+Installation Instructions
+=========================
+
+Prerequisites
+-------------
+
+To build from source, you will need:
+
+ * A relatively modern C compiler (GCC, Clang, and MSVC are known to work).
+
+ * [Meson](http://mesonbuild.com/), which depends on
+ [Python](http://python.org/).
+
+This is a brief overview of building this project with meson. See the meson
+documentation for more detailed information.
+
+Configuration
+-------------
+
+The build is configured with the `setup` command, which creates a new build
+directory with the given name:
+
+ meson setup build
+
+Some environment variables are read during `setup` and stored with the
+configuration:
+
+ * `CC`: Path to C compiler.
+ * `CFLAGS`: C compiler options.
+ * `CXX`: Path to C++ compiler.
+ * `CXXFLAGS`: C++ compiler options.
+ * `LDFLAGS`: Linker options.
+
+However, it is better to use meson options for configuration. All options can
+be inspected with the `configure` command from within the build directory:
+
+ cd build
+ meson configure
+
+Options can be set by passing C-style "define" options to `configure`:
+
+ meson configure -Dc_args="-march=native" -Dprefix="/opt/mypackage/"
+
+Building
+--------
+
+From within a configured build directory, everything can be built with the
+`compile` command:
+
+ meson compile
+
+Similarly, tests can be run with the `test` command:
+
+ meson test
+
+Meson can also generate a project for several popular IDEs, see the `backend`
+option for details.
+
+Installation
+------------
+
+A compiled project can be installed with the `install` command:
+
+ meson install
+
+You may need to acquire root permissions to install to a system-wide prefix.
+For packaging, the installation may be staged to a directory using the
+`DESTDIR` environment variable or the `--destdir` option:
+
+ DESTDIR=/tmp/mypackage/ meson install
+
+ meson install --destdir=/tmp/mypackage/
diff --git a/README.md b/README.md
index 0a4b4ea..5f4c438 100644
--- a/README.md
+++ b/README.md
@@ -1,82 +1,49 @@
LV2
===
-LV2 is a plugin standard for audio systems. It defines a minimal yet extensible
-C API for plugin code and a format for plugin "bundles". See
-<http://lv2plug.in> for more information.
-
-This package contains specifications (C headers and Turtle files),
-documentation generation tools, and example plugins.
-
-Building and installation requires only Python 2.6. Building the documentation
-requires Doxygen.
+LV2 is a plugin standard for audio systems. It defines an extensible C API for
+plugins, and a format for self-contained "bundle" directories that contain
+plugins, metadata, and other resources. See <http://lv2plug.in/> for more
+information.
+This package contains specifications (C headers and Turtle data files),
+documentation generation tools, tests, and example plugins.
Installation
------------
-A typical build looks something like this:
-
- ./waf configure --prefix=/foo
- ./waf
- sudo ./waf install
-
-or, for packaging:
-
- DESTDIR=/home/packager/lv2root ./waf install
-
-For help on the other available options, run:
-
- ./waf --help
-
-The bundle installation directory can be set with the --lv2dir option, e.g.:
-
- ./waf configure --lv2dir=/foo/lib/lv2
-
-Configuring with `--lv2-user` will install bundles to the user-local location.
+See the [installation instructions](INSTALL.md) for details on how to
+configure, build, and install LV2 with meson.
+By default, everything is installed within the `prefix` with a UNIX-style
+hierarchy, and LV2 bundles are installed in the "lv2" subdirectory of the
+`libdir`. The bundle installation directory can be overridden with the
+`lv2dir` option. For example, standard system-wide values for various
+operating systems are:
-Packaging
----------
+ meson configure -Dlv2dir=/Library/Audio/Plug-Ins/LV2
+ meson configure -Dlv2dir=/boot/common/add-ons/lv2
+ meson configure -Dlv2dir=C:/Program Files/Common/LV2
-Specification bundles are both a build-time and run-time dependency of programs
-that use LV2. Programs expect their data to be available somewhere in
-`LV2_PATH`.
+The [specification bundles](lv2) are run-time dependencies of LV2 applications.
+Programs expect their data to be available somewhere in `LV2_PATH`. See
+<http://lv2plug.in/pages/filesystem-hierarchy-standard.html> for details on the
+standard installation paths.
-See <http://lv2plug.in/pages/filesystem-hierarchy-standard.html> for details on
-the standard installation paths.
+Headers
+-------
-Do not split up LV2 bundles, they are self-contained and must remain whole.
-Other than that, things may be split to suit distribution needs. For example,
-separate packages for specifications, tools, and plugins, may be good idea.
+The `lv2/` include namespace is reserved for this LV2 distribution.
+Other projects may extend LV2, but must place their headers elsewhere.
-
-Header Installation
--------------------
-
-By default symbolic links to headers in bundles are installed to `INCLUDEDIR`.
-If symbolic links are a problem, configure with `--copy-headers` and copies
-will be installed instead.
-
-Headers are installed in two paths, the universal URI-based style:
-
- #include "lv2/lv2plug.in/ns/ext/urid/urid.h"
-
-and the newer simple core style:
+Headers are installed to `includedir` with paths like:
#include "lv2/urid/urid.h"
-Projects are encouraged to migrate to the latter style, though note that this
-style of include path may only be used by official LV2 specifications.
-
-
-Documentation
--------------
+For backwards compatibility, if the `old_headers` option is set, then headers
+are also installed to the older URI-based paths:
-Configuring with the --docs option will build the documentation for all the
-included specifications if Doxygen is available. For example:
-
- ./waf configure --docs
- ./waf
+ #include "lv2/lv2plug.in/ns/ext/urid/urid.h"
-Specification documentation is also available online at <http://lv2plug.in/ns>.
+Projects still using this style are encourated to migrate to the shorter style
+above.
diff --git a/doc/doxy-style.css b/doc/c/doxy-style.css
index 219da02..b44675e 100644
--- a/doc/doxy-style.css
+++ b/doc/c/doxy-style.css
@@ -1,6 +1,9 @@
-body {
+html {
background: #FFF;
color: #222;
+}
+
+body {
font-style: normal;
line-height: 1.6em;
margin-left: auto;
@@ -186,10 +189,6 @@ div.navtab {
margin-right: 15px;
}
-.contents a:visited {
- color: #344E00;
-}
-
a.qindexHL {
background-color: #9CAFD4;
color: #FFF;
@@ -526,7 +525,6 @@ td.mlabels-right {
margin-top: 0;
padding-top: 0.25em;
font-weight: normal;
- color: #444;
font-size: 0.9em;
}
@@ -862,3 +860,228 @@ th {
span.icon {
display: none;
}
+
+/* Dark mode */
+@media (prefers-color-scheme: dark) {
+ html {
+ background: #222;
+ color: #DDD;
+ }
+
+ a {
+ color: #B4C342;
+ }
+
+ h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
+ color: #DDD;
+ }
+
+ h1 a:link, h2 a:link, h3 a:link, h4 a:link, h5 a:link, h6 a:link {
+ color: #DDD;
+ }
+
+ h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited {
+ color: #DDD;
+ }
+
+ #header {
+ border-bottom-color: #333;
+ }
+
+ #title {
+ color: #CCC;
+ }
+
+ #shortdesc {
+ color: #BBB;
+ }
+
+ code {
+ color: #DDD;
+ }
+
+ pre.fragment {
+ border: 1px solid #444;
+ background-color: #333;
+ }
+
+ div.ah {
+ background-color: #000;
+ color: #FFF;
+ border-color: #333;
+ }
+
+ .groupheader + p {
+ color: #BBB;
+ }
+
+ td.indexkey {
+ background-color: #EBEFF6;
+ border: 1px solid #C4CFE5;
+ }
+
+ td.indexvalue {
+ background-color: #EBEFF6;
+ border: 1px solid #C4CFE5;
+ }
+
+ tr.memlist {
+ background-color: #EEF1F7;
+ }
+
+ span.keyword {
+ color: #586E75;
+ }
+
+ span.keywordtype {
+ color: #546E00;
+ }
+
+ span.keywordflow {
+ color: #586E75;
+ }
+
+ span.comment {
+ color: #6C71C4;
+ }
+
+ span.preprocessor {
+ color: #D33682;
+ }
+
+ span.stringliteral {
+ color: #CB4B16;
+ }
+
+ span.charliteral {
+ color: #CB4B16;
+ }
+
+ .dirtab {
+ border: 1px solid #A3B4D7;
+ }
+
+ th.dirtab {
+ background: #EBEFF6;
+ }
+
+ hr {
+ border-top: 1px solid #DDD;
+ }
+
+ #footer {
+ color: #888;
+ }
+
+ .mdescLeft,.mdescRight {
+ color: #555;
+ }
+
+ .memTemplParams {
+ color: #464646;
+ }
+
+ td.mlabels-right {
+ color: #B4C342;
+ }
+
+ .memtitle {
+ border-bottom: 1px solid #666;
+ }
+
+ .memtemplate {
+ color: #888;
+ }
+
+ .memnav {
+ background-color: #666;
+ border: 1px solid #B4C342;
+ }
+
+ .memproto {
+ border-bottom: 1px solid #666;
+ border-left: 1px solid #666;
+ color: #BBB;
+ }
+
+ .memdoc > p:first-child, .memdoc .textblock > p:first-child {
+ color: #BBB;
+ }
+
+ .memdoc > p:first-child, .memdoc .textblock > h3:first-child {
+ color: #BBB;
+ }
+
+ .paramtype {
+ color: #BBB;
+ }
+
+ .params .paramname {
+ color: #E8E8E8;
+ }
+
+ .fieldname {
+ color: #FFF;
+ }
+
+ .fieldtable tbody tr td {
+ border-top-color: #555;
+ border-bottom-color: #555;
+ }
+
+ td.fieldtype {
+ color: #BBB;
+ }
+
+ .arrow {
+ color: #666;
+ }
+
+ address {
+ color: #444;
+ }
+
+ table.doxtable td,table.doxtable th {
+ border-color: #DDD;
+ }
+
+ table.doxtable th {
+ background-color: #F3F3F3;
+ color: #000;
+ }
+
+ div.navpath {
+ color: #444;
+ }
+
+ #metabox {
+ color: #666;
+ }
+
+ .glow {
+ background-color: #00736F;
+ box-shadow: 0 0 10px #00736F;
+ }
+
+ span.lineno {
+ border-right: 2px solid #B4C342;
+ background-color: #383838;
+ }
+
+ span.lineno a {
+ background-color: #404040;
+ }
+
+ span.lineno a:hover {
+ background-color: #484848;
+ }
+
+}
+
+/* Hard black for dark mode on mobile (since it's likely to be an OLED screen) */
+@media only screen and (hover: none) and (pointer: coarse) and (prefers-color-scheme: dark) {
+ html {
+ background: #000;
+ color: #CCC;
+ }
+}
diff --git a/doc/footer.html b/doc/c/footer.html
index 0dc6919..0dc6919 100644
--- a/doc/footer.html
+++ b/doc/c/footer.html
diff --git a/doc/header.html b/doc/c/header.html
index 2e419e3..2e419e3 100644
--- a/doc/header.html
+++ b/doc/c/header.html
diff --git a/doc/layout.xml b/doc/c/layout.xml
index 1f63a76..938dbce 100644
--- a/doc/layout.xml
+++ b/doc/c/layout.xml
@@ -9,26 +9,12 @@
<tab type="namespacelist" visible="yes" title="" intro=""/>
<tab type="namespacemembers" visible="yes" title="" intro=""/>
</tab>
- <tab type="interfaces" visible="yes" title="">
- <tab type="interfacelist" visible="yes" title="" intro=""/>
- <tab type="interfaceindex" visible="$ALPHABETICAL_INDEX" title=""/>
- <tab type="interfacehierarchy" visible="yes" title="" intro=""/>
- </tab>
<tab type="classes" visible="yes" title="">
<tab type="classlist" visible="yes" title="" intro=""/>
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="hierarchy" visible="yes" title="" intro=""/>
<tab type="classmembers" visible="yes" title="" intro=""/>
</tab>
- <tab type="structs" visible="yes" title="">
- <tab type="structlist" visible="yes" title="" intro=""/>
- <tab type="structindex" visible="$ALPHABETICAL_INDEX" title=""/>
- </tab>
- <tab type="exceptions" visible="yes" title="">
- <tab type="exceptionlist" visible="yes" title="" intro=""/>
- <tab type="exceptionindex" visible="$ALPHABETICAL_INDEX" title=""/>
- <tab type="exceptionhierarchy" visible="yes" title="" intro=""/>
- </tab>
<tab type="files" visible="yes" title="">
<tab type="filelist" visible="yes" title="" intro=""/>
<tab type="globals" visible="yes" title="" intro=""/>
@@ -47,7 +33,6 @@
<nestedclasses visible="yes" title=""/>
<publictypes title=""/>
<services title=""/>
- <interfaces title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
@@ -82,7 +67,6 @@
<typedefs title=""/>
<enums title=""/>
<services title=""/>
- <interfaces title=""/>
<constructors title=""/>
<functions title=""/>
<related title=""/>
@@ -95,37 +79,6 @@
<authorsection visible="yes"/>
</class>
- <!-- Layout definition for a namespace page -->
- <namespace>
- <briefdescription visible="yes"/>
- <detaileddescription title=""/>
- <memberdecl>
- <nestednamespaces visible="yes" title=""/>
- <constantgroups visible="yes" title=""/>
- <interfaces visible="yes" title=""/>
- <classes visible="yes" title=""/>
- <structs visible="yes" title=""/>
- <exceptions visible="yes" title=""/>
- <typedefs title=""/>
- <sequences title=""/>
- <dictionaries title=""/>
- <enums title=""/>
- <functions title=""/>
- <variables title=""/>
- <membergroups visible="yes"/>
- </memberdecl>
- <memberdef>
- <inlineclasses title=""/>
- <typedefs title=""/>
- <sequences title=""/>
- <dictionaries title=""/>
- <enums title=""/>
- <functions title=""/>
- <variables title=""/>
- </memberdef>
- <authorsection visible="yes"/>
- </namespace>
-
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="yes"/>
@@ -135,16 +88,11 @@
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
<sourcelink visible="yes"/>
<memberdecl>
- <interfaces visible="yes" title=""/>
<classes visible="yes" title=""/>
- <structs visible="yes" title=""/>
- <exceptions visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
- <sequences title=""/>
- <dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
@@ -154,8 +102,6 @@
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
- <sequences title=""/>
- <dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
@@ -176,8 +122,6 @@
<classes visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
- <sequences title=""/>
- <dictionaries title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
@@ -196,8 +140,6 @@
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
- <sequences title=""/>
- <dictionaries title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
diff --git a/doc/mainpage.md b/doc/c/mainpage.md
index 561bc93..561bc93 100644
--- a/doc/mainpage.md
+++ b/doc/c/mainpage.md
diff --git a/doc/c/meson.build b/doc/c/meson.build
new file mode 100644
index 0000000..3ce7fdc
--- /dev/null
+++ b/doc/c/meson.build
@@ -0,0 +1,41 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+lv2_source_doc = meson.current_source_dir()
+
+if doxygen.found()
+ reference_doxygen_in = files('reference.doxygen.in')
+
+ config = configuration_data(
+ {
+ 'LV2_SRCDIR': lv2_source_root,
+ 'LV2_BUILDDIR': lv2_build_root,
+ 'LV2_VERSION': meson.project_version(),
+ }
+ )
+
+ reference_doxygen = configure_file(
+ configuration: config,
+ input: reference_doxygen_in,
+ output: 'reference.doxygen',
+ )
+
+ docs = custom_target(
+ 'html',
+ command: [doxygen, '@INPUT@'],
+ input: reference_doxygen,
+ install: true,
+ install_dir: lv2_docdir,
+ output: ['html', 'tags'],
+ )
+
+ # TODO: doc_deps is needed because Meson did not support using custom target
+ # outputs as dependencies until 0.60.0. When 0.60.0 is required, this can be
+ # cleaned up by removing doc_deps and using lv2_tags (not its path) as a
+ # command argument, which Meson will correctly make a dependency for.
+
+ lv2_tags = docs[1]
+ doc_deps = [docs]
+else
+ doc_deps = []
+endif
diff --git a/doc/reference.doxygen.in b/doc/c/reference.doxygen.in
index d5608ca..0b87d49 100644
--- a/doc/reference.doxygen.in
+++ b/doc/c/reference.doxygen.in
@@ -1,4 +1,4 @@
-# Doxyfile 1.8.15
+# Doxyfile 1.9.3
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
@@ -58,7 +58,7 @@ PROJECT_LOGO =
# entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used.
-OUTPUT_DIRECTORY = .
+OUTPUT_DIRECTORY = @LV2_BUILDDIR@
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and
@@ -222,16 +222,16 @@ TAB_SIZE = 4
# the documentation. An alias has the form:
# name=value
# For example adding
-# "sideeffect=@par Side Effects:\n"
+# "sideeffect=@par Side Effects:^^"
# will allow you to put the command \sideeffect (or @sideeffect) in the
# documentation, which will result in a user-defined paragraph with heading
-# "Side Effects:". You can put \n's in the value part of an alias to insert
-# newlines (in the resulting output). You can put ^^ in the value part of an
-# alias to insert a newline as if a physical newline was in the original file.
-# When you need a literal { or } or , in the value part of an alias you have to
-# escape them by means of a backslash (\), this can lead to conflicts with the
-# commands \{ and \} for these it is advised to use the version @{ and @} or use
-# a double escape (\\{ and \\})
+# "Side Effects:". Note that you cannot put \n's in the value part of an alias
+# to insert newlines (in the resulting output). You can put ^^ in the value part
+# of an alias to insert a newline as if a physical newline was in the original
+# file. When you need a literal { or } or , in the value part of an alias you
+# have to escape them by means of a backslash (\), this can lead to conflicts
+# with the commands \{ and \} for these it is advised to use the version @{ and
+# @} or use a double escape (\\{ and \\})
ALIASES =
@@ -267,19 +267,22 @@ OPTIMIZE_OUTPUT_VHDL = NO
# parses. With this tag you can assign which parser to use for a given
# extension. Doxygen has a built-in mapping, but you can override or extend it
# using this tag. The format is ext=language, where ext is a file extension, and
-# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
-# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice,
-# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
+# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,
+# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice,
+# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
# tries to guess whether the code is fixed or free formatted code, this is the
-# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat
-# .inc files as Fortran files (default is PHP), and .f files as C (default is
-# Fortran), use: inc=Fortran f=C.
+# default for Fortran type files). For instance to make doxygen treat .inc files
+# as Fortran files (default is PHP), and .f files as C (default is Fortran),
+# use: inc=Fortran f=C.
#
# Note: For files without extension you can use no_extension as a placeholder.
#
# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
-# the files are not read by doxygen.
+# the files are not read by doxygen. When specifying no_extension you should add
+# * to the FILE_PATTERNS.
+#
+# Note see also the list of default file extension mappings.
EXTENSION_MAPPING =
@@ -297,7 +300,7 @@ MARKDOWN_SUPPORT = YES
# to that level are automatically included in the table of contents, even if
# they do not have an id attribute.
# Note: This feature currently applies only to Markdown headings.
-# Minimum value: 0, maximum value: 99, default value: 0.
+# Minimum value: 0, maximum value: 99, default value: 5.
# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
TOC_INCLUDE_HEADINGS = 0
@@ -487,8 +490,8 @@ HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
-# (class|struct|union) declarations. If set to NO, these declarations will be
-# included in the documentation.
+# declarations. If set to NO, these declarations will be included in the
+# documentation.
# The default value is: NO.
HIDE_FRIEND_COMPOUNDS = NO
@@ -507,11 +510,18 @@ HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
-# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
-# names in lower-case letters. If set to YES, upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
+# With the correct setting of option CASE_SENSE_NAMES doxygen will better be
+# able to match the capabilities of the underlying filesystem. In case the
+# filesystem is case sensitive (i.e. it supports files in the same directory
+# whose names only differ in casing), the option must be set to YES to properly
+# deal with such files in case they appear in the input. For filesystems that
+# are not case sensitive the option should be be set to NO to properly deal with
+# output files written for symbols that only differ in casing, such as for two
+# classes, one named CLASS and the other named Class, and to also support
+# references to files without having to specify the exact matching casing. On
+# Windows (including Cygwin) and MacOS, users should typically set this option
+# to NO, whereas on Linux or other Unix flavors it should typically be set to
+# YES.
# The default value is: system dependent.
CASE_SENSE_NAMES = YES
@@ -687,13 +697,14 @@ FILE_VERSION_FILTER =
# output files in an output format independent way. To create the layout file
# that represents doxygen's defaults, run doxygen with the -l option. You can
# optionally specify a file name after the option, if omitted DoxygenLayout.xml
-# will be used as the name of the layout file.
+# will be used as the name of the layout file. See also section "Changing the
+# layout of pages" for information.
#
# Note that if you run doxygen from a directory containing a file called
# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
# tag is left empty.
-LAYOUT_FILE = @LV2_SRCDIR@/doc/layout.xml
+LAYOUT_FILE = @LV2_SRCDIR@/doc/c/layout.xml
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
# the reference definitions. This must be a list of .bib files. The .bib
@@ -733,24 +744,28 @@ WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some parameters
-# in a documented function, or documenting parameters that don't exist or using
-# markup commands wrongly.
+# potential errors in the documentation, such as documenting some parameters in
+# a documented function twice, or documenting parameters that don't exist or
+# using markup commands wrongly.
# The default value is: YES.
WARN_IF_DOC_ERROR = YES
# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
# are documented, but have no documentation for their parameters or return
-# value. If set to NO, doxygen will only warn about wrong or incomplete
-# parameter documentation, but not about the absence of documentation. If
-# EXTRACT_ALL is set to YES then this flag will automatically be disabled.
+# value. If set to NO, doxygen will only warn about wrong parameter
+# documentation, but not about the absence of documentation. If EXTRACT_ALL is
+# set to YES then this flag will automatically be disabled. See also
+# WARN_IF_INCOMPLETE_DOC
# The default value is: NO.
WARN_NO_PARAMDOC = NO
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
-# a warning is encountered.
+# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS
+# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but
+# at the end of the doxygen process doxygen will return with a non-zero status.
+# Possible values are: NO, YES and FAIL_ON_WARNINGS.
# The default value is: NO.
WARN_AS_ERROR = NO
@@ -767,7 +782,10 @@ WARN_FORMAT = "$file:$line: $text"
# The WARN_LOGFILE tag can be used to specify a file to which warning and error
# messages should be written. If left blank the output is written to standard
-# error (stderr).
+# error (stderr). In case the file specified cannot be opened for writing the
+# warning and error messages are written to standard error. When as file - is
+# specified the warning and error messages are written to standard output
+# (stdout).
WARN_LOGFILE =
@@ -781,41 +799,41 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.
-INPUT = @LV2_SRCDIR@/doc/mainpage.md \
- @LV2_SRCDIR@/lv2/atom/atom.h \
- @LV2_SRCDIR@/lv2/atom/forge.h \
- @LV2_SRCDIR@/lv2/atom/util.h \
- @LV2_SRCDIR@/lv2/buf-size/buf-size.h \
- @LV2_SRCDIR@/lv2/core/lv2.h \
- @LV2_SRCDIR@/lv2/data-access/data-access.h \
- @LV2_SRCDIR@/lv2/dynmanifest/dynmanifest.h \
- @LV2_SRCDIR@/lv2/event/event-helpers.h \
- @LV2_SRCDIR@/lv2/event/event.h \
- @LV2_SRCDIR@/lv2/instance-access/instance-access.h \
- @LV2_SRCDIR@/lv2/log/log.h \
- @LV2_SRCDIR@/lv2/log/logger.h \
- @LV2_SRCDIR@/lv2/midi/midi.h \
- @LV2_SRCDIR@/lv2/morph/morph.h \
- @LV2_SRCDIR@/lv2/options/options.h \
- @LV2_SRCDIR@/lv2/parameters/parameters.h \
- @LV2_SRCDIR@/lv2/patch/patch.h \
- @LV2_SRCDIR@/lv2/port-groups/port-groups.h \
- @LV2_SRCDIR@/lv2/port-props/port-props.h \
- @LV2_SRCDIR@/lv2/presets/presets.h \
- @LV2_SRCDIR@/lv2/resize-port/resize-port.h \
- @LV2_SRCDIR@/lv2/state/state.h \
- @LV2_SRCDIR@/lv2/time/time.h \
- @LV2_SRCDIR@/lv2/ui/ui.h \
- @LV2_SRCDIR@/lv2/units/units.h \
- @LV2_SRCDIR@/lv2/uri-map/uri-map.h \
- @LV2_SRCDIR@/lv2/urid/urid.h \
- @LV2_SRCDIR@/lv2/worker/worker.h
+INPUT = @LV2_SRCDIR@/doc/c/mainpage.md \
+ @LV2_SRCDIR@/include/lv2/atom/atom.h \
+ @LV2_SRCDIR@/include/lv2/atom/forge.h \
+ @LV2_SRCDIR@/include/lv2/atom/util.h \
+ @LV2_SRCDIR@/include/lv2/buf-size/buf-size.h \
+ @LV2_SRCDIR@/include/lv2/core/lv2.h \
+ @LV2_SRCDIR@/include/lv2/data-access/data-access.h \
+ @LV2_SRCDIR@/include/lv2/dynmanifest/dynmanifest.h \
+ @LV2_SRCDIR@/include/lv2/event/event-helpers.h \
+ @LV2_SRCDIR@/include/lv2/event/event.h \
+ @LV2_SRCDIR@/include/lv2/instance-access/instance-access.h \
+ @LV2_SRCDIR@/include/lv2/log/log.h \
+ @LV2_SRCDIR@/include/lv2/log/logger.h \
+ @LV2_SRCDIR@/include/lv2/midi/midi.h \
+ @LV2_SRCDIR@/include/lv2/morph/morph.h \
+ @LV2_SRCDIR@/include/lv2/options/options.h \
+ @LV2_SRCDIR@/include/lv2/parameters/parameters.h \
+ @LV2_SRCDIR@/include/lv2/patch/patch.h \
+ @LV2_SRCDIR@/include/lv2/port-groups/port-groups.h \
+ @LV2_SRCDIR@/include/lv2/port-props/port-props.h \
+ @LV2_SRCDIR@/include/lv2/presets/presets.h \
+ @LV2_SRCDIR@/include/lv2/resize-port/resize-port.h \
+ @LV2_SRCDIR@/include/lv2/state/state.h \
+ @LV2_SRCDIR@/include/lv2/time/time.h \
+ @LV2_SRCDIR@/include/lv2/ui/ui.h \
+ @LV2_SRCDIR@/include/lv2/units/units.h \
+ @LV2_SRCDIR@/include/lv2/uri-map/uri-map.h \
+ @LV2_SRCDIR@/include/lv2/urid/urid.h \
+ @LV2_SRCDIR@/include/lv2/worker/worker.h
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
-# documentation (see: https://www.gnu.org/software/libiconv/) for the list of
-# possible encodings.
+# documentation (see:
+# https://www.gnu.org/software/libiconv/) for the list of possible encodings.
# The default value is: UTF-8.
INPUT_ENCODING = UTF-8
@@ -828,11 +846,15 @@ INPUT_ENCODING = UTF-8
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# read by doxygen.
#
+# Note the list of default checked file patterns might differ from the list of
+# default file extension mappings.
+#
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
-# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
-# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
-# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice.
+# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml,
+# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C
+# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd,
+# *.vhdl, *.ucf, *.qsf and *.ice.
FILE_PATTERNS =
@@ -871,7 +893,7 @@ EXCLUDE_PATTERNS =
# (namespaces, classes, functions, etc.) that should be excluded from the
# output. The symbol name can be a fully qualified name, a word, or if the
# wildcard * is used, a substring. Examples: ANamespace, AClass,
-# AClass::ANamespace, ANamespace::*Test
+# ANamespace::AClass, ANamespace::*Test
#
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories use the pattern */test/*
@@ -958,7 +980,7 @@ FILTER_SOURCE_PATTERNS =
# (index.html). This can be useful if you have a project on for instance GitHub
# and want to reuse the introduction page also for the doxygen output.
-USE_MDFILE_AS_MAINPAGE = @LV2_SRCDIR@/doc/mainpage.md
+USE_MDFILE_AS_MAINPAGE = @LV2_SRCDIR@/doc/c/mainpage.md
#---------------------------------------------------------------------------
# Configuration options related to source browsing
@@ -1080,7 +1102,7 @@ GENERATE_HTML = YES
# The default directory is: html.
# This tag requires that the tag GENERATE_HTML is set to YES.
-HTML_OUTPUT = html
+HTML_OUTPUT = @LV2_BUILDDIR@/doc/c/html
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
# generated HTML page (for example: .htm, .php, .asp).
@@ -1107,7 +1129,7 @@ HTML_FILE_EXTENSION = .html
# of the possible markers and block names see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.
-HTML_HEADER = @LV2_SRCDIR@/doc/header.html
+HTML_HEADER = @LV2_SRCDIR@/doc/c/header.html
# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
# generated HTML page. If the tag is left blank doxygen will generate a standard
@@ -1117,7 +1139,7 @@ HTML_HEADER = @LV2_SRCDIR@/doc/header.html
# that doxygen normally uses.
# This tag requires that the tag GENERATE_HTML is set to YES.
-HTML_FOOTER = @LV2_SRCDIR@/doc/footer.html
+HTML_FOOTER = @LV2_SRCDIR@/doc/c/footer.html
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
# sheet that is used by each HTML page. It can be used to fine-tune the look of
@@ -1129,7 +1151,7 @@ HTML_FOOTER = @LV2_SRCDIR@/doc/footer.html
# obsolete.
# This tag requires that the tag GENERATE_HTML is set to YES.
-HTML_STYLESHEET = @LV2_SRCDIR@/doc/doxy-style.css
+HTML_STYLESHEET = @LV2_SRCDIR@/doc/c/doxy-style.css
# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
# cascading style sheets that are included after the standard style sheets
@@ -1156,7 +1178,7 @@ HTML_EXTRA_FILES =
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
# will adjust the colors in the style sheet and background images according to
-# this color. Hue is specified as an angle on a colorwheel, see
+# this color. Hue is specified as an angle on a color-wheel, see
# https://en.wikipedia.org/wiki/Hue for more information. For instance the value
# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
# purple, and 360 is red again.
@@ -1166,7 +1188,7 @@ HTML_EXTRA_FILES =
HTML_COLORSTYLE_HUE = 160
# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
-# in the HTML output. For a value of 0 the output will use grayscales only. A
+# in the HTML output. For a value of 0 the output will use gray-scales only. A
# value of 255 will produce the most vivid colors.
# Minimum value: 0, maximum value: 255, default value: 100.
# This tag requires that the tag GENERATE_HTML is set to YES.
@@ -1195,9 +1217,9 @@ HTML_TIMESTAMP = NO
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
# documentation will contain a main index with vertical navigation menus that
-# are dynamically created via Javascript. If disabled, the navigation index will
+# are dynamically created via JavaScript. If disabled, the navigation index will
# consists of multiple levels of tabs that are statically embedded in every HTML
-# page. Disable this option to support browsers that do not have Javascript,
+# page. Disable this option to support browsers that do not have JavaScript,
# like the Qt help browser.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
@@ -1227,10 +1249,11 @@ HTML_INDEX_NUM_ENTRIES = 100
# If the GENERATE_DOCSET tag is set to YES, additional index files will be
# generated that can be used as input for Apple's Xcode 3 integrated development
-# environment (see: https://developer.apple.com/xcode/), introduced with OSX
-# 10.5 (Leopard). To create a documentation set, doxygen will generate a
-# Makefile in the HTML output directory. Running make will produce the docset in
-# that directory and running make install will install the docset in
+# environment (see:
+# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To
+# create a documentation set, doxygen will generate a Makefile in the HTML
+# output directory. Running make will produce the docset in that directory and
+# running make install will install the docset in
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
# genXcode/_index.html for more information.
@@ -1272,8 +1295,12 @@ DOCSET_PUBLISHER_NAME = Publisher
# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
-# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on
-# Windows.
+# on Windows. In the beginning of 2021 Microsoft took the original page, with
+# a.o. the download links, offline the HTML help workshop was already many years
+# in maintenance mode). You can download the HTML help workshop from the web
+# archives at Installation executable (see:
+# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo
+# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe).
#
# The HTML Help Workshop contains a compiler that can convert all HTML output
# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
@@ -1303,7 +1330,7 @@ CHM_FILE =
HHC_LOCATION =
# The GENERATE_CHI flag controls if a separate .chi index file is generated
-# (YES) or that it should be included in the master .chm file (NO).
+# (YES) or that it should be included in the main .chm file (NO).
# The default value is: NO.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
@@ -1348,7 +1375,8 @@ QCH_FILE =
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
# Project output. For more information please see Qt Help Project / Namespace
-# (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
+# (see:
+# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
# The default value is: org.doxygen.Project.
# This tag requires that the tag GENERATE_QHP is set to YES.
@@ -1356,8 +1384,8 @@ QHP_NAMESPACE =
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
# Help Project output. For more information please see Qt Help Project / Virtual
-# Folders (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-
-# folders).
+# Folders (see:
+# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders).
# The default value is: doc.
# This tag requires that the tag GENERATE_QHP is set to YES.
@@ -1365,30 +1393,30 @@ QHP_VIRTUAL_FOLDER = doc
# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
# filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
-# filters).
+# Filters (see:
+# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_CUST_FILTER_NAME =
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
# custom filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
-# filters).
+# Filters (see:
+# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_CUST_FILTER_ATTRS =
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
# project's filter section matches. Qt Help Project / Filter Attributes (see:
-# http://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
+# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_SECT_FILTER_ATTRS =
-# The QHG_LOCATION tag can be used to specify the location of Qt's
-# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
-# generated .qhp file.
+# The QHG_LOCATION tag can be used to specify the location (absolute path
+# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to
+# run qhelpgenerator on the generated .qhp file.
# This tag requires that the tag GENERATE_QHP is set to YES.
QHG_LOCATION =
@@ -1431,11 +1459,11 @@ DISABLE_INDEX = NO
# to work a browser that supports JavaScript, DHTML, CSS and frames is required
# (i.e. any modern browser). Windows users are probably better off using the
# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
-# further fine-tune the look of the index. As an example, the default style
-# sheet generated by doxygen has an example that shows how to put an image at
-# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
-# the same information as the tab index, you could consider setting
-# DISABLE_INDEX to YES when enabling this option.
+# further fine tune the look of the index (see "Fine-tuning the output"). As an
+# example, the default style sheet generated by doxygen has an example that
+# shows how to put an image at the root of the tree instead of the PROJECT_NAME.
+# Since the tree basically has the same information as the tab index, you could
+# consider setting DISABLE_INDEX to YES when enabling this option.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
@@ -1486,7 +1514,7 @@ FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
-# https://www.mathjax.org) which uses client side Javascript for the rendering
+# https://www.mathjax.org) which uses client side JavaScript for the rendering
# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
# installed or if you want to formulas look prettier in the HTML output. When
# enabled you may also need to install MathJax separately and configure the path
@@ -1497,10 +1525,17 @@ FORMULA_TRANSPARENT = YES
USE_MATHJAX = NO
# When MathJax is enabled you can set the default output format to be used for
-# the MathJax output. See the MathJax site (see:
-# http://docs.mathjax.org/en/latest/output.html) for more details.
+# the MathJax output. For more details about the output format see MathJax
+# version 2 (see:
+# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3
+# (see:
+# http://docs.mathjax.org/en/latest/web/components/output.html).
# Possible values are: HTML-CSS (which is slower, but has the best
-# compatibility), NativeMML (i.e. MathML) and SVG.
+# compatibility. This is the name for Mathjax version 2, for MathJax version 3
+# this will be translated into chtml), NativeMML (i.e. MathML. Only supported
+# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This
+# is the name for Mathjax version 3, for MathJax version 2 this will be
+# translated into HTML-CSS) and SVG.
# The default value is: HTML-CSS.
# This tag requires that the tag USE_MATHJAX is set to YES.
@@ -1513,22 +1548,29 @@ MATHJAX_FORMAT = HTML-CSS
# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
# Content Delivery Network so you can quickly see the result without installing
# MathJax. However, it is strongly recommended to install a local copy of
-# MathJax from https://www.mathjax.org before deployment.
-# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/.
+# MathJax from https://www.mathjax.org before deployment. The default value is:
+# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2
+# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
# extension names that should be enabled during MathJax rendering. For example
+# for MathJax version 2 (see
+# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions):
# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# For example for MathJax version 3 (see
+# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html):
+# MATHJAX_EXTENSIONS = ams
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_EXTENSIONS =
# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
# of code that will be used on startup of the MathJax code. See the MathJax site
-# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# (see:
+# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an
# example see the documentation.
# This tag requires that the tag USE_MATHJAX is set to YES.
@@ -1556,7 +1598,7 @@ MATHJAX_CODEFILE =
SEARCHENGINE = NO
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
-# implemented using a web server instead of a web client using Javascript. There
+# implemented using a web server instead of a web client using JavaScript. There
# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
# setting. When disabled, doxygen will generate a PHP script for searching and
# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
@@ -1575,7 +1617,8 @@ SERVER_BASED_SEARCH = NO
#
# Doxygen ships with an example indexer (doxyindexer) and search engine
# (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: https://xapian.org/).
+# Xapian (see:
+# https://xapian.org/).
#
# See the section "External Indexing and Searching" for details.
# The default value is: NO.
@@ -1588,8 +1631,9 @@ EXTERNAL_SEARCH = NO
#
# Doxygen ships with an example indexer (doxyindexer) and search engine
# (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: https://xapian.org/). See the section "External Indexing and
-# Searching" for details.
+# Xapian (see:
+# https://xapian.org/). See the section "External Indexing and Searching" for
+# details.
# This tag requires that the tag SEARCHENGINE is set to YES.
SEARCHENGINE_URL =
@@ -1688,29 +1732,31 @@ PAPER_TYPE = a4
EXTRA_PACKAGES =
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
-# generated LaTeX document. The header should contain everything until the first
-# chapter. If it is left blank doxygen will generate a standard header. See
-# section "Doxygen usage" for information on how to let doxygen write the
-# default header to a separate file.
+# The LATEX_HEADER tag can be used to specify a user-defined LaTeX header for
+# the generated LaTeX document. The header should contain everything until the
+# first chapter. If it is left blank doxygen will generate a standard header. It
+# is highly recommended to start with a default header using
+# doxygen -w latex new_header.tex new_footer.tex new_stylesheet.sty
+# and then modify the file new_header.tex. See also section "Doxygen usage" for
+# information on how to generate the default header that doxygen normally uses.
#
-# Note: Only use a user-defined header if you know what you are doing! The
-# following commands have a special meaning inside the header: $title,
-# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
-# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
-# string, for the replacement values of the other commands the user is referred
-# to HTML_HEADER.
+# Note: Only use a user-defined header if you know what you are doing!
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. The following
+# commands have a special meaning inside the header (and footer): For a
+# description of the possible markers and block names see the documentation.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_HEADER =
-# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
-# generated LaTeX document. The footer should contain everything after the last
-# chapter. If it is left blank doxygen will generate a standard footer. See
+# The LATEX_FOOTER tag can be used to specify a user-defined LaTeX footer for
+# the generated LaTeX document. The footer should contain everything after the
+# last chapter. If it is left blank doxygen will generate a standard footer. See
# LATEX_HEADER for more information on how to generate a default footer and what
-# special commands can be used inside the footer.
-#
-# Note: Only use a user-defined footer if you know what you are doing!
+# special commands can be used inside the footer. See also section "Doxygen
+# usage" for information on how to generate the default footer that doxygen
+# normally uses. Note: Only use a user-defined footer if you know what you are
+# doing!
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_FOOTER =
@@ -1743,9 +1789,11 @@ LATEX_EXTRA_FILES =
PDF_HYPERLINKS = YES
-# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
-# the PDF file directly from the LaTeX files. Set this option to YES, to get a
-# higher quality PDF documentation.
+# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as
+# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX
+# files. Set this option to YES, to get a higher quality PDF documentation.
+#
+# See also section LATEX_CMD_NAME for selecting the engine.
# The default value is: YES.
# This tag requires that the tag GENERATE_LATEX is set to YES.
@@ -1753,8 +1801,7 @@ USE_PDFLATEX = YES
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
# command to the generated LaTeX files. This will instruct LaTeX to keep running
-# if errors occur, instead of asking the user for help. This option is also used
-# when generating formulas in HTML.
+# if errors occur, instead of asking the user for help.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
@@ -1767,16 +1814,6 @@ LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
-# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
-# code with syntax highlighting in the LaTeX output.
-#
-# Note that which sources are shown also depends on other settings such as
-# SOURCE_BROWSER.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_SOURCE_CODE = NO
-
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
# bibliography, e.g. plainnat, or ieeetr. See
# https://en.wikipedia.org/wiki/BibTeX and \cite for more info.
@@ -1849,16 +1886,6 @@ RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
-# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
-# with syntax highlighting in the RTF output.
-#
-# Note that which sources are shown also depends on other settings such as
-# SOURCE_BROWSER.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_SOURCE_CODE = NO
-
#---------------------------------------------------------------------------
# Configuration options related to the man page output
#---------------------------------------------------------------------------
@@ -1948,15 +1975,6 @@ GENERATE_DOCBOOK = NO
DOCBOOK_OUTPUT = docbook
-# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
-# program listings (including syntax highlighting and cross-referencing
-# information) to the DOCBOOK output. Note that enabling this will significantly
-# increase the size of the DOCBOOK output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
-
-DOCBOOK_PROGRAMLISTING = NO
-
#---------------------------------------------------------------------------
# Configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
@@ -2108,7 +2126,7 @@ TAGFILES =
# tag file that is based on the input files it reads. See section "Linking to
# external documentation" for more information about the usage of tag files.
-GENERATE_TAGFILE = tags
+GENERATE_TAGFILE = @LV2_BUILDDIR@/doc/c/tags
# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
# the class index. If set to NO, only the inherited external classes will be
@@ -2135,15 +2153,6 @@ EXTERNAL_PAGES = YES
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
-# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
-# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
-# NO turns the diagrams off. Note that this option also works with HAVE_DOT
-# disabled, but it is recommended to install and use dot, since it yields more
-# powerful graphs.
-# The default value is: YES.
-
-CLASS_DIAGRAMS = YES
-
# You can include diagrams made with dia in doxygen documentation. Doxygen will
# then run dia to produce the diagram and insert it in the documentation. The
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
@@ -2200,11 +2209,14 @@ DOT_FONTSIZE = 10
DOT_FONTPATH =
-# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
-# each documented class showing the direct and indirect inheritance relations.
-# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# If the CLASS_GRAPH tag is set to YES (or GRAPH) then doxygen will generate a
+# graph for each documented class showing the direct and indirect inheritance
+# relations. In case HAVE_DOT is set as well dot will be used to draw the graph,
+# otherwise the built-in generator will be used. If the CLASS_GRAPH tag is set
+# to TEXT the direct and indirect inheritance relations will be shown as texts /
+# links.
+# Possible values are: NO, YES, TEXT and GRAPH.
# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
CLASS_GRAPH = YES
@@ -2241,7 +2253,7 @@ UML_LOOK = NO
# but if the number exceeds 15, the total amount of fields shown is limited to
# 10.
# Minimum value: 0, maximum value: 100, default value: 10.
-# This tag requires that the tag HAVE_DOT is set to YES.
+# This tag requires that the tag UML_LOOK is set to YES.
UML_LIMIT_NUM_FIELDS = 10
@@ -2364,10 +2376,10 @@ MSCFILE_DIRS =
DIAFILE_DIRS =
# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
-# path where java can find the plantuml.jar file. If left blank, it is assumed
-# PlantUML is not used or called during a preprocessing step. Doxygen will
-# generate a warning when it encounters a \startuml command in this case and
-# will not generate output for the diagram.
+# path where java can find the plantuml.jar file or to the filename of jar file
+# to be used. If left blank, it is assumed PlantUML is not used or called during
+# a preprocessing step. Doxygen will generate a warning when it encounters a
+# \startuml command in this case and will not generate output for the diagram.
PLANTUML_JAR_PATH =
@@ -2429,14 +2441,18 @@ DOT_MULTI_TARGETS = YES
# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
# explaining the meaning of the various boxes and arrows in the dot generated
# graphs.
+# Note: This tag requires that UML_LOOK isn't set, i.e. the doxygen internal
+# graphical representation for inheritance and collaboration diagrams is used.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
GENERATE_LEGEND = YES
-# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate
# files that are used to generate the various graphs.
+#
+# Note: This setting is not only used for dot files but also for msc temporary
+# files.
# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
DOT_CLEANUP = YES
diff --git a/doc/index.html.in b/doc/index.html.in
index 875ad39..6f3e0f9 100644
--- a/doc/index.html.in
+++ b/doc/index.html.in
@@ -6,7 +6,7 @@
<meta http-equiv="Content-Type"
content="application/xhtml+xml;charset=utf-8" />
<link rel="stylesheet" type="text/css"
- href="../aux/style.css" />
+ href="../style/style.css" />
</head>
<body>
@@ -62,12 +62,12 @@
</div>
<div>
Valid
- <a about="" rel="dct:conformsTo" resource="http://www.w3.org/TR/rdfa-syntax"
+ <a about="" rel="dcterms:conformsTo" resource="http://www.w3.org/TR/rdfa-syntax"
href="http://validator.w3.org/check?uri=referer">
XHTML+RDFa
</a>
and
- <a about="" rel="dct:conformsTo" resource="http://www.w3.org/TR/CSS2"
+ <a about="" rel="dcterms:conformsTo" resource="http://www.w3.org/TR/CSS2"
href="http://jigsaw.w3.org/css-validator/check/referer">
CSS
</a>
diff --git a/doc/ns/ext/meson.build b/doc/ns/ext/meson.build
new file mode 100644
index 0000000..f6ad06b
--- /dev/null
+++ b/doc/ns/ext/meson.build
@@ -0,0 +1,67 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+config = configuration_data({'BASE': '/ns/ext'})
+
+if get_option('online_docs')
+ htaccess = configure_file(
+ configuration: config,
+ input: files('..' / '..' / 'htaccess.in'),
+ install_dir: lv2_docdir / 'ns' / 'ext',
+ output: '.htaccess',
+ )
+endif
+
+spec_names = [
+ 'atom',
+ 'buf-size',
+ 'data-access',
+ 'dynmanifest',
+ 'event',
+ 'instance-access',
+ 'log',
+ 'midi',
+ 'morph',
+ 'options',
+ 'parameters',
+ 'patch',
+ 'port-groups',
+ 'port-props',
+ 'presets',
+ 'resize-port',
+ 'state',
+ 'time',
+ 'uri-map',
+ 'urid',
+ 'worker',
+]
+
+if build_docs
+ foreach name : spec_names
+ spec_file = files(lv2_source_root / 'lv2' / name + '.lv2' / name + '.ttl')
+
+ custom_target(
+ name + '.html',
+ command: lv2specgen_command_prefix + [
+ '--docdir=../../c/html',
+ '--style-uri=../../style/style.css',
+ '@INPUT@',
+ '@OUTPUT@',
+ ],
+ depends: doc_deps,
+ input: spec_file,
+ install: true,
+ install_dir: lv2_docdir / 'ns' / 'ext',
+ output: name + '.html',
+ )
+
+ if get_option('online_docs')
+ configure_file(
+ copy: true,
+ input: spec_file,
+ install_dir: lv2_docdir / 'ns' / 'ext',
+ output: '@PLAINNAME@',
+ )
+ endif
+ endforeach
+endif
diff --git a/doc/ns/extensions/meson.build b/doc/ns/extensions/meson.build
new file mode 100644
index 0000000..5a25184
--- /dev/null
+++ b/doc/ns/extensions/meson.build
@@ -0,0 +1,48 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+config = configuration_data({'BASE': '/ns/extensions'})
+
+if get_option('online_docs')
+ htaccess = configure_file(
+ configuration: config,
+ input: files('..' / '..' / 'htaccess.in'),
+ install_dir: lv2_docdir / 'ns' / 'extensions',
+ output: '.htaccess',
+ )
+endif
+
+spec_names = [
+ 'ui',
+ 'units',
+]
+
+if build_docs
+ foreach name : spec_names
+ spec_file = files(lv2_source_root / 'lv2' / name + '.lv2' / name + '.ttl')
+
+ custom_target(
+ name + '.html',
+ command: lv2specgen_command_prefix + [
+ '--docdir=../../c/html',
+ '--style-uri=../../style/style.css',
+ '@INPUT@',
+ '@OUTPUT@',
+ ],
+ depends: doc_deps,
+ input: spec_file,
+ install: true,
+ install_dir: lv2_docdir / 'ns' / 'extensions',
+ output: name + '.html',
+ )
+
+ if get_option('online_docs')
+ configure_file(
+ copy: true,
+ input: spec_file,
+ install_dir: lv2_docdir / 'ns' / 'ext',
+ output: '@PLAINNAME@',
+ )
+ endif
+ endforeach
+endif
diff --git a/doc/ns/meson.build b/doc/ns/meson.build
new file mode 100644
index 0000000..aa41464
--- /dev/null
+++ b/doc/ns/meson.build
@@ -0,0 +1,80 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+config = configuration_data({'BASE': '/ns'})
+
+if get_option('online_docs')
+ htaccess = configure_file(
+ configuration: config,
+ input: files('..' / 'htaccess.in'),
+ install_dir: lv2_docdir / 'ns',
+ output: '.htaccess',
+ )
+endif
+
+######################
+# Core Documentation #
+######################
+
+if build_docs
+ spec_file = files(lv2_source_root / 'lv2' / 'core.lv2' / 'lv2core.ttl')
+
+ lv2_core_docs = custom_target(
+ 'lv2core.html',
+ command: lv2specgen_command_prefix + [
+ '--docdir=../c/html',
+ '--style-uri=../style/style.css',
+ '@INPUT@',
+ '@OUTPUT@',
+ ],
+ input: spec_file,
+ output: 'lv2core.html',
+ depends: doc_deps,
+ install: true,
+ install_dir: lv2_docdir / 'ns',
+ )
+
+ if get_option('online_docs')
+ configure_file(
+ copy: true,
+ input: spec_file,
+ install_dir: lv2_docdir / 'ns' / 'ext',
+ output: '@PLAINNAME@',
+ )
+ endif
+endif
+
+###########################
+# Extension Documentation #
+###########################
+
+subdir('ext')
+subdir('extensions')
+
+#########
+# Index #
+#########
+
+lv2_build_index = find_program(lv2_source_root / 'scripts' / 'lv2_build_index.py')
+
+lv2_build_index_command = [
+ lv2_build_index,
+ '--lv2-version', meson.project_version(),
+ '--lv2-source-root', lv2_source_root,
+]
+
+if get_option('online_docs')
+ lv2_build_index_command += [
+ '--online',
+ ]
+endif
+
+index = custom_target(
+ 'index.html',
+ capture: true,
+ command: lv2_build_index_command + ['@INPUT@'],
+ input: spec_files,
+ install: true,
+ install_dir: lv2_docdir / 'ns',
+ output: 'index.html',
+)
diff --git a/doc/pygments.css b/doc/pygments.css
deleted file mode 100644
index 4fb3387..0000000
--- a/doc/pygments.css
+++ /dev/null
@@ -1,61 +0,0 @@
-.c { color: #6C71C4; font-style: italic } /* Comment */
-.err { border: 1px solid #DC322F } /* Error */
-.k { color: #888888 } /* Keyword */
-.o { color: #839496 } /* Operator */
-.cm { color: #6C71C4; font-style: italic } /* Comment.Multiline */
-.cp { color: #D33682 } /* Comment.Preproc */
-.c1 { color: #6C71C4; font-style: italic } /* Comment.Single */
-.cs { color: #6C71C4; font-style: italic } /* Comment.Special */
-.gd { color: #A00000 } /* Generic.Deleted */
-.ge { font-style: italic } /* Generic.Emph */
-.gr { color: #DC322F } /* Generic.Error */
-.gh { color: #6C71C4; font-weight: bold } /* Generic.Heading */
-.gi { color: #859900 } /* Generic.Inserted */
-.go { color: #808080 } /* Generic.Output */
-.gp { color: #268BD2; font-weight: bold } /* Generic.Prompt */
-.gs { font-weight: bold } /* Generic.Strong */
-.gu { color: #800080; font-weight: bold } /* Generic.Subheading */
-.gt { color: #0040D0 } /* Generic.Traceback */
-.kc { color: #586E75; font-weight: bold } /* Keyword.Constant */
-.kd { color: #586E75; font-weight: bold } /* Keyword.Declaration */
-.kn { color: #586E75; font-weight: bold } /* Keyword.Namespace */
-.kp { color: #586E75 } /* Keyword.Pseudo */
-.kr { color: #586E75; font-weight: bold } /* Keyword.Reserved */
-.kt { color: #546E00 } /* Keyword.Type */
-.m { color: #666666 } /* Literal.Number */
-.s { color: #CB4B16 } /* Literal.String */
-.na { color: #7D9029 } /* Name.Attribute */
-.nb { color: #008000 } /* Name.Builtin */
-.nc { color: #000000; } /* Name.Class */
-.no { color: #880000 } /* Name.Constant */
-.nd { color: #AA22FF } /* Name.Decorator */
-.ni { color: #999999; font-weight: bold } /* Name.Entity */
-.ne { color: #D2413A; font-weight: bold } /* Name.Exception */
-.nf { color: #000000; } /* Name.Function */
-.nl { color: #A0A000 } /* Name.Label */
-.nn { color: #555555 } /* Name.Namespace */
-.nt { color: #223322; } /* Name.Tag */
-.nv { color: #222222 } /* Name.Variable */
-.ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
-.w { color: #bbbbbb } /* Text.Whitespace */
-.mf { color: #000000 } /* Literal.Number.Float */
-.mh { color: #000000 } /* Literal.Number.Hex */
-.mi { color: #000000 } /* Literal.Number.Integer */
-.mo { color: #000000 } /* Literal.Number.Oct */
-.sb { color: #CB4B16 } /* Literal.String.Backtick */
-.sc { color: #CB4B16 } /* Literal.String.Char */
-.sd { color: #CB4B16; font-style: italic } /* Literal.String.Doc */
-.s2 { color: #CB4B16 } /* Literal.String.Double */
-.se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
-.sh { color: #CB4B16 } /* Literal.String.Heredoc */
-.si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
-.sx { color: #008000 } /* Literal.String.Other */
-.sr { color: #BB6688 } /* Literal.String.Regex */
-.s1 { color: #CB4B16 } /* Literal.String.Single */
-.ss { color: #00629D } /* Literal.String.Symbol */
-.bp { color: #008000 } /* Name.Builtin.Pseudo */
-.vc { color: #00629D } /* Name.Variable.Class */
-.vg { color: #00629D } /* Name.Variable.Global */
-.vi { color: #00629D } /* Name.Variable.Instance */
-.il { color: #666666 } /* Literal.Number.Integer.Long */
-.p { color: #888888 } /* Punctuation */
diff --git a/doc/asciidoc.css b/doc/style/asciidoc.css
index 2e64544..2e64544 100644
--- a/doc/asciidoc.css
+++ b/doc/style/asciidoc.css
diff --git a/doc/style/meson.build b/doc/style/meson.build
new file mode 100644
index 0000000..7ae9a04
--- /dev/null
+++ b/doc/style/meson.build
@@ -0,0 +1,16 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+style_files = files(
+ 'pygments.css',
+ 'style.css'
+)
+
+foreach file : style_files
+ configure_file(
+ copy: true,
+ input: file,
+ install_dir: lv2_docdir / 'style',
+ output: '@PLAINNAME@',
+ )
+endforeach
diff --git a/doc/style/pygments.css b/doc/style/pygments.css
new file mode 100644
index 0000000..2472b1a
--- /dev/null
+++ b/doc/style/pygments.css
@@ -0,0 +1,558 @@
+/* Light (default) theme */
+
+.n {
+ color: #222;
+}
+
+.c {
+ color: #3F4D91;
+ font-style: italic;
+}
+
+.err {
+ border: 1px solid #DC322F;
+}
+
+.k {
+ color: #586E75;
+}
+
+.o {
+ color: #586E75;
+}
+
+.cm {
+ color: #3F4D91;
+ font-style: italic;
+}
+
+.cp {
+ color: #586E75;
+}
+
+.cpf {
+ color: #93115C;
+}
+
+.c1 {
+ color: #3F4D91;
+ font-style: italic;
+}
+
+.cs {
+ color: #3F4D91;
+ font-style: italic;
+}
+
+.gd {
+ color: #990A1B;
+}
+
+.ge {
+ font-style: italic;
+}
+
+.gr {
+ color: #DC322F;
+}
+
+.gh {
+ color: #3F4D91;
+ font-weight: bold;
+}
+
+.gi {
+ color: #859900;
+}
+
+.go {
+ color: #666;
+}
+
+.gp {
+ color: #666;
+ font-weight: bold;
+}
+
+.gs {
+ font-weight: bold;
+}
+
+.gu {
+ color: #444;
+ font-weight: bold;
+}
+
+.gt {
+ color: #268BD2;
+}
+
+.kc {
+ color: #586E75;
+ font-weight: bold;
+}
+
+.kd {
+ color: #586E75;
+ font-weight: bold;
+}
+
+.kn {
+ color: #586E75;
+ font-weight: bold;
+}
+
+.kp {
+ color: #586E75;
+}
+
+.kr {
+ color: #586E75;
+ font-weight: bold;
+}
+
+.kt {
+ color: #586E75;
+}
+
+.m {
+ color: #666;
+}
+
+.s {
+ color: #93115C;
+}
+
+.na {
+ color: #444;
+}
+
+.nb {
+ color: #3F4D91;
+}
+
+.nc {
+ color: #000;
+}
+
+.no {
+ color: #880;
+}
+
+.nd {
+ color: #A2F;
+}
+
+.ni {
+ color: #666;
+ font-weight: bold;
+}
+
+.ne {
+ color: #D2413A;
+ font-weight: bold;
+}
+
+.nf {
+ color: #000;
+}
+
+.nl {
+ color: #546E00;
+}
+
+.nn {
+ color: #444;
+}
+
+.nt {
+ color: #444;
+}
+
+.nv {
+ color: #222;
+}
+
+.ow {
+ color: #3F4D91;
+}
+
+.w {
+ color: #BBB;
+}
+
+.mb {
+ color: #93115C;
+ font-weight: bold;
+}
+
+.mf {
+ color: #93115C;
+}
+
+.mh {
+ color: #93115C;
+ font-weight: bold;
+}
+
+.mi {
+ color: #93115C;
+}
+
+.mo {
+ color: #93115C;
+ font-weight: bold;
+}
+
+.sb {
+ color: #93115C;
+}
+
+.sc {
+ color: #93115C;
+}
+
+.sd {
+ color: #3F4D91;
+ font-style: italic;
+}
+
+.s2 {
+ color: #93115C;
+}
+
+.se {
+ color: #93115C;
+ font-weight: bold;
+}
+
+.sh {
+ color: #93115C;
+}
+
+.si {
+ color: #93115C;
+ font-weight: bold;
+}
+
+.sx {
+ color: #93115C;
+}
+
+.sr {
+ color: #93115C;
+ font-weight: bold;
+}
+
+.s1 {
+ color: #93115C;
+}
+
+.ss {
+ color: #444;
+ font-weight: bold;
+}
+
+.bp {
+ color: #859900;
+}
+
+.vc {
+ color: #00629D;
+}
+
+.vg {
+ color: #00629D;
+}
+
+.vi {
+ color: #00629D;
+}
+
+.il {
+ color: #000;
+}
+
+.p {
+ color: #444;
+}
+
+/* Dark theme */
+@media (prefers-color-scheme: dark) {
+ .n {
+ color: #BBB;
+ }
+
+ .c {
+ color: #6C71C4;
+ font-style: italic;
+ }
+
+ .err {
+ border: 1px solid #FF6E64;
+ }
+
+ .k {
+ color: #93A1A1;
+ }
+
+ .o {
+ color: #93A1A1;
+ }
+
+ .cm {
+ color: #6C71C4;
+ font-style: italic;
+ }
+
+ .cp {
+ color: #93A1A1;
+ }
+
+ .cpf {
+ color: #D33682;
+ }
+
+ .c1 {
+ color: #6C71C4;
+ font-style: italic;
+ }
+
+ .cs {
+ color: #6C71C4;
+ font-style: italic;
+ }
+
+ .gd {
+ color: #DC322F;
+ }
+
+ .ge {
+ font-style: italic;
+ }
+
+ .gr {
+ color: #FF6E64;
+ }
+
+ .gh {
+ color: #6C71C4;
+ font-weight: bold;
+ }
+
+ .gi {
+ color: #859900;
+ }
+
+ .go {
+ color: #666;
+ }
+
+ .gp {
+ color: #666;
+ font-weight: bold;
+ }
+
+ .gs {
+ font-weight: bold;
+ }
+
+ .gu {
+ color: #BBB;
+ font-weight: bold;
+ }
+
+ .gt {
+ color: #69B7F0;
+ }
+
+ .kc {
+ color: #93A1A1;
+ font-weight: bold;
+ }
+
+ .kd {
+ color: #93A1A1;
+ font-weight: bold;
+ }
+
+ .kn {
+ color: #93A1A1;
+ font-weight: bold;
+ }
+
+ .kp {
+ color: #93A1A1;
+ }
+
+ .kr {
+ color: #93A1A1;
+ font-weight: bold;
+ }
+
+ .kt {
+ color: #93A1A1;
+ }
+
+ .m {
+ color: #999;
+ }
+
+ .s {
+ color: #D33682;
+ }
+
+ .na {
+ color: #BBB;
+ }
+
+ .nb {
+ color: #6C71C4;
+ }
+
+ .nc {
+ color: #FFF;
+ }
+
+ .no {
+ color: #880;
+ }
+
+ .nd {
+ color: #A2F;
+ }
+
+ .ni {
+ color: #999;
+ font-weight: bold;
+ }
+
+ .ne {
+ color: #D2413A;
+ font-weight: bold;
+ }
+
+ .nf {
+ color: #FFF;
+ }
+
+ .nl {
+ color: #546E00;
+ }
+
+ .nn {
+ color: #BBB;
+ }
+
+ .nt {
+ color: #BBB;
+ }
+
+ .nv {
+ color: #DDD;
+ }
+
+ .ow {
+ color: #6C71C4;
+ }
+
+ .w {
+ color: #BBB;
+ }
+
+ .mb {
+ color: #D33682;
+ font-weight: bold;
+ }
+
+ .mf {
+ color: #D33682;
+ }
+
+ .mh {
+ color: #D33682;
+ font-weight: bold;
+ }
+
+ .mi {
+ color: #D33682;
+ }
+
+ .mo {
+ color: #D33682;
+ font-weight: bold;
+ }
+
+ .sb {
+ color: #D33682;
+ }
+
+ .sc {
+ color: #D33682;
+ }
+
+ .sd {
+ color: #6C71C4;
+ font-style: italic;
+ }
+
+ .s2 {
+ color: #D33682;
+ }
+
+ .se {
+ color: #D33682;
+ font-weight: bold;
+ }
+
+ .sh {
+ color: #D33682;
+ }
+
+ .si {
+ color: #D33682;
+ font-weight: bold;
+ }
+
+ .sx {
+ color: #D33682;
+ }
+
+ .sr {
+ color: #D33682;
+ font-weight: bold;
+ }
+
+ .s1 {
+ color: #D33682;
+ }
+
+ .ss {
+ color: #BBB;
+ font-weight: bold;
+ }
+
+ .bp {
+ color: #859900;
+ }
+
+ .vc {
+ color: #268BD2;
+ }
+
+ .vg {
+ color: #268BD2;
+ }
+
+ .vi {
+ color: #268BD2;
+ }
+
+ .il {
+ color: #FFF;
+ }
+
+ .p {
+ color: #BBB;
+ }
+}
diff --git a/doc/style.css b/doc/style/style.css
index cf32b28..fca399e 100644
--- a/doc/style.css
+++ b/doc/style/style.css
@@ -2,9 +2,12 @@
/* Generic page style */
-body {
+html {
background: #FFF;
color: #222;
+}
+
+body {
font-family: "DejaVu Sans", "SF Pro Text", Verdana, sans-serif;
font-style: normal;
line-height: 1.6em;
@@ -19,7 +22,7 @@ h1 {
font-size: 2.38em;
font-weight: 600;
line-height: 1.41em;
- margin: 0 0 0.25em 0;
+ margin: 0 0 0.25em;
}
h2 {
@@ -27,7 +30,7 @@ h2 {
font-size: 1.68em;
font-weight: 600;
line-height: 1.3em;
- margin: 1.25em 0 0.5em 0;
+ margin: 1.25em 0 0.5em;
}
h3 {
@@ -35,7 +38,7 @@ h3 {
font-size: 1.41em;
font-weight: 600;
line-height: 1.19em;
- margin: 1.25em 0 0.5em 0;
+ margin: 1.25em 0 0.5em;
}
h4 {
@@ -43,7 +46,7 @@ h4 {
font-size: 1.19em;
font-weight: 600;
line-height: 1.09em;
- margin: 1.25em 0 0.5em 0;
+ margin: 1.25em 0 0.5em;
}
h5, h6 {
@@ -51,7 +54,7 @@ h5, h6 {
font-size: 1em;
font-weight: 600;
line-height: 1em;
- margin: 1.25em 0 0.5em 0;
+ margin: 1.25em 0 0.5em;
}
a {
@@ -89,7 +92,7 @@ img {
}
p {
- margin: 0.5em 0 0.5em 0;
+ margin: 0.5em 0;
}
blockquote {
@@ -106,13 +109,13 @@ pre, code, kbd, samp {
}
ul, ol {
- margin: 0 0 0.5em 0;
+ margin: 0 0 0.5em;
padding-top: 0;
}
dt {
font-weight: 600;
- margin: 0.75em 0 0.125em 0;
+ margin: 0.75em 0 0.125em;
}
dt::after {
@@ -123,7 +126,7 @@ dt::after {
hr {
background-color: #EEE;
border: 0;
- color: gray;
+ color: #666;
height: 1px;
margin-bottom: 1.5ex;
margin-top: 1.5ex;
@@ -192,7 +195,7 @@ footer {
#meta tr, #meta th, #meta td {
border: 0;
font-weight: normal;
- padding: 0 0 0.125em 0;
+ padding: 0 0 0.125em;
background-color: transparent;
}
@@ -211,7 +214,7 @@ footer {
#shortdesc {
padding: 0;
- margin: 0 0 0.5em 0;
+ margin: 0 0 0.5em;
font-style: italic;
color: #666;
display: inline-block;
@@ -238,7 +241,7 @@ footer {
padding: 3px 10px 0 0;
position: absolute;
top: 63px;
- width: 93.900002%;
+ width: 93.9%;
z-index: 0;
}
@@ -416,17 +419,11 @@ input.formbutton {
padding: 0 0 0 12px;
}
-blockquote {
- border-left: 1px solid #CCC;
- margin-left: 1em;
- padding-left: 1em;
-}
-
#footer {
bottom: 0;
clear: both;
font-size: x-small;
- margin: 2em 0 0 0;
+ margin: 2em 0 0;
padding: 0;
color: #888;
}
@@ -449,8 +446,8 @@ blockquote {
@media print {
#topbar {
color: #000;
- margin: 0.25em auto 0.25em auto;
- padding: 0.25em 0.5em 0.5em 0.5em;
+ margin: 0.25em auto;
+ padding: 0.25em 0.5em 0.5em;
max-width: 60em;
position: relative;
}
@@ -470,7 +467,7 @@ blockquote {
@media screen {
#topbar {
- margin: 0.25em auto 0.25em auto;
+ margin: 0.25em auto;
padding: 0;
max-width: 60em;
position: relative;
@@ -479,7 +476,7 @@ blockquote {
#contentsbox {
color: #546E00;
font-size: small;
- margin: 0 0 1.5em 0;
+ margin: 0 0 1.5em;
}
#contents {
@@ -506,7 +503,7 @@ blockquote {
.section {
clear: right;
- padding: 0 0 1.5em 0;
+ padding: 0 0 1.5em;
}
.category {
@@ -581,12 +578,11 @@ table.index {
border-bottom-left-radius: 6px;
}
-
table.terminfo {
border-top: 0;
border-collapse: collapse;
margin: -1px 0 2em 2em;
- padding: 0.25em 0 0.25em 0;
+ padding: 0.25em 0;
float: right;
border-bottom: 1px solid #EEE;
border-left: 1px solid #EEE;
@@ -602,7 +598,7 @@ table.terminfo td {
.restriction {
border-style: hidden;
- margin: 0 0 0.5ex 0;
+ margin: 0 0 0.5ex;
padding: 0;
vertical-align: text-top;
}
@@ -659,15 +655,6 @@ dl {
padding: 0;
}
-hr {
- background-color: #EEE;
- border: 0;
- color: gray;
- height: 1px;
- margin-bottom: 1.5ex;
- margin-top: 1.5ex;
-}
-
div.head {
margin-bottom: 1em;
}
@@ -701,3 +688,118 @@ div.head table {
.highlight, .codehilite {
margin-left: 2em;
}
+
+/* Dark mode */
+@media (prefers-color-scheme: dark) {
+ /* Dark generic page style */
+
+ html {
+ background: #222;
+ color: #DDD;
+ }
+
+ a {
+ color: #B4C342;
+ }
+
+ a:link {
+ color: #B4C342;
+ }
+
+ a:visited {
+ color: #B4C342;
+ }
+
+ h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
+ color: #DDD;
+ }
+
+ h1 a:link, h2 a:link, h3 a:link, h4 a:link, h5 a:link, h6 a:link {
+ color: #DDD;
+ }
+
+ h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited {
+ color: #DDD;
+ }
+
+ blockquote {
+ border-left: 1px solid #444;
+ }
+
+ pre, code, kbd, samp {
+ color: #DDD;
+ }
+
+ hr {
+ background-color: #333;
+ border: 0;
+ color: #666;
+ }
+
+ th {
+ border: 1px solid #444;
+ }
+
+ td {
+ border: 1px solid #444;
+ }
+
+ footer {
+ color: #BBB;
+ }
+
+ /* Dark specgen style */
+
+ #metabox {
+ color: #999;
+ }
+
+ #shortdesc {
+ color: #999;
+ }
+
+ #titlesep {
+ color: #444;
+ }
+
+ .terminfo, .restriction {
+ color: #999;
+ }
+
+ table.terminfo {
+ border-bottom: 1px solid #444;
+ border-left: 1px solid #444;
+ }
+
+ .spectermbody {
+ border-top: 1px solid #444;
+ }
+
+ .spectermbody .description .comment > p:first-child {
+ color: #BBB;
+ }
+
+ .error {
+ color: #DC322F;
+ }
+
+ .warning {
+ color: #B58900;
+ }
+
+ .success {
+ color: #859900;
+ }
+
+ #topbar {
+ border-bottom: 1px solid #444;
+ }
+}
+
+/* Hard black for dark mode on mobile (since it's likely to be an OLED screen) */
+@media only screen and (hover: none) and (pointer: coarse) and (prefers-color-scheme: dark) {
+ html {
+ background: #000;
+ color: #CCC;
+ }
+}
diff --git a/lv2/atom/atom.h b/include/lv2/atom/atom.h
index 5483155..b090c1e 100644
--- a/lv2/atom/atom.h
+++ b/include/lv2/atom/atom.h
@@ -234,7 +234,7 @@ typedef struct {
| Event 1 (size 6) | Event 2
| | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
- |FRAMES |SUBFRMS|TYPE |SIZE |DATADATADATAPAD|FRAMES |SUBFRMS|...
+ |FRAMES |TYPE |SIZE |DATADATADATAPAD|FRAMES |...
</pre>
*/
typedef struct {
diff --git a/lv2/atom/forge.h b/include/lv2/atom/forge.h
index 5cf3551..280bd53 100644
--- a/lv2/atom/forge.h
+++ b/include/lv2/atom/forge.h
@@ -365,7 +365,7 @@ static inline LV2_Atom_Forge_Ref
lv2_atom_forge_int(LV2_Atom_Forge* forge, int32_t val)
{
const LV2_Atom_Int a = {{sizeof(val), forge->Int}, val};
- return lv2_atom_forge_primitive(forge, &a.atom);
+ return lv2_atom_forge_primitive(forge, (const LV2_Atom*)&a);
}
/** Write an atom:Long. */
@@ -373,7 +373,7 @@ static inline LV2_Atom_Forge_Ref
lv2_atom_forge_long(LV2_Atom_Forge* forge, int64_t val)
{
const LV2_Atom_Long a = {{sizeof(val), forge->Long}, val};
- return lv2_atom_forge_primitive(forge, &a.atom);
+ return lv2_atom_forge_primitive(forge, (const LV2_Atom*)&a);
}
/** Write an atom:Float. */
@@ -381,7 +381,7 @@ static inline LV2_Atom_Forge_Ref
lv2_atom_forge_float(LV2_Atom_Forge* forge, float val)
{
const LV2_Atom_Float a = {{sizeof(val), forge->Float}, val};
- return lv2_atom_forge_primitive(forge, &a.atom);
+ return lv2_atom_forge_primitive(forge, (const LV2_Atom*)&a);
}
/** Write an atom:Double. */
@@ -389,7 +389,7 @@ static inline LV2_Atom_Forge_Ref
lv2_atom_forge_double(LV2_Atom_Forge* forge, double val)
{
const LV2_Atom_Double a = {{sizeof(val), forge->Double}, val};
- return lv2_atom_forge_primitive(forge, &a.atom);
+ return lv2_atom_forge_primitive(forge, (const LV2_Atom*)&a);
}
/** Write an atom:Bool. */
@@ -397,7 +397,7 @@ static inline LV2_Atom_Forge_Ref
lv2_atom_forge_bool(LV2_Atom_Forge* forge, bool val)
{
const LV2_Atom_Bool a = {{sizeof(int32_t), forge->Bool}, val ? 1 : 0};
- return lv2_atom_forge_primitive(forge, &a.atom);
+ return lv2_atom_forge_primitive(forge, (const LV2_Atom*)&a);
}
/** Write an atom:URID. */
@@ -405,7 +405,7 @@ static inline LV2_Atom_Forge_Ref
lv2_atom_forge_urid(LV2_Atom_Forge* forge, LV2_URID id)
{
const LV2_Atom_URID a = {{sizeof(id), forge->URID}, id};
- return lv2_atom_forge_primitive(forge, &a.atom);
+ return lv2_atom_forge_primitive(forge, (const LV2_Atom*)&a);
}
/** Write an atom compatible with atom:String. Used internally. */
@@ -497,7 +497,7 @@ lv2_atom_forge_vector(LV2_Atom_Forge* forge,
const void* elems)
{
const LV2_Atom_Vector a = {
- {(uint32_t)(sizeof(LV2_Atom_Vector_Body) + n_elems * child_size),
+ {(uint32_t)sizeof(LV2_Atom_Vector_Body) + n_elems * child_size,
forge->Vector},
{child_size, child_type}};
LV2_Atom_Forge_Ref out = lv2_atom_forge_write(forge, &a, sizeof(a));
diff --git a/lv2/atom/util.h b/include/lv2/atom/util.h
index f4612e9..16d2c00 100644
--- a/lv2/atom/util.h
+++ b/include/lv2/atom/util.h
@@ -125,13 +125,13 @@ lv2_atom_sequence_next(const LV2_Atom_Event* i)
@endcode
*/
#define LV2_ATOM_SEQUENCE_FOREACH(seq, iter) \
- for (LV2_Atom_Event * (iter) = lv2_atom_sequence_begin(&(seq)->body); \
+ for (LV2_Atom_Event * iter = lv2_atom_sequence_begin(&(seq)->body); \
!lv2_atom_sequence_is_end(&(seq)->body, (seq)->atom.size, (iter)); \
(iter) = lv2_atom_sequence_next(iter))
/** Like LV2_ATOM_SEQUENCE_FOREACH but for a headerless sequence body. */
#define LV2_ATOM_SEQUENCE_BODY_FOREACH(body, size, iter) \
- for (LV2_Atom_Event * (iter) = lv2_atom_sequence_begin(body); \
+ for (LV2_Atom_Event * iter = lv2_atom_sequence_begin(body); \
!lv2_atom_sequence_is_end(body, size, (iter)); \
(iter) = lv2_atom_sequence_next(iter))
@@ -224,14 +224,14 @@ lv2_atom_tuple_next(const LV2_Atom* i)
@endcode
*/
#define LV2_ATOM_TUPLE_FOREACH(tuple, iter) \
- for (LV2_Atom * (iter) = lv2_atom_tuple_begin(tuple); \
+ for (LV2_Atom * iter = lv2_atom_tuple_begin(tuple); \
!lv2_atom_tuple_is_end( \
LV2_ATOM_BODY(tuple), (tuple)->atom.size, (iter)); \
(iter) = lv2_atom_tuple_next(iter))
/** Like LV2_ATOM_TUPLE_FOREACH but for a headerless tuple body. */
#define LV2_ATOM_TUPLE_BODY_FOREACH(body, size, iter) \
- for (LV2_Atom * (iter) = (LV2_Atom*)(body); \
+ for (LV2_Atom * iter = (LV2_Atom*)(body); \
!lv2_atom_tuple_is_end(body, size, (iter)); \
(iter) = lv2_atom_tuple_next(iter))
@@ -284,13 +284,13 @@ lv2_atom_object_next(const LV2_Atom_Property_Body* i)
@endcode
*/
#define LV2_ATOM_OBJECT_FOREACH(obj, iter) \
- for (LV2_Atom_Property_Body * (iter) = lv2_atom_object_begin(&(obj)->body); \
+ for (LV2_Atom_Property_Body * iter = lv2_atom_object_begin(&(obj)->body); \
!lv2_atom_object_is_end(&(obj)->body, (obj)->atom.size, (iter)); \
(iter) = lv2_atom_object_next(iter))
/** Like LV2_ATOM_OBJECT_FOREACH but for a headerless object body. */
#define LV2_ATOM_OBJECT_BODY_FOREACH(body, size, iter) \
- for (LV2_Atom_Property_Body * (iter) = lv2_atom_object_begin(body); \
+ for (LV2_Atom_Property_Body * iter = lv2_atom_object_begin(body); \
!lv2_atom_object_is_end(body, size, (iter)); \
(iter) = lv2_atom_object_next(iter))
diff --git a/lv2/buf-size/buf-size.h b/include/lv2/buf-size/buf-size.h
index d96e17d..d96e17d 100644
--- a/lv2/buf-size/buf-size.h
+++ b/include/lv2/buf-size/buf-size.h
diff --git a/lv2/core/attributes.h b/include/lv2/core/attributes.h
index dfcff3a..81791a2 100644
--- a/lv2/core/attributes.h
+++ b/include/lv2/core/attributes.h
@@ -35,11 +35,11 @@
#if defined(__clang__)
# define LV2_DISABLE_DEPRECATION_WARNINGS \
_Pragma("clang diagnostic push") \
- _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
+ _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
#elif defined(__GNUC__) && __GNUC__ > 4
# define LV2_DISABLE_DEPRECATION_WARNINGS \
_Pragma("GCC diagnostic push") \
- _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
+ _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
#else
# define LV2_DISABLE_DEPRECATION_WARNINGS
#endif
diff --git a/lv2/core/lv2.h b/include/lv2/core/lv2.h
index 84c40a5..84c40a5 100644
--- a/lv2/core/lv2.h
+++ b/include/lv2/core/lv2.h
diff --git a/lv2/core/lv2_util.h b/include/lv2/core/lv2_util.h
index f3766aa..f3766aa 100644
--- a/lv2/core/lv2_util.h
+++ b/include/lv2/core/lv2_util.h
diff --git a/lv2/data-access/data-access.h b/include/lv2/data-access/data-access.h
index de3b6b6..de3b6b6 100644
--- a/lv2/data-access/data-access.h
+++ b/include/lv2/data-access/data-access.h
diff --git a/lv2/dynmanifest/dynmanifest.h b/include/lv2/dynmanifest/dynmanifest.h
index 674577b..674577b 100644
--- a/lv2/dynmanifest/dynmanifest.h
+++ b/include/lv2/dynmanifest/dynmanifest.h
diff --git a/lv2/event/event-helpers.h b/include/lv2/event/event-helpers.h
index 1e19e58..bf1b885 100644
--- a/lv2/event/event-helpers.h
+++ b/include/lv2/event/event-helpers.h
@@ -51,7 +51,7 @@ LV2_DISABLE_DEPRECATION_WARNINGS
static inline uint16_t
lv2_event_pad_size(uint16_t size)
{
- return (uint16_t)(size + 7U) & (uint16_t)(~7U);
+ return (uint16_t)((size + 7U) & ~7U);
}
/** Initialize (empty, reset..) an existing event buffer.
diff --git a/lv2/event/event.h b/include/lv2/event/event.h
index 045ac12..ed5adde 100644
--- a/lv2/event/event.h
+++ b/include/lv2/event/event.h
@@ -255,15 +255,11 @@ typedef struct {
If the event is only stored OR passed through, this is not necessary
(as the plugin already has 1 implicit reference).
+ @param callback_data The callback_data field of this struct.
+
@param event An event received at an input that will not be copied to
an output or stored in any way.
- @param context The calling context. Like event types, this is a mapped
- URI, see lv2_context.h. Simple plugin with just a run() method should
- pass 0 here (the ID of the 'standard' LV2 run context). The host
- guarantees that this function is realtime safe iff the context is
- realtime safe.
-
PLUGINS THAT VIOLATE THESE RULES MAY CAUSE CRASHES AND MEMORY LEAKS.
*/
uint32_t (*lv2_event_ref)(LV2_Event_Callback_Data callback_data,
@@ -278,15 +274,11 @@ typedef struct {
an output or store it internally somehow, it MUST call this function
on the event (more information on using non-POD events below).
+ @param callback_data The callback_data field of this struct.
+
@param event An event received at an input that will not be copied to an
output or stored in any way.
- @param context The calling context. Like event types, this is a mapped
- URI, see lv2_context.h. Simple plugin with just a run() method should
- pass 0 here (the ID of the 'standard' LV2 run context). The host
- guarantees that this function is realtime safe iff the context is
- realtime safe.
-
PLUGINS THAT VIOLATE THESE RULES MAY CAUSE CRASHES AND MEMORY LEAKS.
*/
uint32_t (*lv2_event_unref)(LV2_Event_Callback_Data callback_data,
diff --git a/lv2/instance-access/instance-access.h b/include/lv2/instance-access/instance-access.h
index 2986f69..2986f69 100644
--- a/lv2/instance-access/instance-access.h
+++ b/include/lv2/instance-access/instance-access.h
diff --git a/lv2/log/log.h b/include/lv2/log/log.h
index cc62bef..cc62bef 100644
--- a/lv2/log/log.h
+++ b/include/lv2/log/log.h
diff --git a/lv2/log/logger.h b/include/lv2/log/logger.h
index d6919a2..d6919a2 100644
--- a/lv2/log/logger.h
+++ b/include/lv2/log/logger.h
diff --git a/lv2/midi/midi.h b/include/lv2/midi/midi.h
index 2c70f0c..f7e0500 100644
--- a/lv2/midi/midi.h
+++ b/include/lv2/midi/midi.h
@@ -215,7 +215,7 @@ lv2_midi_is_system_message(const uint8_t* msg)
case 0xFD:
return false;
default:
- return (msg[0] & 0xF0) == 0xF0;
+ return (msg[0] & 0xF0u) == 0xF0u;
}
}
@@ -227,7 +227,7 @@ static inline LV2_Midi_Message_Type
lv2_midi_message_type(const uint8_t* msg)
{
if (lv2_midi_is_voice_message(msg)) {
- return (LV2_Midi_Message_Type)(msg[0] & 0xF0);
+ return (LV2_Midi_Message_Type)(msg[0] & 0xF0u);
}
if (lv2_midi_is_system_message(msg)) {
diff --git a/lv2/morph/morph.h b/include/lv2/morph/morph.h
index 370937a..370937a 100644
--- a/lv2/morph/morph.h
+++ b/include/lv2/morph/morph.h
diff --git a/lv2/options/options.h b/include/lv2/options/options.h
index 0d0c16d..06e5db4 100644
--- a/lv2/options/options.h
+++ b/include/lv2/options/options.h
@@ -102,11 +102,11 @@ typedef struct {
/** A status code for option functions. */
typedef enum {
- LV2_OPTIONS_SUCCESS = 0, /**< Completed successfully. */
- LV2_OPTIONS_ERR_UNKNOWN = 1, /**< Unknown error. */
- LV2_OPTIONS_ERR_BAD_SUBJECT = 1 << 1, /**< Invalid/unsupported subject. */
- LV2_OPTIONS_ERR_BAD_KEY = 1 << 2, /**< Invalid/unsupported key. */
- LV2_OPTIONS_ERR_BAD_VALUE = 1 << 3 /**< Invalid/unsupported value. */
+ LV2_OPTIONS_SUCCESS = 0u, /**< Completed successfully. */
+ LV2_OPTIONS_ERR_UNKNOWN = 1u, /**< Unknown error. */
+ LV2_OPTIONS_ERR_BAD_SUBJECT = 1u << 1u, /**< Invalid/unsupported subject. */
+ LV2_OPTIONS_ERR_BAD_KEY = 1u << 2u, /**< Invalid/unsupported key. */
+ LV2_OPTIONS_ERR_BAD_VALUE = 1u << 3u /**< Invalid/unsupported value. */
} LV2_Options_Status;
/**
diff --git a/lv2/parameters/parameters.h b/include/lv2/parameters/parameters.h
index 66a7561..66a7561 100644
--- a/lv2/parameters/parameters.h
+++ b/include/lv2/parameters/parameters.h
diff --git a/lv2/patch/patch.h b/include/lv2/patch/patch.h
index 4db2abb..4db2abb 100644
--- a/lv2/patch/patch.h
+++ b/include/lv2/patch/patch.h
diff --git a/lv2/port-groups/port-groups.h b/include/lv2/port-groups/port-groups.h
index 0ff25c7..0ff25c7 100644
--- a/lv2/port-groups/port-groups.h
+++ b/include/lv2/port-groups/port-groups.h
diff --git a/lv2/port-props/port-props.h b/include/lv2/port-props/port-props.h
index ff4adcd..ff4adcd 100644
--- a/lv2/port-props/port-props.h
+++ b/include/lv2/port-props/port-props.h
diff --git a/lv2/presets/presets.h b/include/lv2/presets/presets.h
index 716ab32..716ab32 100644
--- a/lv2/presets/presets.h
+++ b/include/lv2/presets/presets.h
diff --git a/lv2/resize-port/resize-port.h b/include/lv2/resize-port/resize-port.h
index a3a11c4..a3a11c4 100644
--- a/lv2/resize-port/resize-port.h
+++ b/include/lv2/resize-port/resize-port.h
diff --git a/lv2/state/state.h b/include/lv2/state/state.h
index e526d85..01ec598 100644
--- a/lv2/state/state.h
+++ b/include/lv2/state/state.h
@@ -82,7 +82,7 @@ typedef enum {
Implementations MUST NOT attempt to copy or serialise a non-POD value if
they do not understand its type (and thus know how to correctly do so).
*/
- LV2_STATE_IS_POD = 1,
+ LV2_STATE_IS_POD = 1u << 0u,
/**
Portable (architecture independent) data.
@@ -93,7 +93,7 @@ typedef enum {
values MUST NOT depend on architecture-specific properties like
endianness or alignment. Portable values MUST NOT contain filenames.
*/
- LV2_STATE_IS_PORTABLE = 1 << 1,
+ LV2_STATE_IS_PORTABLE = 1u << 1u,
/**
Native data.
@@ -104,7 +104,7 @@ typedef enum {
most efficient representation possible and not worry about serialisation
and portability.
*/
- LV2_STATE_IS_NATIVE = 1 << 2
+ LV2_STATE_IS_NATIVE = 1u << 2u
} LV2_State_Flags;
/** A status code for state functions. */
diff --git a/lv2/time/time.h b/include/lv2/time/time.h
index 1dce219..1dce219 100644
--- a/lv2/time/time.h
+++ b/include/lv2/time/time.h
diff --git a/lv2/ui/ui.h b/include/lv2/ui/ui.h
index fb41d90..fb41d90 100644
--- a/lv2/ui/ui.h
+++ b/include/lv2/ui/ui.h
diff --git a/lv2/units/units.h b/include/lv2/units/units.h
index 09ae16b..09ae16b 100644
--- a/lv2/units/units.h
+++ b/include/lv2/units/units.h
diff --git a/lv2/uri-map/uri-map.h b/include/lv2/uri-map/uri-map.h
index 47cde1c..47cde1c 100644
--- a/lv2/uri-map/uri-map.h
+++ b/include/lv2/uri-map/uri-map.h
diff --git a/lv2/urid/urid.h b/include/lv2/urid/urid.h
index b537d14..b537d14 100644
--- a/lv2/urid/urid.h
+++ b/include/lv2/urid/urid.h
diff --git a/lv2/worker/worker.h b/include/lv2/worker/worker.h
index 4fd89f9..4fd89f9 100644
--- a/lv2/worker/worker.h
+++ b/include/lv2/worker/worker.h
diff --git a/lv2.pc.in b/lv2.pc.in
deleted file mode 100644
index bfc1d14..0000000
--- a/lv2.pc.in
+++ /dev/null
@@ -1,7 +0,0 @@
-prefix=@PREFIX@
-includedir=@INCLUDEDIR@
-
-Name: LV2
-Version: @VERSION@
-Description: An extensible audio plugin interface.
-Cflags: -I${includedir}
diff --git a/lv2/atom/atom.meta.ttl b/lv2/atom.lv2/atom.meta.ttl
index cc09060..adab5f4 100644
--- a/lv2/atom/atom.meta.ttl
+++ b/lv2/atom.lv2/atom.meta.ttl
@@ -13,6 +13,16 @@
doap:created "2007-00-00" ;
doap:developer <http://drobilla.net/drobilla#me> ;
doap:release [
+ doap:revision "2.4" ;
+ doap:created "2022-05-26" ;
+ doap:file-release <http://lv2plug.in/spec/lv2-1.18.4.tar.bz2> ;
+ dcs:blame <http://drobilla.net/drobilla#me> ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "Fix spelling errors."
+ ]
+ ]
+ ] , [
doap:revision "2.2" ;
doap:created "2019-02-03" ;
doap:file-release <http://lv2plug.in/spec/lv2-1.16.0.tar.bz2> ;
diff --git a/lv2/atom/atom.ttl b/lv2/atom.lv2/atom.ttl
index ef221ad..bdeaebf 100644
--- a/lv2/atom/atom.ttl
+++ b/lv2/atom.lv2/atom.ttl
@@ -9,10 +9,7 @@
<http://lv2plug.in/ns/ext/atom>
a owl:Ontology ;
- rdfs:seeAlso <atom.h> ,
- <util.h> ,
- <forge.h> ,
- <atom.meta.ttl> ;
+ rdfs:seeAlso <atom.meta.ttl> ;
rdfs:label "LV2 Atom" ;
rdfs:comment "A generic value container and several data types." ;
owl:imports <http://lv2plug.in/ns/lv2core> ,
diff --git a/lv2/atom/manifest.ttl b/lv2/atom.lv2/manifest.ttl
index 9cf13aa..3cb5134 100644
--- a/lv2/atom/manifest.ttl
+++ b/lv2/atom.lv2/manifest.ttl
@@ -4,6 +4,6 @@
<http://lv2plug.in/ns/ext/atom>
a lv2:Specification ;
lv2:minorVersion 2 ;
- lv2:microVersion 3 ;
+ lv2:microVersion 4 ;
rdfs:seeAlso <atom.ttl> .
diff --git a/lv2/buf-size/buf-size.meta.ttl b/lv2/buf-size.lv2/buf-size.meta.ttl
index b1d8011..b1d8011 100644
--- a/lv2/buf-size/buf-size.meta.ttl
+++ b/lv2/buf-size.lv2/buf-size.meta.ttl
diff --git a/lv2/buf-size/buf-size.ttl b/lv2/buf-size.lv2/buf-size.ttl
index c78d2cc..4f6bd52 100644
--- a/lv2/buf-size/buf-size.ttl
+++ b/lv2/buf-size.lv2/buf-size.ttl
@@ -10,8 +10,7 @@
a owl:Ontology ;
rdfs:label "LV2 Buf Size" ;
rdfs:comment "Access to, and restrictions on, buffer sizes." ;
- rdfs:seeAlso <buf-size.h> ,
- <buf-size.meta.ttl> ;
+ rdfs:seeAlso <buf-size.meta.ttl> ;
owl:imports <http://lv2plug.in/ns/lv2core> ,
<http://lv2plug.in/ns/ext/options> .
diff --git a/lv2/buf-size/manifest.ttl b/lv2/buf-size.lv2/manifest.ttl
index d242f97..d242f97 100644
--- a/lv2/buf-size/manifest.ttl
+++ b/lv2/buf-size.lv2/manifest.ttl
diff --git a/lv2/core/lv2core.meta.ttl b/lv2/core.lv2/lv2core.meta.ttl
index 7dac5c1..e9ed39c 100644
--- a/lv2/core/lv2core.meta.ttl
+++ b/lv2/core.lv2/lv2core.meta.ttl
@@ -16,6 +16,25 @@
<http://drobilla.net/drobilla#me> ;
doap:maintainer <http://drobilla.net/drobilla#me> ;
doap:release [
+ doap:revision "18.5" ;
+ doap:created "2022-08-04" ;
+ dcs:blame <http://drobilla.net/drobilla#me> ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "Fix inconsistent plugin class labels."
+ ]
+ ]
+ ] , [
+ doap:revision "18.4" ;
+ doap:created "2022-05-26" ;
+ doap:file-release <http://lv2plug.in/spec/lv2-1.18.4.tar.bz2> ;
+ dcs:blame <http://drobilla.net/drobilla#me> ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "Fix spelling errors."
+ ]
+ ]
+ ] , [
doap:revision "18.0" ;
doap:created "2020-04-26" ;
doap:file-release <http://lv2plug.in/spec/lv2-1.18.0.tar.bz2> ;
diff --git a/lv2/core/lv2core.ttl b/lv2/core.lv2/lv2core.ttl
index bd9fc93..7722cac 100644
--- a/lv2/core/lv2core.ttl
+++ b/lv2/core.lv2/lv2core.ttl
@@ -9,9 +9,7 @@
a owl:Ontology ;
rdfs:label "LV2" ;
rdfs:comment "An extensible open standard for audio plugins." ;
- rdfs:seeAlso <lv2.h> ,
- <lv2_util.h> ,
- <lv2core.meta.ttl> ;
+ rdfs:seeAlso <lv2core.meta.ttl> ;
owl:imports doap: .
lv2:Specification
@@ -537,21 +535,21 @@ lv2:CombPlugin
a rdfs:Class ,
owl:Class ;
rdfs:subClassOf lv2:FilterPlugin ;
- rdfs:label "Comb FilterPlugin" ;
+ rdfs:label "Comb Filter Plugin" ;
rdfs:comment "A filter that adds a delayed version of its input to itself." .
lv2:AllpassPlugin
a rdfs:Class ,
owl:Class ;
rdfs:subClassOf lv2:FilterPlugin ;
- rdfs:label "Allpass Plugin" ;
+ rdfs:label "Allpass Filter Plugin" ;
rdfs:comment "A filter that changes the phase relationship between frequency components." .
lv2:EQPlugin
a rdfs:Class ,
owl:Class ;
rdfs:subClassOf lv2:FilterPlugin ;
- rdfs:label "Equaliser Plugin" ;
+ rdfs:label "EQ Plugin" ;
rdfs:comment "A plugin that adjusts the balance between frequency components." .
lv2:ParaEQPlugin
diff --git a/lv2/core/manifest.ttl b/lv2/core.lv2/manifest.ttl
index 179076d..26c10b6 100644
--- a/lv2/core/manifest.ttl
+++ b/lv2/core.lv2/manifest.ttl
@@ -5,7 +5,7 @@
<http://lv2plug.in/ns/lv2core>
a lv2:Specification ;
lv2:minorVersion 18 ;
- lv2:microVersion 1 ;
+ lv2:microVersion 5 ;
rdfs:seeAlso <lv2core.ttl> .
<http://lv2plug.in/ns/lv2>
diff --git a/lv2/core/meta.ttl b/lv2/core.lv2/meta.ttl
index 5d646e5..f51da18 100644
--- a/lv2/core/meta.ttl
+++ b/lv2/core.lv2/meta.ttl
@@ -34,6 +34,62 @@ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH R
meta:kfoltman ,
meta:paniq ;
doap:release [
+ doap:revision "1.18.7" ;
+ doap:created "2022-08-04" ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "lv2specgen: Fix installed data paths."
+ ] , [
+ rdfs:label "Fix documentation build with meson 0.56.2."
+ ] , [
+ rdfs:label "Fix lv2.h missing from installation."
+ ] , [
+ rdfs:label "Fix documentation build with Python 3.7."
+ ] , [
+ rdfs:label "eg-midigate: Fix output timing."
+ ] , [
+ rdfs:label "eg-sampler: Add resampling via libsamplerate."
+ ] , [
+ rdfs:label "eg-sampler: Fix potentially corrupt notification events."
+ ]
+ ]
+ ] , [
+ doap:revision "1.18.6" ;
+ doap:created "2022-07-07" ;
+ doap:file-release <http://lv2plug.in/spec/lv2-1.18.6.tar.bz2> ;
+ dcs:blame <http://drobilla.net/drobilla#me> ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "Fix or avoid new compiler and tool warnings."
+ ] , [
+ rdfs:label "Add dark mode style for documentation."
+ ] , [
+ rdfs:label "Clean up and modernize Python support code."
+ ] , [
+ rdfs:label "Remove archaic properties from foaf vocabulary."
+ ] , [
+ rdfs:label "Replace canonical dcs ontology with a minimal version for LV2."
+ ] , [
+ rdfs:label "Switch to Meson build system."
+ ] , [
+ rdfs:label "Separate API headers from data."
+ ] , [
+ rdfs:label "Rearrange source tree to be directly usable by dependants."
+ ]
+ ]
+ ] , [
+ doap:revision "1.18.4" ;
+ doap:created "2022-05-26" ;
+ doap:file-release <http://lv2plug.in/spec/lv2-1.18.4.tar.bz2> ;
+ dcs:blame <http://drobilla.net/drobilla#me> ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "Fix spelling errors."
+ ] , [
+ rdfs:label "Fix build issues with newer toolchains."
+ ]
+ ]
+ ] , [
doap:revision "1.18.2" ;
doap:created "2021-01-07" ;
doap:file-release <http://lv2plug.in/spec/lv2-1.18.2.tar.bz2> ;
diff --git a/lv2/core/people.ttl b/lv2/core.lv2/people.ttl
index 52d0384..52d0384 100644
--- a/lv2/core/people.ttl
+++ b/lv2/core.lv2/people.ttl
diff --git a/lv2/data-access/data-access.meta.ttl b/lv2/data-access.lv2/data-access.meta.ttl
index 3184110..822b28c 100644
--- a/lv2/data-access/data-access.meta.ttl
+++ b/lv2/data-access.lv2/data-access.meta.ttl
@@ -7,7 +7,6 @@
<http://lv2plug.in/ns/ext/data-access>
a doap:Project ;
- rdfs:seeAlso <data-access.h> ;
doap:license <http://opensource.org/licenses/isc> ;
doap:name "LV2 Data Access" ;
doap:shortdesc "Provides access to plugin extension data." ;
diff --git a/lv2/data-access/data-access.ttl b/lv2/data-access.lv2/data-access.ttl
index 0185cd0..b0dc6f4 100644
--- a/lv2/data-access/data-access.ttl
+++ b/lv2/data-access.lv2/data-access.ttl
@@ -6,6 +6,5 @@
a lv2:Feature ;
rdfs:label "data access" ;
rdfs:comment "A feature that provides access to plugin extension data." ;
- rdfs:seeAlso <data-access.h> ,
- <data-access.meta.ttl> .
+ rdfs:seeAlso <data-access.meta.ttl> .
diff --git a/lv2/data-access/manifest.ttl b/lv2/data-access.lv2/manifest.ttl
index 9585a5e..9585a5e 100644
--- a/lv2/data-access/manifest.ttl
+++ b/lv2/data-access.lv2/manifest.ttl
diff --git a/lv2/dynmanifest/dynmanifest.meta.ttl b/lv2/dynmanifest.lv2/dynmanifest.meta.ttl
index 4e66d98..4e66d98 100644
--- a/lv2/dynmanifest/dynmanifest.meta.ttl
+++ b/lv2/dynmanifest.lv2/dynmanifest.meta.ttl
diff --git a/lv2/dynmanifest/dynmanifest.ttl b/lv2/dynmanifest.lv2/dynmanifest.ttl
index 4e2e830..b46d694 100644
--- a/lv2/dynmanifest/dynmanifest.ttl
+++ b/lv2/dynmanifest.lv2/dynmanifest.ttl
@@ -9,8 +9,7 @@
a owl:Ontology ;
rdfs:label "LV2 Dyn Manifest" ;
rdfs:comment "Support for dynamic manifest data generation." ;
- rdfs:seeAlso <dynmanifest.h> ,
- <dynmanifest.meta.ttl> .
+ rdfs:seeAlso <dynmanifest.meta.ttl> .
dman:DynManifest
a rdfs:Class ;
diff --git a/lv2/dynmanifest/manifest.ttl b/lv2/dynmanifest.lv2/manifest.ttl
index db27a73..db27a73 100644
--- a/lv2/dynmanifest/manifest.ttl
+++ b/lv2/dynmanifest.lv2/manifest.ttl
diff --git a/lv2/event/event.meta.ttl b/lv2/event.lv2/event.meta.ttl
index 05476d8..e9c26bc 100644
--- a/lv2/event/event.meta.ttl
+++ b/lv2/event.lv2/event.meta.ttl
@@ -14,6 +14,16 @@
doap:developer <http://drobilla.net/drobilla#me> ,
<http://lv2plug.in/ns/meta#larsl> ;
doap:release [
+ doap:revision "1.14" ;
+ doap:created "2022-05-26" ;
+ doap:file-release <http://lv2plug.in/spec/lv2-1.18.4.tar.bz2> ;
+ dcs:blame <http://drobilla.net/drobilla#me> ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "Fix spelling errors."
+ ]
+ ]
+ ] , [
doap:revision "1.12" ;
doap:created "2014-08-08" ;
doap:file-release <http://lv2plug.in/spec/lv2-1.10.0.tar.bz2> ;
diff --git a/lv2/event/event.ttl b/lv2/event.lv2/event.ttl
index 119e606..2d871f6 100644
--- a/lv2/event/event.ttl
+++ b/lv2/event.lv2/event.ttl
@@ -9,9 +9,7 @@
owl:deprecated true ;
rdfs:label "LV2 Event" ;
rdfs:comment "A port-based real-time generic event interface." ;
- rdfs:seeAlso <event.h> ,
- <event-helpers.h> ,
- <event.meta.ttl> ;
+ rdfs:seeAlso <event.meta.ttl> ;
owl:imports <http://lv2plug.in/ns/lv2core> .
ev:EventPort
diff --git a/lv2/event/manifest.ttl b/lv2/event.lv2/manifest.ttl
index 8581a6e..230fe73 100644
--- a/lv2/event/manifest.ttl
+++ b/lv2/event.lv2/manifest.ttl
@@ -4,6 +4,6 @@
<http://lv2plug.in/ns/ext/event>
a lv2:Specification ;
lv2:minorVersion 1 ;
- lv2:microVersion 13 ;
+ lv2:microVersion 14 ;
rdfs:seeAlso <event.ttl> .
diff --git a/lv2/instance-access/instance-access.meta.ttl b/lv2/instance-access.lv2/instance-access.meta.ttl
index 875e2f8..875e2f8 100644
--- a/lv2/instance-access/instance-access.meta.ttl
+++ b/lv2/instance-access.lv2/instance-access.meta.ttl
diff --git a/lv2/instance-access/instance-access.ttl b/lv2/instance-access.lv2/instance-access.ttl
index 085ae37..637f4e0 100644
--- a/lv2/instance-access/instance-access.ttl
+++ b/lv2/instance-access.lv2/instance-access.ttl
@@ -6,6 +6,5 @@
a lv2:Feature ;
rdfs:label "instance access" ;
rdfs:comment "A feature that provides access to a plugin instance." ;
- rdfs:seeAlso <instance-access.h> ,
- <instance-access.meta.ttl> .
+ rdfs:seeAlso <instance-access.meta.ttl> .
diff --git a/lv2/instance-access/manifest.ttl b/lv2/instance-access.lv2/manifest.ttl
index e6c8810..e6c8810 100644
--- a/lv2/instance-access/manifest.ttl
+++ b/lv2/instance-access.lv2/manifest.ttl
diff --git a/lv2/log/log.meta.ttl b/lv2/log.lv2/log.meta.ttl
index 87cff43..87cff43 100644
--- a/lv2/log/log.meta.ttl
+++ b/lv2/log.lv2/log.meta.ttl
diff --git a/lv2/log/log.ttl b/lv2/log.lv2/log.ttl
index a8c4236..0b334ed 100644
--- a/lv2/log/log.ttl
+++ b/lv2/log.lv2/log.ttl
@@ -9,8 +9,7 @@
a owl:Ontology ;
rdfs:label "LV2 Log" ;
rdfs:comment "A feature for writing log messages." ;
- rdfs:seeAlso <log.h> ,
- <log.meta.ttl> ;
+ rdfs:seeAlso <log.meta.ttl> ;
owl:imports <http://lv2plug.in/ns/lv2core> .
log:Entry
diff --git a/lv2/log/manifest.ttl b/lv2/log.lv2/manifest.ttl
index bcaeff3..bcaeff3 100644
--- a/lv2/log/manifest.ttl
+++ b/lv2/log.lv2/manifest.ttl
diff --git a/lv2/midi/manifest.ttl b/lv2/midi.lv2/manifest.ttl
index f141936..f141936 100644
--- a/lv2/midi/manifest.ttl
+++ b/lv2/midi.lv2/manifest.ttl
diff --git a/lv2/midi/midi.meta.ttl b/lv2/midi.lv2/midi.meta.ttl
index 7efdb01..7efdb01 100644
--- a/lv2/midi/midi.meta.ttl
+++ b/lv2/midi.lv2/midi.meta.ttl
diff --git a/lv2/midi/midi.ttl b/lv2/midi.lv2/midi.ttl
index 81f3495..4a0e8c9 100644
--- a/lv2/midi/midi.ttl
+++ b/lv2/midi.lv2/midi.ttl
@@ -11,8 +11,7 @@
a owl:Ontology ;
rdfs:label "LV2 MIDI" ;
rdfs:comment "A normalised definition of raw MIDI." ;
- rdfs:seeAlso <midi.h> ,
- <midi.meta.ttl> .
+ rdfs:seeAlso <midi.meta.ttl> .
midi:ActiveSense
a rdfs:Class ;
diff --git a/lv2/morph/manifest.ttl b/lv2/morph.lv2/manifest.ttl
index 7c85cfd..7c85cfd 100644
--- a/lv2/morph/manifest.ttl
+++ b/lv2/morph.lv2/manifest.ttl
diff --git a/lv2/morph/morph.meta.ttl b/lv2/morph.lv2/morph.meta.ttl
index c247783..c247783 100644
--- a/lv2/morph/morph.meta.ttl
+++ b/lv2/morph.lv2/morph.meta.ttl
diff --git a/lv2/morph/morph.ttl b/lv2/morph.lv2/morph.ttl
index a771e03..9b8ef51 100644
--- a/lv2/morph/morph.ttl
+++ b/lv2/morph.lv2/morph.ttl
@@ -12,8 +12,7 @@
a owl:Ontology ;
rdfs:label "LV2 Morph" ;
rdfs:comment "Ports that can dynamically change type." ;
- rdfs:seeAlso <morph.h> ,
- <morph.meta.ttl> ;
+ rdfs:seeAlso <morph.meta.ttl> ;
owl:imports <http://lv2plug.in/ns/lv2core> .
morph:MorphPort
diff --git a/lv2/options/manifest.ttl b/lv2/options.lv2/manifest.ttl
index 18db448..18db448 100644
--- a/lv2/options/manifest.ttl
+++ b/lv2/options.lv2/manifest.ttl
diff --git a/lv2/options/options.meta.ttl b/lv2/options.lv2/options.meta.ttl
index 838b0b9..838b0b9 100644
--- a/lv2/options/options.meta.ttl
+++ b/lv2/options.lv2/options.meta.ttl
diff --git a/lv2/options/options.ttl b/lv2/options.lv2/options.ttl
index 78defef..5f9fcc9 100644
--- a/lv2/options/options.ttl
+++ b/lv2/options.lv2/options.ttl
@@ -9,8 +9,7 @@
a owl:Ontology ;
rdfs:label "LV2 Options" ;
rdfs:comment "Runtime options for LV2 plugins and UIs." ;
- rdfs:seeAlso <options.h> ,
- <options.meta.ttl> ;
+ rdfs:seeAlso <options.meta.ttl> ;
owl:imports <http://lv2plug.in/ns/lv2core> .
opts:Option
diff --git a/lv2/parameters/manifest.ttl b/lv2/parameters.lv2/manifest.ttl
index 57f5d2e..57f5d2e 100644
--- a/lv2/parameters/manifest.ttl
+++ b/lv2/parameters.lv2/manifest.ttl
diff --git a/lv2/parameters/parameters.meta.ttl b/lv2/parameters.lv2/parameters.meta.ttl
index 9d7c623..9d7c623 100644
--- a/lv2/parameters/parameters.meta.ttl
+++ b/lv2/parameters.lv2/parameters.meta.ttl
diff --git a/lv2/parameters/parameters.ttl b/lv2/parameters.lv2/parameters.ttl
index 9987812..9987812 100644
--- a/lv2/parameters/parameters.ttl
+++ b/lv2/parameters.lv2/parameters.ttl
diff --git a/lv2/patch/manifest.ttl b/lv2/patch.lv2/manifest.ttl
index 90419bb..4bf9cfb 100644
--- a/lv2/patch/manifest.ttl
+++ b/lv2/patch.lv2/manifest.ttl
@@ -4,6 +4,6 @@
<http://lv2plug.in/ns/ext/patch>
a lv2:Specification ;
lv2:minorVersion 2 ;
- lv2:microVersion 9 ;
+ lv2:microVersion 10 ;
rdfs:seeAlso <patch.ttl> .
diff --git a/lv2/patch/patch.meta.ttl b/lv2/patch.lv2/patch.meta.ttl
index 53cbdc0..12cb6c6 100644
--- a/lv2/patch/patch.meta.ttl
+++ b/lv2/patch.lv2/patch.meta.ttl
@@ -13,6 +13,20 @@
doap:name "LV2 Patch" ;
doap:shortdesc "A protocol for accessing and manipulating properties." ;
doap:release [
+ doap:revision "2.10" ;
+ doap:created "2022-05-26" ;
+ doap:file-release <http://lv2plug.in/spec/lv2-1.18.4.tar.bz2> ;
+ dcs:blame <http://drobilla.net/drobilla#me> ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "Fix spelling errors."
+ ] , [
+ rdfs:label "Make the type of patch:wildcard more precise."
+ ] , [
+ rdfs:label "Fix type and range of patch:value."
+ ]
+ ]
+ ] , [
doap:revision "2.8" ;
doap:created "2020-04-26" ;
doap:file-release <http://lv2plug.in/spec/lv2-1.18.0.tar.bz2> ;
diff --git a/lv2/patch/patch.ttl b/lv2/patch.lv2/patch.ttl
index c7f6d76..33d04d1 100644
--- a/lv2/patch/patch.ttl
+++ b/lv2/patch.lv2/patch.ttl
@@ -7,8 +7,7 @@
<http://lv2plug.in/ns/ext/patch>
a owl:Ontology ;
- rdfs:seeAlso <patch.h> ,
- <patch.meta.ttl> ;
+ rdfs:seeAlso <patch.meta.ttl> ;
rdfs:label "LV2 Patch" ;
rdfs:comment "A protocol for accessing and manipulating properties." .
diff --git a/lv2/port-groups/manifest.ttl b/lv2/port-groups.lv2/manifest.ttl
index a887cb0..a887cb0 100644
--- a/lv2/port-groups/manifest.ttl
+++ b/lv2/port-groups.lv2/manifest.ttl
diff --git a/lv2/port-groups/port-groups.meta.ttl b/lv2/port-groups.lv2/port-groups.meta.ttl
index 67408ec..67408ec 100644
--- a/lv2/port-groups/port-groups.meta.ttl
+++ b/lv2/port-groups.lv2/port-groups.meta.ttl
diff --git a/lv2/port-groups/port-groups.ttl b/lv2/port-groups.lv2/port-groups.ttl
index 5173aa0..2806821 100644
--- a/lv2/port-groups/port-groups.ttl
+++ b/lv2/port-groups.lv2/port-groups.ttl
@@ -21,7 +21,7 @@ pg:Group
owl:cardinality 1 ;
rdfs:comment "A Group MUST have exactly one string lv2:symbol."
] ;
- rdfs:comment "A set of ports that are logicaly grouped together." .
+ rdfs:comment "A set of ports that are logically grouped together." .
pg:InputGroup
a rdfs:Class ;
diff --git a/lv2/port-props/manifest.ttl b/lv2/port-props.lv2/manifest.ttl
index 45f598d..45f598d 100644
--- a/lv2/port-props/manifest.ttl
+++ b/lv2/port-props.lv2/manifest.ttl
diff --git a/lv2/port-props/port-props.meta.ttl b/lv2/port-props.lv2/port-props.meta.ttl
index 7077e4b..7077e4b 100644
--- a/lv2/port-props/port-props.meta.ttl
+++ b/lv2/port-props.lv2/port-props.meta.ttl
diff --git a/lv2/port-props/port-props.ttl b/lv2/port-props.lv2/port-props.ttl
index ea25c6b..ea25c6b 100644
--- a/lv2/port-props/port-props.ttl
+++ b/lv2/port-props.lv2/port-props.ttl
diff --git a/lv2/presets/manifest.ttl b/lv2/presets.lv2/manifest.ttl
index b9cacf5..b9cacf5 100644
--- a/lv2/presets/manifest.ttl
+++ b/lv2/presets.lv2/manifest.ttl
diff --git a/lv2/presets/presets.meta.ttl b/lv2/presets.lv2/presets.meta.ttl
index 8ff25c1..8ff25c1 100644
--- a/lv2/presets/presets.meta.ttl
+++ b/lv2/presets.lv2/presets.meta.ttl
diff --git a/lv2/presets/presets.ttl b/lv2/presets.lv2/presets.ttl
index 60189ea..60189ea 100644
--- a/lv2/presets/presets.ttl
+++ b/lv2/presets.lv2/presets.ttl
diff --git a/lv2/resize-port/manifest.ttl b/lv2/resize-port.lv2/manifest.ttl
index 9fae8b8..9fae8b8 100644
--- a/lv2/resize-port/manifest.ttl
+++ b/lv2/resize-port.lv2/manifest.ttl
diff --git a/lv2/resize-port/resize-port.meta.ttl b/lv2/resize-port.lv2/resize-port.meta.ttl
index d44620c..d44620c 100644
--- a/lv2/resize-port/resize-port.meta.ttl
+++ b/lv2/resize-port.lv2/resize-port.meta.ttl
diff --git a/lv2/resize-port/resize-port.ttl b/lv2/resize-port.lv2/resize-port.ttl
index a6712e7..6f42c8f 100644
--- a/lv2/resize-port/resize-port.ttl
+++ b/lv2/resize-port.lv2/resize-port.ttl
@@ -9,8 +9,7 @@
a owl:Ontology ;
rdfs:label "LV2 Resize Port" ;
rdfs:comment "Dynamically sized LV2 port buffers." ;
- rdfs:seeAlso <resize-port.h> ,
- <resize-port.meta.ttl> ;
+ rdfs:seeAlso <resize-port.meta.ttl> ;
owl:imports <http://lv2plug.in/ns/lv2core> .
rsz:resize
diff --git a/lv2/state/manifest.ttl b/lv2/state.lv2/manifest.ttl
index 67beca1..e56c4e5 100644
--- a/lv2/state/manifest.ttl
+++ b/lv2/state.lv2/manifest.ttl
@@ -4,6 +4,6 @@
<http://lv2plug.in/ns/ext/state>
a lv2:Specification ;
lv2:minorVersion 2 ;
- lv2:microVersion 9 ;
+ lv2:microVersion 10 ;
rdfs:seeAlso <state.ttl> .
diff --git a/lv2/state/state.meta.ttl b/lv2/state.lv2/state.meta.ttl
index 271814c..cebe0ac 100644
--- a/lv2/state/state.meta.ttl
+++ b/lv2/state.lv2/state.meta.ttl
@@ -15,6 +15,16 @@
<http://drobilla.net/drobilla#me> ;
doap:maintainer <http://drobilla.net/drobilla#me> ;
doap:release [
+ doap:revision "2.10" ;
+ doap:created "2022-05-26" ;
+ doap:file-release <http://lv2plug.in/spec/lv2-1.18.4.tar.bz2> ;
+ dcs:blame <http://drobilla.net/drobilla#me> ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "Fix spelling errors."
+ ]
+ ]
+ ] , [
doap:revision "2.8" ;
doap:created "2021-01-07" ;
doap:file-release <http://lv2plug.in/spec/lv2-1.18.2.tar.bz2> ;
diff --git a/lv2/state/state.ttl b/lv2/state.lv2/state.ttl
index 48537c8..463fdb9 100644
--- a/lv2/state/state.ttl
+++ b/lv2/state.lv2/state.ttl
@@ -8,8 +8,7 @@
a owl:Ontology ;
rdfs:label "LV2 State" ;
rdfs:comment "An interface for LV2 plugins to save and restore state." ;
- rdfs:seeAlso <state.h> ,
- <state.meta.ttl> ;
+ rdfs:seeAlso <state.meta.ttl> ;
owl:imports <http://lv2plug.in/ns/lv2core> .
state:interface
diff --git a/lv2/time/manifest.ttl b/lv2/time.lv2/manifest.ttl
index d80aa75..d80aa75 100644
--- a/lv2/time/manifest.ttl
+++ b/lv2/time.lv2/manifest.ttl
diff --git a/lv2/time/time.meta.ttl b/lv2/time.lv2/time.meta.ttl
index 2b99cb7..2b99cb7 100644
--- a/lv2/time/time.meta.ttl
+++ b/lv2/time.lv2/time.meta.ttl
diff --git a/lv2/time/time.ttl b/lv2/time.lv2/time.ttl
index a4085c6..f3da9b0 100644
--- a/lv2/time/time.ttl
+++ b/lv2/time.lv2/time.ttl
@@ -8,8 +8,7 @@
a owl:Ontology ;
rdfs:label "LV2 Time" ;
rdfs:comment "A vocabulary for describing musical time." ;
- rdfs:seeAlso <time.h> ,
- <time.meta.ttl> .
+ rdfs:seeAlso <time.meta.ttl> .
time:Time
a rdfs:Class ,
diff --git a/lv2/ui/manifest.ttl b/lv2/ui.lv2/manifest.ttl
index 304005a..d3b12b5 100644
--- a/lv2/ui/manifest.ttl
+++ b/lv2/ui.lv2/manifest.ttl
@@ -4,6 +4,6 @@
<http://lv2plug.in/ns/extensions/ui>
a lv2:Specification ;
lv2:minorVersion 2 ;
- lv2:microVersion 23 ;
+ lv2:microVersion 24 ;
rdfs:seeAlso <ui.ttl> .
diff --git a/lv2/ui/ui.meta.ttl b/lv2/ui.lv2/ui.meta.ttl
index 540dc4b..95336bf 100644
--- a/lv2/ui/ui.meta.ttl
+++ b/lv2/ui.lv2/ui.meta.ttl
@@ -15,6 +15,18 @@
doap:developer <http://lv2plug.in/ns/meta#larsl> ;
doap:maintainer <http://drobilla.net/drobilla#me> ;
doap:release [
+ doap:revision "2.24" ;
+ doap:created "2022-05-26" ;
+ doap:file-release <http://lv2plug.in/spec/lv2-1.18.4.tar.bz2> ;
+ dcs:blame <http://drobilla.net/drobilla#me> ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "Fix spelling errors."
+ ] , [
+ rdfs:label "Deprecate ui:resize."
+ ]
+ ]
+ ] , [
doap:revision "2.22" ;
doap:created "2020-04-26" ;
doap:file-release <http://lv2plug.in/spec/lv2-1.18.0.tar.bz2> ;
diff --git a/lv2/ui/ui.ttl b/lv2/ui.lv2/ui.ttl
index b355764..1c2e455 100644
--- a/lv2/ui/ui.ttl
+++ b/lv2/ui.lv2/ui.ttl
@@ -10,8 +10,7 @@
a owl:Ontology ;
rdfs:label "LV2 UI" ;
rdfs:comment "User interfaces for LV2 plugins." ;
- rdfs:seeAlso <ui.h> ,
- <ui.meta.ttl> ;
+ rdfs:seeAlso <ui.meta.ttl> ;
owl:imports <http://lv2plug.in/ns/lv2core> ,
<http://lv2plug.in/ns/ext/options> .
diff --git a/lv2/units/manifest.ttl b/lv2/units.lv2/manifest.ttl
index c6c9286..c6c9286 100644
--- a/lv2/units/manifest.ttl
+++ b/lv2/units.lv2/manifest.ttl
diff --git a/lv2/units/units.meta.ttl b/lv2/units.lv2/units.meta.ttl
index a857046..a857046 100644
--- a/lv2/units/units.meta.ttl
+++ b/lv2/units.lv2/units.meta.ttl
diff --git a/lv2/units/units.ttl b/lv2/units.lv2/units.ttl
index 959c063..21a1898 100644
--- a/lv2/units/units.ttl
+++ b/lv2/units.lv2/units.ttl
@@ -8,8 +8,7 @@
a owl:Ontology ;
rdfs:label "LV2 Units" ;
rdfs:comment "Units for LV2 values." ;
- rdfs:seeAlso <units.h> ,
- <units.meta.ttl> .
+ rdfs:seeAlso <units.meta.ttl> .
units:Unit
a rdfs:Class ,
diff --git a/lv2/uri-map/manifest.ttl b/lv2/uri-map.lv2/manifest.ttl
index a64e4fb..a64e4fb 100644
--- a/lv2/uri-map/manifest.ttl
+++ b/lv2/uri-map.lv2/manifest.ttl
diff --git a/lv2/uri-map/uri-map.meta.ttl b/lv2/uri-map.lv2/uri-map.meta.ttl
index acd1c26..acd1c26 100644
--- a/lv2/uri-map/uri-map.meta.ttl
+++ b/lv2/uri-map.lv2/uri-map.meta.ttl
diff --git a/lv2/uri-map/uri-map.ttl b/lv2/uri-map.lv2/uri-map.ttl
index bfb0d0b..7a7d6e3 100644
--- a/lv2/uri-map/uri-map.ttl
+++ b/lv2/uri-map.lv2/uri-map.ttl
@@ -9,6 +9,5 @@
owl:deprecated true ;
rdfs:label "LV2 URI Map" ;
rdfs:comment "A feature for mapping URIs to integers." ;
- rdfs:seeAlso <uri-map.h> ,
- <uri-map.meta.ttl> .
+ rdfs:seeAlso <uri-map.meta.ttl> .
diff --git a/lv2/urid/manifest.ttl b/lv2/urid.lv2/manifest.ttl
index 772e2b6..772e2b6 100644
--- a/lv2/urid/manifest.ttl
+++ b/lv2/urid.lv2/manifest.ttl
diff --git a/lv2/urid/urid.meta.ttl b/lv2/urid.lv2/urid.meta.ttl
index b2a74fa..b2a74fa 100644
--- a/lv2/urid/urid.meta.ttl
+++ b/lv2/urid.lv2/urid.meta.ttl
diff --git a/lv2/urid/urid.ttl b/lv2/urid.lv2/urid.ttl
index 53aa1e5..6ce666a 100644
--- a/lv2/urid/urid.ttl
+++ b/lv2/urid.lv2/urid.ttl
@@ -7,8 +7,7 @@
a owl:Ontology ;
rdfs:label "LV2 URID" ;
rdfs:comment "Features for mapping URIs to and from integers." ;
- rdfs:seeAlso <urid.h> ,
- <urid.meta.ttl> ;
+ rdfs:seeAlso <urid.meta.ttl> ;
owl:imports <http://lv2plug.in/ns/lv2core> .
urid:map
diff --git a/lv2/worker/manifest.ttl b/lv2/worker.lv2/manifest.ttl
index 692720d..692720d 100644
--- a/lv2/worker/manifest.ttl
+++ b/lv2/worker.lv2/manifest.ttl
diff --git a/lv2/worker/worker.meta.ttl b/lv2/worker.lv2/worker.meta.ttl
index 2fc51bc..2fc51bc 100644
--- a/lv2/worker/worker.meta.ttl
+++ b/lv2/worker.lv2/worker.meta.ttl
diff --git a/lv2/worker/worker.ttl b/lv2/worker.lv2/worker.ttl
index cb8a81a..581be71 100644
--- a/lv2/worker/worker.ttl
+++ b/lv2/worker.lv2/worker.ttl
@@ -10,8 +10,7 @@
rdfs:label "LV2 Worker" ;
rdfs:comment "Support for doing non-realtime work in plugins." ;
owl:imports <http://lv2plug.in/ns/lv2core> ;
- rdfs:seeAlso <worker.h> ,
- <worker.meta.ttl> .
+ rdfs:seeAlso <worker.meta.ttl> .
work:interface
a lv2:ExtensionData ;
diff --git a/lv2specgen/DTD/xhtml-rdfa-1.dtd b/lv2specgen/DTD/xhtml-rdfa-1.dtd
index 26ed117..bd3479e 100644
--- a/lv2specgen/DTD/xhtml-rdfa-1.dtd
+++ b/lv2specgen/DTD/xhtml-rdfa-1.dtd
@@ -437,36 +437,18 @@
<!-- end of XHTML-RDFa DTD ................................................ -->
<!-- ....................................................................... -->
-<!-- Add xmlns attributes to validate lv2specgen output -->
-<!-- This is a pretty dirty hack, but avoids needing to write a bunch of code to
- mangle DTDs to appease validation -->
+<!-- Hack for lv2specgen: declare prefixes for the external vocabularies used
+ in LV2 (most of which are generally common for RDF), so RDFa in spec pages
+ can use prefixed names. This glaring separation-of-concerns violation
+ is... not nice, but neither is diving into the horrors of custom XML DTD
+ validation, so here we are.
+-->
-<!ATTLIST html xmlns:dc CDATA #IMPLIED>
-<!ATTLIST html xmlns:dct CDATA #IMPLIED>
+<!ATTLIST html xmlns:dcs CDATA #IMPLIED>
+<!ATTLIST html xmlns:dcterms CDATA #IMPLIED>
+<!ATTLIST html xmlns:doap CDATA #IMPLIED>
+<!ATTLIST html xmlns:foaf CDATA #IMPLIED>
+<!ATTLIST html xmlns:owl CDATA #IMPLIED>
<!ATTLIST html xmlns:rdf CDATA #IMPLIED>
<!ATTLIST html xmlns:rdfs CDATA #IMPLIED>
-
-<!ATTLIST html xmlns:atom CDATA #IMPLIED>
-<!ATTLIST html xmlns:bufsz CDATA #IMPLIED>
-<!ATTLIST html xmlns:da CDATA #IMPLIED>
-<!ATTLIST html xmlns:dman CDATA #IMPLIED>
-<!ATTLIST html xmlns:ev CDATA #IMPLIED>
-<!ATTLIST html xmlns:ia CDATA #IMPLIED>
-<!ATTLIST html xmlns:log CDATA #IMPLIED>
-<!ATTLIST html xmlns:lv2 CDATA #IMPLIED>
-<!ATTLIST html xmlns:midi CDATA #IMPLIED>
-<!ATTLIST html xmlns:morph CDATA #IMPLIED>
-<!ATTLIST html xmlns:opts CDATA #IMPLIED>
-<!ATTLIST html xmlns:param CDATA #IMPLIED>
-<!ATTLIST html xmlns:patch CDATA #IMPLIED>
-<!ATTLIST html xmlns:pg CDATA #IMPLIED>
-<!ATTLIST html xmlns:pprops CDATA #IMPLIED>
-<!ATTLIST html xmlns:pset CDATA #IMPLIED>
-<!ATTLIST html xmlns:rsz CDATA #IMPLIED>
-<!ATTLIST html xmlns:state CDATA #IMPLIED>
-<!ATTLIST html xmlns:time CDATA #IMPLIED>
-<!ATTLIST html xmlns:ui CDATA #IMPLIED>
-<!ATTLIST html xmlns:umap CDATA #IMPLIED>
-<!ATTLIST html xmlns:units CDATA #IMPLIED>
-<!ATTLIST html xmlns:urid CDATA #IMPLIED>
-<!ATTLIST html xmlns:work CDATA #IMPLIED>
+<!ATTLIST html xmlns:xsd CDATA #IMPLIED>
diff --git a/lv2specgen/lv2docgen.py b/lv2specgen/lv2docgen.py
index 23a239d..c5e13a7 100755
--- a/lv2specgen/lv2docgen.py
+++ b/lv2specgen/lv2docgen.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# lv2docgen, a documentation generator for LV2 plugins
@@ -20,63 +20,74 @@ import errno
import os
import sys
-__date__ = '2012-03-27'
-__version__ = '0.0.0'
-__authors__ = 'David Robillard'
-__license__ = 'ISC License <http://www.opensource.org/licenses/isc>'
-__contact__ = 'devel@lists.lv2plug.in'
+__date__ = "2012-03-27"
+__version__ = "0.0.0"
+__authors__ = "David Robillard"
+__license__ = "ISC License <http://www.opensource.org/licenses/isc>"
+__contact__ = "devel@lists.lv2plug.in"
try:
import rdflib
except ImportError:
- sys.exit('Error importing rdflib')
+ sys.exit("Error importing rdflib")
+
+doap = rdflib.Namespace("http://usefulinc.com/ns/doap#")
+lv2 = rdflib.Namespace("http://lv2plug.in/ns/lv2core#")
+rdf = rdflib.Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
+rdfs = rdflib.Namespace("http://www.w3.org/2000/01/rdf-schema#")
-doap = rdflib.Namespace('http://usefulinc.com/ns/doap#')
-lv2 = rdflib.Namespace('http://lv2plug.in/ns/lv2core#')
-rdf = rdflib.Namespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#')
-rdfs = rdflib.Namespace('http://www.w3.org/2000/01/rdf-schema#')
def uri_to_path(uri):
- path = uri[uri.find(':'):]
+ first_colon = uri.find(":")
+ path = uri[first_colon:]
while not path[0].isalpha():
path = path[1:]
return path
+
def get_doc(model, subject):
comment = model.value(subject, rdfs.comment, None)
if comment:
return '<p class="content">%s</p>' % comment
- return ''
+ return ""
+
def port_doc(model, port):
name = model.value(port, lv2.name, None)
- comment = model.value(port, rdfs.comment, None)
html = '<div class="specterm"><h3>%s</h3>' % name
html += get_doc(model, port)
- html += '</div>'
+ html += "</div>"
return html
+
def plugin_doc(model, plugin, style_uri):
- uri = str(plugin)
+ uri = str(plugin)
name = model.value(plugin, doap.name, None)
- html = '''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
+ dtd = "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd"
+ html = """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" %s>
<html about="%s"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:lv2="http://lv2plug.in/ns/lv2core#"
- xml:lang="en">''' % uri
+ xml:lang="en">""" % (
+ uri,
+ dtd,
+ )
- html += '''<head>
+ html += """<head>
<title>%s</title>
<meta http-equiv="content-type" content="text/xhtml+xml; charset=utf-8" />
<meta name="generator" content="lv2docgen" />
<link href="%s" rel="stylesheet" type="text/css" />
</head>
- <body>''' % (name, style_uri)
+ <body>""" % (
+ name,
+ style_uri,
+ )
- html += '''
+ html += """
<!-- HEADER -->
<div id="header">
<h1 id="title">%s</h1>
@@ -85,44 +96,53 @@ def plugin_doc(model, plugin, style_uri):
<tr><th>Version</th><td>%s</td></tr>
</table>
</div>
-''' % (name, uri, uri, '0.0.0')
+""" % (
+ name,
+ uri,
+ uri,
+ "0.0.0",
+ )
html += get_doc(model, plugin)
- ports_html = ''
+ ports_html = ""
for p in model.triples([plugin, lv2.port, None]):
ports_html += port_doc(model, p[2])
if len(ports_html):
- html += '''
+ html += (
+ """
<h2 class="sec">Ports</h2>
<div class="content">
%s
- </div>''' % ports_html
+ </div>"""
+ % ports_html
+ )
- html += ' </body></html>'
+ html += " </body></html>"
return html
-if __name__ == '__main__':
- 'LV2 plugin documentation generator'
+
+if __name__ == "__main__":
+ "LV2 plugin documentation generator"
if len(sys.argv) < 2:
- print('Usage: %s OUTDIR FILE...' % sys.argv[0])
+ print("Usage: %s OUTDIR FILE..." % sys.argv[0])
sys.exit(1)
outdir = sys.argv[1]
files = sys.argv[2:]
model = rdflib.ConjunctiveGraph()
for f in files:
- model.parse(f, format='n3')
+ model.parse(f, format="n3")
- style_uri = os.path.abspath(os.path.join(outdir, 'style.css'))
+ style_uri = os.path.abspath(os.path.join(outdir, "style.css"))
for p in model.triples([None, rdf.type, lv2.Plugin]):
plugin = p[0]
html = plugin_doc(model, plugin, style_uri)
path = uri_to_path(plugin)
- outpath = os.path.join(outdir, path + '.html')
+ outpath = os.path.join(outdir, path + ".html")
try:
os.makedirs(os.path.dirname(outpath))
except OSError:
@@ -132,7 +152,6 @@ if __name__ == '__main__':
else:
raise
- print('Writing <%s> documentation to %s' % (plugin, outpath))
- out = open(outpath, 'w')
- out.write(html)
- out.close()
+ print("Writing <%s> documentation to %s" % (plugin, outpath))
+ with open(outpath, "w") as out:
+ out.write(html)
diff --git a/lv2specgen/lv2specgen.py b/lv2specgen/lv2specgen.py
index 14c88c3..5f06af3 100755
--- a/lv2specgen/lv2specgen.py
+++ b/lv2specgen/lv2specgen.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# lv2specgen, a documentation generator for LV2 specifications.
@@ -86,20 +86,14 @@ spec_pre = None
spec_bundle = None
specgendir = None
ns_list = {
+ "http://ontologi.es/doap-changeset#": "dcs",
+ "http://purl.org/dc/terms/": "dcterms",
+ "http://usefulinc.com/ns/doap#": "doap",
+ "http://xmlns.com/foaf/0.1/": "foaf",
+ "http://www.w3.org/2002/07/owl#": "owl",
"http://www.w3.org/1999/02/22-rdf-syntax-ns#": "rdf",
"http://www.w3.org/2000/01/rdf-schema#": "rdfs",
- "http://www.w3.org/2002/07/owl#": "owl",
"http://www.w3.org/2001/XMLSchema#": "xsd",
- "http://rdfs.org/sioc/ns#": "sioc",
- "http://xmlns.com/foaf/0.1/": "foaf",
- "http://purl.org/dc/elements/1.1/": "dc",
- "http://purl.org/dc/terms/": "dct",
- "http://purl.org/rss/1.0/modules/content/": "content",
- "http://www.w3.org/2003/01/geo/wgs84_pos#": "geo",
- "http://www.w3.org/2004/02/skos/core#": "skos",
- "http://lv2plug.in/ns/lv2core#": "lv2",
- "http://usefulinc.com/ns/doap#": "doap",
- "http://ontologi.es/doap-changeset#": "dcs",
}
rdf = rdflib.Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
@@ -154,7 +148,7 @@ def isLiteral(n):
def niceName(uri):
global spec_bundle
if uri.startswith(spec_ns_str):
- return uri[len(spec_ns_str) :]
+ return uri.replace(spec_ns_str, "")
elif uri == str(rdfs.seeAlso):
return "See also"
@@ -166,8 +160,6 @@ def niceName(uri):
if pref in ns_list:
return ns_list.get(pref, pref) + ":" + rez.group(2)
else:
- print("warning: prefix %s not in ns list:" % pref)
- print(ns_list)
return uri
@@ -239,9 +231,9 @@ def linkifyVocabIdentifiers(m, string, classlist, proplist, instalist):
def prettifyHtml(m, markup, subject, classlist, proplist, instalist):
# Syntax highlight all C code
if have_pygments:
- code_rgx = re.compile('<pre class="c-code">(.*?)</pre>', re.DOTALL)
+ code_re = re.compile('<pre class="c-code">(.*?)</pre>', re.DOTALL)
while True:
- code = code_rgx.search(markup)
+ code = code_re.search(markup)
if not code:
break
match_str = xml.sax.saxutils.unescape(code.group(1))
@@ -250,15 +242,13 @@ def prettifyHtml(m, markup, subject, classlist, proplist, instalist):
pygments.lexers.CLexer(),
pygments.formatters.HtmlFormatter(),
)
- markup = code_rgx.sub(code_str, markup, 1)
+ markup = code_re.sub(code_str, markup, 1)
# Syntax highlight all Turtle code
if have_pygments:
- code_rgx = re.compile(
- '<pre class="turtle-code">(.*?)</pre>', re.DOTALL
- )
+ code_re = re.compile('<pre class="turtle-code">(.*?)</pre>', re.DOTALL)
while True:
- code = code_rgx.search(markup)
+ code = code_re.search(markup)
if not code:
break
match_str = xml.sax.saxutils.unescape(code.group(1))
@@ -267,7 +257,7 @@ def prettifyHtml(m, markup, subject, classlist, proplist, instalist):
pygments.lexers.rdf.TurtleLexer(),
pygments.formatters.HtmlFormatter(),
)
- markup = code_rgx.sub(code_str, markup, 1)
+ markup = code_re.sub(code_str, markup, 1)
# Add links to code documentation for identifiers
markup = linkifyCodeIdentifiers(markup)
@@ -768,12 +758,15 @@ def docTerms(category, list, m, classlist, proplist, instalist):
doc = ""
for term in list:
if not term.startswith(spec_ns_str):
- sys.stderr.write("warning: Skipping external term `%s'" % term)
continue
t = termName(m, term)
curie = term.split(spec_ns_str[-1])[1]
- doc += '<div class="specterm" id="%s" about="%s">' % (t, term)
+ if t:
+ doc += '<div class="specterm" id="%s" about="%s">' % (t, term)
+ else:
+ doc += '<div class="specterm" about="%s">' % term
+
doc += '<h3><a href="#%s">%s</a></h3>' % (getAnchor(term), curie)
doc += '<span class="spectermtype">%s</span>' % category
@@ -830,7 +823,7 @@ def getShortName(uri):
def getAnchor(uri):
uri = str(uri)
if uri.startswith(spec_ns_str):
- return uri[len(spec_ns_str) :].replace("/", "_")
+ return uri.replace(spec_ns_str, "").replace("/", "_")
else:
return getShortName(uri)
@@ -861,7 +854,7 @@ def buildIndex(m, classlist, proplist, instalist=None):
local_subclass = False
for p in findStatements(m, c, rdfs.subClassOf, None):
parent = str(p[2])
- if parent[0 : len(spec_ns_str)] == spec_ns_str:
+ if parent.startswith(spec_ns_str):
local_subclass = True
if local_subclass:
continue
@@ -1020,17 +1013,14 @@ def specAuthors(m, subject):
for d in sorted(dev):
if not first:
devdoc += ", "
- devdoc += (
- '<span class="author" property="doap:developer">%s</span>' % d
- )
+
+ devdoc += f'<span class="author" property="doap:developer">{d}</span>'
first = False
if len(dev) == 1:
- doc += (
- '<tr><th class="metahead">Developer</th><td>%s</td></tr>' % devdoc
- )
+ doc += f'<tr><th class="metahead">Developer</th><td>{devdoc}</td></tr>'
elif len(dev) > 0:
doc += (
- '<tr><th class="metahead">Developers</th><td>%s</td></tr>' % devdoc
+ f'<tr><th class="metahead">Developers</th><td>{devdoc}</td></tr>'
)
maintdoc = ""
@@ -1038,20 +1028,14 @@ def specAuthors(m, subject):
for m in sorted(maint):
if not first:
maintdoc += ", "
+
maintdoc += (
- '<span class="author" property="doap:maintainer">%s</span>' % m
+ f'<span class="author" property="doap:maintainer">{m}</span>'
)
first = False
- if len(maint) == 1:
- doc += (
- '<tr><th class="metahead">Maintainer</th><td>%s</td></tr>'
- % maintdoc
- )
- elif len(maint) > 0:
- doc += (
- '<tr><th class="metahead">Maintainers</th><td>%s</td></tr>'
- % maintdoc
- )
+ if len(maint):
+ label = "Maintainer" if len(maint) == 1 else "Maintainers"
+ doc += f'<tr><th class="metahead">{label}</th><td>{maintdoc}</td></tr>'
return doc
@@ -1246,129 +1230,14 @@ def load_tags(path, docdir):
return linkmap
-def writeIndex(model, specloc, index_path, root_path, root_uri, online):
- # Get extension URI
- ext_node = model.value(None, rdf.type, lv2.Specification)
- if not ext_node:
- ext_node = model.value(None, rdf.type, owl.Ontology)
- if not ext_node:
- print("no extension found in %s" % bundle)
- sys.exit(1)
-
- ext = str(ext_node)
-
- # Get version
- minor = 0
- micro = 0
- try:
- minor = int(model.value(ext_node, lv2.minorVersion, None))
- micro = int(model.value(ext_node, lv2.microVersion, None))
- except Exception:
- print("warning: %s: failed to find version for %s" % (bundle, ext))
-
- # Get date
- date = None
- for r in model.triples([ext_node, doap.release, None]):
- revision = model.value(r[2], doap.revision, None)
- if str(revision) == ("%d.%d" % (minor, micro)):
- date = model.value(r[2], doap.created, None)
- break
-
- # Verify that this date is the latest
- if date is None:
- print("warning: %s has no doap:created date" % ext_node)
- else:
- for r in model.triples([ext_node, doap.release, None]):
- this_date = model.value(r[2], doap.created, None)
- if this_date is None:
- print(
- "warning: %s has no doap:created date"
- % (ext_node, minor, micro, date)
- )
- continue
-
- if this_date > date:
- print(
- "warning: %s revision %d.%d (%s) is not the latest release"
- % (ext_node, minor, micro, date)
- )
- break
-
- # Get name and short description
- name = model.value(ext_node, doap.name, None)
- shortdesc = model.value(ext_node, doap.shortdesc, None)
-
- # Chop 'LV2' prefix from name for cleaner index
- if name.startswith("LV2 "):
- name = name[4:]
-
- # Find relative link target
- if root_uri and ext_node.startswith(root_uri):
- target = ext_node[len(root_uri) :]
- else:
- target = os.path.relpath(ext_node, root_path)
-
- if not online:
- target += ".html"
-
- stem = os.path.splitext(os.path.basename(target))[0]
-
- # Specification (comment is to act as a sort key)
- row = '<tr><!-- %s --><td><a rel="rdfs:seeAlso" href="%s">%s</a></td>' % (
- b,
- target,
- name,
- )
-
- # API
- row += "<td>"
- row += '<a rel="rdfs:seeAlso" href="../doc/html/group__%s.html">%s</a>' % (
- stem,
- name,
- )
- row += "</td>"
-
- # Description
- if shortdesc:
- row += "<td>" + str(shortdesc) + "</td>"
- else:
- row += "<td></td>"
-
- # Version
- version_str = "%s.%s" % (minor, micro)
- if minor == 0 or (micro % 2 != 0):
- row += '<td><span style="color: red">' + version_str + "</span></td>"
- else:
- row += "<td>" + version_str + "</td>"
-
- # Status
- deprecated = model.value(ext_node, owl.deprecated, None)
- if minor == 0:
- row += '<td><span class="error">Experimental</span></td>'
- elif deprecated and str(deprecated[2]) != "false":
- row += '<td><span class="warning">Deprecated</span></td>'
- elif micro % 2 == 0:
- row += '<td><span class="success">Stable</span></td>'
-
- row += "</tr>"
-
- index = open(index_path, "w")
- index.write(row)
- index.close()
-
-
def specgen(
specloc,
- indir,
+ template_path,
style_uri,
docdir,
tags,
opts,
instances=False,
- root_link=None,
- index_path=None,
- root_path=None,
- root_uri=None,
):
"""The meat and potatoes: Everything starts here."""
@@ -1382,19 +1251,21 @@ def specgen(
global linkmap
spec_bundle = "file://%s/" % os.path.abspath(os.path.dirname(specloc))
- specgendir = os.path.abspath(indir)
# Template
- temploc = os.path.join(indir, "template.html")
- template = None
- f = open(temploc, "r")
- template = f.read()
- f.close()
+ with open(template_path, "r") as f:
+ template = f.read()
# Load code documentation link map from tags file
linkmap = load_tags(tags, docdir)
m = rdflib.ConjunctiveGraph()
+
+ # RDFLib adds its own prefixes, so kludge around "time" prefix conflict
+ m.namespace_manager.bind(
+ "time", rdflib.URIRef("http://lv2plug.in/ns/ext/time#"), replace=True
+ )
+
manifest_path = os.path.join(os.path.dirname(specloc), "manifest.ttl")
if os.path.exists(manifest_path):
m.parse(manifest_path, format="n3")
@@ -1490,8 +1361,6 @@ def specgen(
name = specProperty(m, spec, doap.name)
title = name
- if root_link:
- name = '<a href="%s">%s</a>' % (root_link, name)
template = template.replace("@TITLE@", title)
template = template.replace("@NAME@", name)
@@ -1500,15 +1369,9 @@ def specgen(
)
template = template.replace("@URI@", spec)
template = template.replace("@PREFIX@", spec_pre)
- if spec_pre == "lv2":
- template = template.replace("@XMLNS@", "")
- else:
- template = template.replace(
- "@XMLNS@", ' xmlns:%s="%s"' % (spec_pre, spec_ns_str)
- )
filename = os.path.basename(specloc)
- basename = filename[0 : filename.rfind(".")]
+ basename = os.path.splitext(filename)[0]
template = template.replace("@STYLE_URI@", style_uri)
template = template.replace("@PREFIXES@", str(prefixes_html))
@@ -1564,10 +1427,6 @@ def specgen(
template = template.replace("@DATE@", build_date.strftime("%F"))
template = template.replace("@TIME@", build_date.strftime("%F %H:%M UTC"))
- # Write index row
- if index_path is not None:
- writeIndex(m, specloc, index_path, root_path, root_uri, opts["online"])
-
# Validate complete output page
try:
oldcwd = os.getcwd()
@@ -1580,7 +1439,9 @@ def specgen(
etree.XMLParser(dtd_validation=True, no_network=True),
)
except Exception as e:
- sys.stderr.write("error: Validation failed for %s: %s" % (specloc, e))
+ sys.stderr.write(
+ "error: Validation failed for %s: %s\n" % (specloc, e)
+ )
finally:
os.chdir(oldcwd)
@@ -1589,10 +1450,9 @@ def specgen(
def save(path, text):
try:
- f = open(path, "w")
- f.write(text)
- f.flush()
- f.close()
+ with open(path, "w") as f:
+ f.write(text)
+ f.flush()
except Exception:
e = sys.exc_info()[1]
print('Error writing to file "' + path + '": ' + str(e))
@@ -1628,12 +1488,57 @@ def usage():
return "Usage: %s ONTOLOGY_TTL OUTPUT_HTML [OPTION]..." % script
+def _path_from_env(variable, default):
+ value = os.environ.get(variable)
+ return value if value and os.path.isabs(value) else default
+
+
+def _paths_from_env(variable, default):
+ paths = []
+ value = os.environ.get(variable)
+ if value:
+ paths = [p for p in value.split(os.pathsep) if os.path.isabs(p)]
+
+ return paths if paths else default
+
+
+def _data_dirs():
+ return _paths_from_env(
+ "XDG_DATA_DIRS", ["/usr/local/share/", "/usr/share/"]
+ )
+
+
if __name__ == "__main__":
"""Ontology specification generator tool"""
- indir = os.path.abspath(os.path.dirname(sys.argv[0]))
- if not os.path.exists(os.path.join(indir, "template.html")):
- indir = os.path.join(os.path.dirname(indir), "share", "lv2specgen")
+ data_dir = None
+ for d in _data_dirs():
+ path = os.path.join(d, "lv2specgen")
+ if (
+ os.path.exists(os.path.join(path, "template.html"))
+ and os.path.exists(os.path.join(path, "style.css"))
+ and os.path.exists(os.path.join(path, "pygments.css"))
+ ):
+ data_dir = path
+ break
+
+ if data_dir:
+ # Use installed files
+ specgendir = data_dir
+ default_template_path = os.path.join(data_dir, "template.html")
+ default_style_dir = data_dir
+ else:
+ script_path = os.path.realpath(__file__)
+ script_dir = os.path.dirname(os.path.realpath(__file__))
+ if os.path.exists(os.path.join(script_dir, "template.html")):
+ # Run from source repository
+ specgendir = script_dir
+ lv2_source_root = os.path.dirname(script_dir)
+ default_template_path = os.path.join(script_dir, "template.html")
+ default_style_dir = os.path.join(lv2_source_root, "doc", "style")
+ else:
+ sys.stderr.write("error: Unable to find lv2specgen data\n")
+ sys.exit(-2)
opt = optparse.OptionParser(
usage=usage(),
@@ -1652,11 +1557,18 @@ if __name__ == "__main__":
help="Mailing list info page address",
)
opt.add_option(
- "--template-dir",
+ "--template",
+ type="string",
+ dest="template",
+ default=default_template_path,
+ help="Template file for output page",
+ )
+ opt.add_option(
+ "--style-dir",
type="string",
- dest="template_dir",
- default=indir,
- help="Template directory",
+ dest="style_dir",
+ default=default_style_dir,
+ help="Stylesheet directory path",
)
opt.add_option(
"--style-uri",
@@ -1673,13 +1585,6 @@ if __name__ == "__main__":
help="Doxygen output directory",
)
opt.add_option(
- "--index",
- type="string",
- dest="index_path",
- default=None,
- help="Index row output file",
- )
- opt.add_option(
"--tags",
type="string",
dest="tags",
@@ -1687,22 +1592,6 @@ if __name__ == "__main__":
help="Doxygen tags file",
)
opt.add_option(
- "-r",
- "--root-path",
- type="string",
- dest="root_path",
- default="",
- help="Root path",
- )
- opt.add_option(
- "-R",
- "--root-uri",
- type="string",
- dest="root_uri",
- default="",
- help="Root URI",
- )
- opt.add_option(
"-p",
"--prefix",
type="string",
@@ -1722,13 +1611,6 @@ if __name__ == "__main__":
dest="copy_style",
help="Copy style from template directory to output directory",
)
- opt.add_option(
- "-o",
- "--online",
- action="store_true",
- dest="online",
- help="Generate index for online documentation",
- )
(options, args) = opt.parse_args()
opts = vars(options)
@@ -1740,7 +1622,6 @@ if __name__ == "__main__":
spec_pre = options.prefix
ontology = "file:" + str(args[0])
output = args[1]
- index_path = options.index_path
docdir = options.docdir
tags = options.tags
@@ -1753,27 +1634,18 @@ if __name__ == "__main__":
b = os.path.basename(outdir)
if not os.access(os.path.abspath(spec), os.R_OK):
- print("warning: extension %s has no %s.ttl file" % (b, b))
+ sys.stderr.write("error: extension %s has no %s.ttl file\n" % (b, b))
sys.exit(1)
- # Root link
- root_path = opts["root_path"]
- root_uri = opts["root_uri"]
- root_link = os.path.join(root_path, "index.html")
-
# Generate spec documentation
specdoc = specgen(
spec,
- indir,
+ opts["template"],
opts["style_uri"],
docdir,
tags,
opts,
instances=True,
- root_link=root_link,
- index_path=index_path,
- root_path=root_path,
- root_uri=root_uri,
)
# Save to HTML output file
@@ -1782,7 +1654,10 @@ if __name__ == "__main__":
if opts["copy_style"]:
import shutil
- shutil.copyfile(
- os.path.join(indir, "style.css"),
- os.path.join(os.path.dirname(output), "style.css"),
- )
+ for stylesheet in ["pygments.css", "style.css"]:
+ style_dir = opts["style_dir"]
+ output_dir = os.path.dirname(output)
+ shutil.copyfile(
+ os.path.join(style_dir, stylesheet),
+ os.path.join(output_dir, stylesheet),
+ )
diff --git a/lv2specgen/meson.build b/lv2specgen/meson.build
new file mode 100644
index 0000000..9ecb8d4
--- /dev/null
+++ b/lv2specgen/meson.build
@@ -0,0 +1,41 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+lv2specgen_py = files('lv2specgen.py')
+
+lv2_list_email = 'devel@lists.lv2plug.in'
+lv2_list_page = 'http://lists.lv2plug.in/listinfo.cgi/devel-lv2plug.in'
+
+lv2specgen_command_prefix = [
+ lv2specgen_py,
+ '--list-email=' + lv2_list_email,
+ '--list-page=' + lv2_list_page,
+]
+
+if is_variable('lv2_tags')
+ lv2specgen_command_prefix += [
+ '--tags', lv2_tags.full_path(), # TODO: Remove full_path() in meson 0.60.0
+ ]
+endif
+
+install_data(
+ files('lv2specgen.py'),
+ install_dir: get_option('bindir'),
+ install_mode: 'rwxr-xr-x',
+)
+
+meson.override_find_program('lv2specgen.py', lv2specgen_py)
+
+install_data(
+ files(
+ '../doc/style/pygments.css',
+ '../doc/style/style.css',
+ 'template.html',
+ ),
+ install_dir: get_option('datadir') / 'lv2specgen',
+)
+
+install_subdir(
+ 'DTD',
+ install_dir: get_option('datadir') / 'lv2specgen',
+)
diff --git a/lv2specgen/style.css b/lv2specgen/style.css
deleted file mode 120000
index f320096..0000000
--- a/lv2specgen/style.css
+++ /dev/null
@@ -1 +0,0 @@
-../doc/style.css \ No newline at end of file
diff --git a/lv2specgen/template.html b/lv2specgen/template.html
index ed9d6fb..4eb3d96 100644
--- a/lv2specgen/template.html
+++ b/lv2specgen/template.html
@@ -2,12 +2,14 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
<html about="@URI@"
xmlns="http://www.w3.org/1999/xhtml"
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:dct="http://purl.org/dc/terms/"
+ xmlns:dcs="http://ontologi.es/doap-changeset#"
+ xmlns:dcterms="http://purl.org/dc/terms/"
+ xmlns:doap="http://usefulinc.com/ns/doap#"
+ xmlns:foaf="http://xmlns.com/foaf/0.1/"
+ xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
- xmlns:lv2="http://lv2plug.in/ns/lv2core#"
- @XMLNS@
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xml:lang="en">
<head>
<title>@TITLE@</title>
@@ -77,12 +79,12 @@
</div>
<div>
Valid
- <a about="" rel="dct:conformsTo" resource="http://www.w3.org/TR/rdfa-syntax"
+ <a about="" rel="dcterms:conformsTo" resource="http://www.w3.org/TR/rdfa-syntax"
href="http://validator.w3.org/check?uri=referer">
XHTML+RDFa
</a>
and
- <a about="" rel="dct:conformsTo" resource="http://www.w3.org/TR/CSS2"
+ <a about="" rel="dcterms:conformsTo" resource="http://www.w3.org/TR/CSS2"
href="http://jigsaw.w3.org/css-validator/check/referer">
CSS
</a>
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..4f4fcf1
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,373 @@
+# Copyright 2021-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+project('lv2', ['c'],
+ version: '1.18.7',
+ license: 'ISC',
+ meson_version: '>= 0.56.0',
+ default_options: [
+ 'b_ndebug=if-release',
+ 'buildtype=release',
+ 'c_std=c99',
+ ])
+
+lv2_docdir = get_option('datadir') / 'doc' / 'lv2'
+lv2_source_root = meson.current_source_dir()
+lv2_build_root = meson.current_build_dir()
+
+#######################
+# Compilers and Flags #
+#######################
+
+# Required tools
+pkg = import('pkgconfig')
+pymod = import('python')
+cc = meson.get_compiler('c')
+
+# Optional C++ compiler and Python tools for tests
+if not get_option('tests').disabled()
+ if add_languages(['cpp'], native: false, required: get_option('tests'))
+ cpp = meson.get_compiler('cpp')
+ endif
+endif
+
+# Set global warning flags
+if get_option('strict') and not meson.is_subproject()
+ subdir('meson/warnings')
+endif
+subdir('meson/suppressions')
+
+##########################
+# LV2 Path Configuration #
+##########################
+
+lv2dir = get_option('lv2dir')
+if lv2dir == ''
+ prefix = get_option('prefix')
+ if target_machine.system() == 'darwin' and prefix == '/'
+ lv2dir = '/Library/Audio/Plug-Ins/LV2'
+ elif target_machine.system() == 'haiku' and prefix == '/'
+ lv2dir = '/boot/common/add-ons/lv2'
+ elif target_machine.system() == 'windows' and prefix == 'C:/'
+ lv2dir = 'C:/Program Files/Common/LV2'
+ else
+ lv2dir = prefix / get_option('libdir') / 'lv2'
+ endif
+endif
+
+######################
+# Package/Dependency #
+######################
+
+# Generage pkg-config file for external dependants
+pkg.generate(
+ description: 'Plugin standard for audio systems',
+ filebase: 'lv2',
+ name: 'LV2',
+ subdirs: ['lv2'],
+ variables: [
+ 'lv2dir=' + lv2dir,
+ 'plugindir=' + lv2dir,
+ ],
+ version: meson.project_version(),
+)
+
+# Declare dependency for internal meson dependants
+lv2_dep = declare_dependency(
+ include_directories: include_directories('include'),
+ variables: [
+ 'lv2dir=' + lv2_source_root / 'lv2',
+ 'plugindir=' + lv2_build_root / 'plugins',
+ ],
+ version: meson.project_version(),
+)
+
+##################
+# Specifications #
+##################
+
+# Extensions in http://lv2plug.in/ns/ext/
+ext_names = [
+ 'atom',
+ 'buf-size',
+ 'data-access',
+ 'dynmanifest',
+ 'event',
+ 'instance-access',
+ 'log',
+ 'midi',
+ 'morph',
+ 'options',
+ 'parameters',
+ 'patch',
+ 'port-groups',
+ 'port-props',
+ 'presets',
+ 'resize-port',
+ 'state',
+ 'time',
+ 'uri-map',
+ 'urid',
+ 'worker',
+]
+
+# Extensions in http://lv2plug.in/ns/extensions/
+extensions_names = [
+ 'ui',
+ 'units',
+]
+
+# All extensions (not core) in http://lv2plug.in/ns/
+all_extension_names = ext_names + extensions_names
+
+# All specifications in http://lv2plug.in/ns/
+all_spec_names = ['core'] + ext_names + extensions_names
+
+###############
+# API Headers #
+###############
+
+prefix = get_option('prefix')
+includedir = get_option('includedir')
+
+install_subdir('include/lv2', install_dir: includedir)
+
+if get_option('old_headers')
+ uri_include_dir = prefix / includedir / 'lv2' / 'lv2plug.in' / 'ns'
+ include_prefix = 'include' / 'lv2'
+
+ # Install the core headers specially, because they are inconsistent
+
+ core_headers = files(
+ include_prefix / 'core' / 'attributes.h',
+ include_prefix / 'core' / 'lv2.h',
+ include_prefix / 'core' / 'lv2_util.h',
+ )
+
+ # Special case lv2.h is also in top-level include directory
+ install_headers(files(include_prefix / 'core' / 'lv2.h'))
+
+ # Core headers are inconsistently in "lv2plug.in/ns/lv2core"
+ install_data(core_headers, install_dir: uri_include_dir / 'lv2core')
+
+ # Some extensions are in "lv2plug.in/ns/ext"
+ foreach dir : ext_names
+ install_subdir(
+ include_prefix / dir,
+ install_dir: uri_include_dir / 'ext',
+ )
+ endforeach
+
+ # Some extensions are in "lv2plug.in/ns/extensions"
+ foreach dir : extensions_names
+ install_subdir(
+ include_prefix / dir,
+ install_dir: uri_include_dir / 'extensions',
+ )
+ endforeach
+endif
+
+#######################
+# Scripts and Schemas #
+#######################
+
+subdir('scripts')
+subdir('schemas.lv2')
+
+##################
+# Specifications #
+##################
+
+lv2_check_specification = files('scripts' / 'lv2_check_specification.py')
+
+check_python = pymod.find_installation(
+ 'python3',
+ modules: ['rdflib'],
+ required: get_option('tests'),
+)
+
+if (check_python.found() and
+ check_python.language_version().version_compare('<3.7'))
+ warning('Python 3.7 is required for tests')
+ check_python = disabler()
+endif
+
+foreach bundle_name : all_spec_names
+ bundle = 'lv2' / bundle_name + '.lv2'
+
+ # Check specification
+ if check_python.found()
+ test(
+ bundle_name,
+ lv2_check_specification,
+ args: files(bundle / 'manifest.ttl'),
+ suite: ['spec'],
+ )
+ endif
+
+ # Install specification bundle
+ install_subdir(bundle, install_dir: lv2dir)
+endforeach
+
+spec_files = files(
+ 'lv2/atom.lv2/atom.meta.ttl',
+ 'lv2/atom.lv2/atom.ttl',
+ 'lv2/atom.lv2/manifest.ttl',
+ 'lv2/buf-size.lv2/buf-size.meta.ttl',
+ 'lv2/buf-size.lv2/buf-size.ttl',
+ 'lv2/buf-size.lv2/manifest.ttl',
+ 'lv2/core.lv2/lv2core.meta.ttl',
+ 'lv2/core.lv2/lv2core.ttl',
+ 'lv2/core.lv2/manifest.ttl',
+ 'lv2/core.lv2/meta.ttl',
+ 'lv2/core.lv2/people.ttl',
+ 'lv2/data-access.lv2/data-access.meta.ttl',
+ 'lv2/data-access.lv2/data-access.ttl',
+ 'lv2/data-access.lv2/manifest.ttl',
+ 'lv2/dynmanifest.lv2/dynmanifest.meta.ttl',
+ 'lv2/dynmanifest.lv2/dynmanifest.ttl',
+ 'lv2/dynmanifest.lv2/manifest.ttl',
+ 'lv2/event.lv2/event.meta.ttl',
+ 'lv2/event.lv2/event.ttl',
+ 'lv2/event.lv2/manifest.ttl',
+ 'lv2/instance-access.lv2/instance-access.meta.ttl',
+ 'lv2/instance-access.lv2/instance-access.ttl',
+ 'lv2/instance-access.lv2/manifest.ttl',
+ 'lv2/log.lv2/log.meta.ttl',
+ 'lv2/log.lv2/log.ttl',
+ 'lv2/log.lv2/manifest.ttl',
+ 'lv2/midi.lv2/manifest.ttl',
+ 'lv2/midi.lv2/midi.meta.ttl',
+ 'lv2/midi.lv2/midi.ttl',
+ 'lv2/morph.lv2/manifest.ttl',
+ 'lv2/morph.lv2/morph.meta.ttl',
+ 'lv2/morph.lv2/morph.ttl',
+ 'lv2/options.lv2/manifest.ttl',
+ 'lv2/options.lv2/options.meta.ttl',
+ 'lv2/options.lv2/options.ttl',
+ 'lv2/parameters.lv2/manifest.ttl',
+ 'lv2/parameters.lv2/parameters.meta.ttl',
+ 'lv2/parameters.lv2/parameters.ttl',
+ 'lv2/patch.lv2/manifest.ttl',
+ 'lv2/patch.lv2/patch.meta.ttl',
+ 'lv2/patch.lv2/patch.ttl',
+ 'lv2/port-groups.lv2/manifest.ttl',
+ 'lv2/port-groups.lv2/port-groups.meta.ttl',
+ 'lv2/port-groups.lv2/port-groups.ttl',
+ 'lv2/port-props.lv2/manifest.ttl',
+ 'lv2/port-props.lv2/port-props.meta.ttl',
+ 'lv2/port-props.lv2/port-props.ttl',
+ 'lv2/presets.lv2/manifest.ttl',
+ 'lv2/presets.lv2/presets.meta.ttl',
+ 'lv2/presets.lv2/presets.ttl',
+ 'lv2/resize-port.lv2/manifest.ttl',
+ 'lv2/resize-port.lv2/resize-port.meta.ttl',
+ 'lv2/resize-port.lv2/resize-port.ttl',
+ 'lv2/state.lv2/manifest.ttl',
+ 'lv2/state.lv2/state.meta.ttl',
+ 'lv2/state.lv2/state.ttl',
+ 'lv2/time.lv2/manifest.ttl',
+ 'lv2/time.lv2/time.meta.ttl',
+ 'lv2/time.lv2/time.ttl',
+ 'lv2/ui.lv2/manifest.ttl',
+ 'lv2/ui.lv2/ui.meta.ttl',
+ 'lv2/ui.lv2/ui.ttl',
+ 'lv2/units.lv2/manifest.ttl',
+ 'lv2/units.lv2/units.meta.ttl',
+ 'lv2/units.lv2/units.ttl',
+ 'lv2/uri-map.lv2/manifest.ttl',
+ 'lv2/uri-map.lv2/uri-map.meta.ttl',
+ 'lv2/uri-map.lv2/uri-map.ttl',
+ 'lv2/urid.lv2/manifest.ttl',
+ 'lv2/urid.lv2/urid.meta.ttl',
+ 'lv2/urid.lv2/urid.ttl',
+ 'lv2/worker.lv2/manifest.ttl',
+ 'lv2/worker.lv2/worker.meta.ttl',
+ 'lv2/worker.lv2/worker.ttl',
+)
+
+#################
+# Documentation #
+#################
+
+# Determine if all the dependencies for building documentation are present
+doxygen = find_program('doxygen', required: get_option('docs'))
+build_docs = false
+doc_deps = []
+if not get_option('docs').disabled()
+ doc_python_modules = ['lxml', 'markdown', 'pygments', 'rdflib']
+
+ python = pymod.find_installation(
+ 'python3',
+ modules: doc_python_modules,
+ required: get_option('docs'),
+ )
+
+ if python.found() and python.language_version().version_compare('<3.7')
+ warning('Python 3.7 is required for documentation')
+ build_docs = false
+ endif
+endif
+
+# Run Doxygen first to generate tags
+subdir('doc/c')
+
+# Set up lv2specgen and lv2specgen_command_prefix (which references tags)
+subdir('lv2specgen')
+
+# Generate specification documentation
+if build_docs
+ subdir('doc/style')
+ subdir('doc/ns')
+endif
+
+###########
+# Plugins #
+###########
+
+# Example plugins and "Programming LV2 Plugins" book
+if not get_option('plugins').disabled()
+ subdir('plugins')
+endif
+
+############
+# Programs #
+############
+
+# Command-line utilities
+subdir('util')
+
+# Data and build tests
+subdir('test')
+
+########
+# News #
+########
+
+lv2_write_news_py = find_program('scripts' / 'lv2_write_news.py')
+
+write_news_command = [
+ lv2_write_news_py,
+ '-t', 'http://lv2plug.in/ns/lv2',
+ files(lv2_source_root / 'lv2' / 'core.lv2' / 'people.ttl'),
+ files(lv2_source_root / 'lv2' / 'core.lv2' / 'meta.ttl'),
+ spec_files,
+]
+
+custom_target(
+ 'NEWS',
+ capture: true,
+ command: write_news_command,
+ output: 'NEWS',
+)
+
+if not meson.is_subproject()
+ # Generate NEWS file from data in distribution archive
+ meson.add_dist_script(write_news_command)
+
+ summary('Tests', not get_option('tests').disabled(), bool_yn: true)
+ summary('Documentation', build_docs, bool_yn: true)
+ summary('Prefix', get_option('prefix'), section: 'Paths')
+ summary('LV2 bundles', lv2dir, section: 'Paths')
+ summary('Headers', get_option('prefix') / get_option('includedir'), section: 'Paths')
+endif
diff --git a/meson/library/meson.build b/meson/library/meson.build
new file mode 100644
index 0000000..f50505f
--- /dev/null
+++ b/meson/library/meson.build
@@ -0,0 +1,30 @@
+# Copyright 2020-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+# General definitions for building libraries.
+#
+# These are essentially workarounds for meson and/or MSVC. Unfortunately,
+# meson's default_library option doesn't support shared and static builds very
+# well. In particular, it's often necessary to define different symbols for
+# static and shared builds of libraries so that symbols can be exported. To
+# work around this, we do not support default_library=both on Windows. On
+# other platforms with GCC-like compilers, we can support both because symbols
+# can safely be exported in the same way (giving them default visibility) in
+# both static and shared builds.
+
+# Abort on Windows with default_library=both
+if get_option('default_library') == 'both'
+ if host_machine.system() == 'windows'
+ error('default_library=both is not supported on Windows')
+ endif
+endif
+
+# Set library_suffix to the suffix for libraries
+if cc.get_id() == 'msvc'
+ # Meson appends a version to the name only on MS, which leads to inconsistent
+ # library names, like `mylib-1-1`. So, provide no suffix to ultimately get
+ # the same name as on other platforms, like `mylib-1`.
+ library_suffix = ''
+else
+ library_suffix = '-@0@'.format(meson.project_version().split('.')[0])
+endif
diff --git a/meson/suppressions/meson.build b/meson/suppressions/meson.build
new file mode 100644
index 0000000..e2170c0
--- /dev/null
+++ b/meson/suppressions/meson.build
@@ -0,0 +1,130 @@
+# Copyright 2020-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+# Project-specific warning suppressions.
+#
+# This should be used in conjunction with the generic "warnings" sibling that
+# enables all reasonable warnings for the compiler. It lives here just to keep
+# the top-level meson.build more readable.
+
+#####
+# C #
+#####
+
+if is_variable('cc')
+ c_suppressions = []
+
+ if get_option('strict')
+ if cc.get_id() in ['clang', 'emscripten']
+ c_suppressions += [
+ '-Wno-cast-align',
+ '-Wno-cast-qual',
+ '-Wno-declaration-after-statement',
+ '-Wno-documentation-unknown-command',
+ '-Wno-double-promotion',
+ '-Wno-float-conversion',
+ '-Wno-float-equal',
+ '-Wno-implicit-float-conversion',
+ '-Wno-padded',
+ '-Wno-reserved-id-macro',
+ '-Wno-shorten-64-to-32',
+ '-Wno-sign-conversion',
+ '-Wno-switch-enum',
+ '-Wno-unused-parameter',
+ ]
+ elif cc.get_id() == 'gcc'
+ c_suppressions += [
+ '-Wno-cast-align',
+ '-Wno-cast-qual',
+ '-Wno-conversion',
+ '-Wno-double-promotion',
+ '-Wno-float-equal',
+ '-Wno-inline',
+ '-Wno-padded',
+ '-Wno-suggest-attribute=const',
+ '-Wno-suggest-attribute=malloc',
+ '-Wno-suggest-attribute=pure',
+ '-Wno-switch-default',
+ '-Wno-switch-enum',
+ '-Wno-unsuffixed-float-constants',
+ '-Wno-unused-const-variable',
+ '-Wno-unused-parameter',
+ ]
+
+ if target_machine.system() == 'windows'
+ c_suppressions += [
+ '-Wno-suggest-attribute=format',
+ ]
+ endif
+
+ elif cc.get_id() == 'msvc'
+ c_suppressions += [
+ '/wd4061', # enumerator in switch is not explicitly handled
+ '/wd4100', # unreferenced formal parameter
+ '/wd4244', # conversion with possible loss of data
+ '/wd4267', # conversion from size_t to a smaller type
+ '/wd4310', # cast truncates constant value
+ '/wd4365', # signed/unsigned mismatch
+ '/wd4464', # relative include path contains ".."
+ '/wd4514', # unreferenced inline function has been removed
+ '/wd4514', # unreferenced inline function has been removed
+ '/wd4706', # assignment within conditional expression
+ '/wd4710', # function not inlined
+ '/wd4711', # function selected for automatic inline expansion
+ '/wd4820', # padding added after construct
+ '/wd5045', # will insert Spectre mitigation for memory load
+ ]
+ endif
+ endif
+
+ c_suppressions = cc.get_supported_arguments(c_suppressions)
+endif
+
+#######
+# C++ #
+#######
+
+if is_variable('cpp')
+ cpp_suppressions = []
+
+ if get_option('strict')
+ if cpp.get_id() in ['clang', 'emscripten']
+ cpp_suppressions = [
+ '-Wno-cast-align',
+ '-Wno-cast-qual',
+ '-Wno-documentation-unknown-command',
+ '-Wno-nullability-extension',
+ '-Wno-padded',
+ '-Wno-reserved-id-macro',
+ ]
+
+ elif cpp.get_id() == 'gcc'
+ cpp_suppressions = [
+ '-Wno-cast-align',
+ '-Wno-cast-qual',
+ '-Wno-inline',
+ '-Wno-padded',
+ '-Wno-unused-const-variable',
+ '-Wno-useless-cast',
+ ]
+
+ if target_machine.system() == 'windows'
+ cpp_suppressions += [
+ '-Wno-suggest-attribute=format',
+ ]
+ endif
+
+ elif cpp.get_id() == 'msvc'
+ cpp_suppressions = [
+ '/wd4514', # unreferenced inline function has been removed
+ '/wd4706', # assignment within conditional expression
+ '/wd4710', # function not inlined
+ '/wd4711', # function selected for automatic inline expansion
+ '/wd4820', # padding added after data member
+ '/wd5045', # will insert Spectre mitigation
+ ]
+ endif
+ endif
+
+ cpp_suppressions = cpp.get_supported_arguments(cpp_suppressions)
+endif
diff --git a/meson/warnings/meson.build b/meson/warnings/meson.build
new file mode 100644
index 0000000..e0051f9
--- /dev/null
+++ b/meson/warnings/meson.build
@@ -0,0 +1,256 @@
+# Copyright 2020-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+# General code to enable approximately all warnings in GCC 12, clang, and MSVC.
+#
+# This is trivial for clang and MSVC, but GCC doesn't have an "everything"
+# option, so we need to enable everything we want explicitly. Wall is assumed,
+# but Wextra is not, for stability.
+#
+# These are collected from common.opt and c.opt in the GCC source, and manually
+# curated with the help of the GCC documentation. Warnings that are
+# application-specific, historical, or about compatibility between specific
+# language revisions are omitted. The intent here is to have roughly the same
+# meaning as clang's Weverything: extremely strict, but general. Specifically
+# omitted are:
+#
+# General:
+#
+# Wabi=
+# Waggregate-return
+# Walloc-size-larger-than=BYTES
+# Walloca-larger-than=BYTES
+# Wframe-larger-than=BYTES
+# Wlarger-than=BYTES
+# Wstack-usage=BYTES
+# Wsystem-headers
+# Wtraditional
+# Wtraditional-conversion
+# Wtrampolines
+# Wvla-larger-than=BYTES
+#
+# Build specific:
+#
+# Wpoison-system-directories
+#
+# C Specific:
+#
+# Wc11-c2x-compat
+# Wc90-c99-compat
+# Wc99-c11-compat
+# Wdeclaration-after-statement
+# Wtraditional
+# Wtraditional-conversion
+#
+# C++ Specific:
+#
+# Wc++0x-compat
+# Wc++1z-compat
+# Wc++2a-compat
+# Wctad-maybe-unsupported
+# Wnamespaces
+# Wtemplates
+
+# GCC warnings that apply to all C-family languages
+gcc_common_warnings = [
+ '-Walloc-zero',
+ '-Walloca',
+ '-Wanalyzer-too-complex',
+ '-Warith-conversion',
+ '-Warray-bounds=2',
+ '-Wattribute-alias=2',
+ '-Wbidi-chars=ucn',
+ '-Wcast-align=strict',
+ '-Wcast-function-type',
+ '-Wcast-qual',
+ '-Wclobbered',
+ '-Wconversion',
+ '-Wdate-time',
+ '-Wdisabled-optimization',
+ '-Wdouble-promotion',
+ '-Wduplicated-branches',
+ '-Wduplicated-cond',
+ '-Wempty-body',
+ '-Wendif-labels',
+ '-Wfloat-equal',
+ '-Wformat-overflow=2',
+ '-Wformat-signedness',
+ '-Wformat-truncation=2',
+ '-Wformat=2',
+ '-Wignored-qualifiers',
+ '-Wimplicit-fallthrough=3',
+ '-Winit-self',
+ '-Winline',
+ '-Winvalid-pch',
+ '-Wlogical-op',
+ '-Wmissing-declarations',
+ '-Wmissing-field-initializers',
+ '-Wmissing-include-dirs',
+ '-Wmultichar',
+ '-Wnormalized=nfc',
+ '-Wnull-dereference',
+ '-Wopenacc-parallelism',
+ '-Woverlength-strings',
+ '-Wpacked',
+ '-Wpacked-bitfield-compat',
+ '-Wpadded',
+ '-Wpointer-arith',
+ '-Wredundant-decls',
+ '-Wshadow',
+ '-Wshift-negative-value',
+ '-Wshift-overflow=2',
+ '-Wstack-protector',
+ '-Wstrict-aliasing=3',
+ '-Wstrict-overflow=5',
+ '-Wstring-compare',
+ '-Wstringop-overflow=3',
+ '-Wsuggest-attribute=cold',
+ '-Wsuggest-attribute=const',
+ '-Wsuggest-attribute=format',
+ '-Wsuggest-attribute=malloc',
+ '-Wsuggest-attribute=noreturn',
+ '-Wsuggest-attribute=pure',
+ '-Wswitch-default',
+ '-Wswitch-enum',
+ '-Wtrampolines',
+ '-Wtrivial-auto-var-init',
+ '-Wtype-limits',
+ '-Wundef',
+ '-Wuninitialized',
+ '-Wunsafe-loop-optimizations',
+ '-Wunused',
+ '-Wunused-const-variable=2',
+ '-Wunused-macros',
+ '-Wvector-operation-performance',
+ '-Wvla',
+ '-Wwrite-strings',
+]
+
+#####
+# C #
+#####
+
+if is_variable('cc') and not is_variable('all_c_warnings')
+ # Set all_c_warnings for the current C compiler
+ all_c_warnings = []
+
+ if get_option('strict')
+ if cc.get_id() == 'clang'
+ all_c_warnings += ['-Weverything']
+
+ if not meson.is_cross_build()
+ all_c_warnings += [
+ '-Wno-poison-system-directories',
+ ]
+ endif
+
+ elif cc.get_id() == 'gcc'
+ all_c_warnings += gcc_common_warnings + [
+ '-Wabsolute-value',
+ '-Wbad-function-cast',
+ '-Wc++-compat',
+ '-Wenum-conversion',
+ '-Wjump-misses-init',
+ '-Wmissing-parameter-type',
+ '-Wmissing-prototypes',
+ '-Wnested-externs',
+ '-Wold-style-declaration',
+ '-Wold-style-definition',
+ '-Woverride-init',
+ '-Wsign-compare',
+ '-Wstrict-prototypes',
+ '-Wunsuffixed-float-constants',
+ ]
+
+ elif cc.get_id() == 'msvc'
+ all_c_warnings += [
+ '/Wall',
+ '/experimental:external',
+ '/external:W0',
+ '/external:anglebrackets',
+ ]
+ endif
+ endif
+
+ all_c_warnings = cc.get_supported_arguments(all_c_warnings)
+ add_global_arguments(all_c_warnings, language: ['c'])
+endif
+
+#######
+# C++ #
+#######
+
+if is_variable('cpp') and not is_variable('all_cpp_warnings')
+ # Set all_cpp_warnings for the current C++ compiler
+ all_cpp_warnings = []
+
+ if get_option('strict')
+ if cpp.get_id() == 'clang'
+ all_cpp_warnings += [
+ '-Weverything',
+ '-Wno-c++98-compat',
+ '-Wno-c++98-compat-pedantic',
+ ]
+
+ if not meson.is_cross_build()
+ all_cpp_warnings += [
+ '-Wno-poison-system-directories',
+ ]
+ endif
+
+ elif cpp.get_id() == 'gcc'
+ all_cpp_warnings += gcc_common_warnings + [
+ '-Wabi-tag',
+ '-Waligned-new=all',
+ '-Wcatch-value=3',
+ '-Wcomma-subscript',
+ '-Wconditionally-supported',
+ '-Wctor-dtor-privacy',
+ '-Wdelete-non-virtual-dtor',
+ '-Wdeprecated',
+ '-Wdeprecated-copy',
+ '-Wdeprecated-copy-dtor',
+ '-Wdeprecated-enum-enum-conversion',
+ '-Wdeprecated-enum-float-conversion',
+ '-Weffc++',
+ '-Wexpansion-to-defined',
+ '-Wextra-semi',
+ '-Wimport',
+ '-Winvalid-imported-macros',
+ '-Wmismatched-tags',
+ '-Wmultiple-inheritance',
+ '-Wnoexcept',
+ '-Wnoexcept-type',
+ '-Wnon-virtual-dtor',
+ '-Wold-style-cast',
+ '-Woverloaded-virtual',
+ '-Wplacement-new=2',
+ '-Wredundant-move',
+ '-Wredundant-tags',
+ '-Wregister',
+ '-Wsign-compare',
+ '-Wsign-promo',
+ '-Wsized-deallocation',
+ '-Wstrict-null-sentinel',
+ '-Wsuggest-final-methods',
+ '-Wsuggest-final-types',
+ '-Wsuggest-override',
+ '-Wuseless-cast',
+ '-Wvirtual-inheritance',
+ '-Wvolatile',
+ '-Wzero-as-null-pointer-constant',
+ ]
+
+ elif cpp.get_id() == 'msvc'
+ all_cpp_warnings += [
+ '/Wall',
+ '/experimental:external',
+ '/external:W0',
+ '/external:anglebrackets',
+ ]
+ endif
+ endif
+
+ all_cpp_warnings = cpp.get_supported_arguments(all_cpp_warnings)
+ add_global_arguments(all_cpp_warnings, language: ['cpp'])
+endif
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 0000000..089402e
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,23 @@
+option('docs', type: 'feature', value: 'auto', yield: true,
+ description: 'Build documentation')
+
+option('lv2dir', type: 'string', value: '', yield: true,
+ description: 'LV2 bundle installation directory')
+
+option('old_headers', type: 'boolean', value: true, yield: true,
+ description: 'Install backwards compatible headers at URI-style paths')
+
+option('online_docs', type: 'boolean', value: 'false', yield: true,
+ description: 'Build documentation for online hosting')
+
+option('plugins', type: 'feature', value: 'auto', yield: true,
+ description: 'Build example plugins')
+
+option('strict', type: 'boolean', value: false, yield: true,
+ description: 'Enable ultra-strict warnings')
+
+option('tests', type: 'feature', value: 'auto', yield: true,
+ description: 'Build tests')
+
+option('title', type: 'string', value: 'LV2',
+ description: 'Project title')
diff --git a/plugins/eg-amp.lv2/meson.build b/plugins/eg-amp.lv2/meson.build
new file mode 100644
index 0000000..2b15b01
--- /dev/null
+++ b/plugins/eg-amp.lv2/meson.build
@@ -0,0 +1,41 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+plugin_sources = files('amp.c')
+bundle_name = 'eg-amp.lv2'
+data_filenames = ['manifest.ttl.in', 'amp.ttl']
+
+module = shared_library(
+ 'amp',
+ plugin_sources,
+ c_args: c_suppressions,
+ dependencies: [lv2_dep, m_dep],
+ gnu_symbol_visibility: 'hidden',
+ install: true,
+ install_dir: lv2dir / bundle_name,
+ name_prefix: '',
+)
+
+config = configuration_data(
+ {
+ 'LIB_EXT': '.' + module.full_path().split('.')[-1],
+ }
+)
+
+foreach filename : data_filenames
+ if filename.endswith('.in')
+ configure_file(
+ configuration: config,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename.substring(0, -3),
+ )
+ else
+ configure_file(
+ copy: true,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename,
+ )
+ endif
+endforeach
diff --git a/plugins/eg-amp.lv2/waf b/plugins/eg-amp.lv2/waf
deleted file mode 120000
index 59a1ac9..0000000
--- a/plugins/eg-amp.lv2/waf
+++ /dev/null
@@ -1 +0,0 @@
-../../waf \ No newline at end of file
diff --git a/plugins/eg-amp.lv2/wscript b/plugins/eg-amp.lv2/wscript
deleted file mode 100644
index 822825d..0000000
--- a/plugins/eg-amp.lv2/wscript
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/env python
-from waflib.extras import autowaf as autowaf
-import re
-
-# Variables for 'waf dist'
-APPNAME = 'eg-amp.lv2'
-VERSION = '1.0.0'
-
-# Mandatory variables
-top = '.'
-out = 'build'
-
-def options(opt):
- opt.load('compiler_c')
- opt.load('lv2')
- autowaf.set_options(opt)
-
-def configure(conf):
- conf.load('compiler_c', cache=True)
- conf.load('lv2', cache=True)
- conf.load('autowaf', cache=True)
-
- conf.check_pkg('lv2', uselib_store='LV2')
-
- conf.check(features='c cshlib', lib='m', uselib_store='M', mandatory=False)
-
-def build(bld):
- bundle = 'eg-amp.lv2'
-
- # Build manifest.ttl by substitution (for portable lib extension)
- bld(features = 'subst',
- source = 'manifest.ttl.in',
- target = 'lv2/%s/%s' % (bundle, 'manifest.ttl'),
- install_path = '${LV2DIR}/%s' % bundle,
- LIB_EXT = bld.env.LV2_LIB_EXT)
-
- # Copy other data files to build bundle (build/eg-amp.lv2)
- for i in ['amp.ttl']:
- bld(features = 'subst',
- is_copy = True,
- source = i,
- target = 'lv2/%s/%s' % (bundle, i),
- install_path = '${LV2DIR}/%s' % bundle)
-
- # Build plugin library
- obj = bld(features = 'c cshlib lv2lib',
- source = 'amp.c',
- name = 'amp',
- target = 'lv2/%s/amp' % bundle,
- install_path = '${LV2DIR}/%s' % bundle,
- uselib = 'M LV2')
diff --git a/plugins/eg-fifths.lv2/meson.build b/plugins/eg-fifths.lv2/meson.build
new file mode 100644
index 0000000..fd38ee3
--- /dev/null
+++ b/plugins/eg-fifths.lv2/meson.build
@@ -0,0 +1,41 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+plugin_sources = files('fifths.c')
+bundle_name = 'eg-fifths.lv2'
+data_filenames = ['manifest.ttl.in', 'fifths.ttl']
+
+module = shared_library(
+ 'fifths',
+ plugin_sources,
+ c_args: c_suppressions,
+ dependencies: [lv2_dep, m_dep],
+ gnu_symbol_visibility: 'hidden',
+ install: true,
+ install_dir: lv2dir / bundle_name,
+ name_prefix: '',
+)
+
+config = configuration_data(
+ {
+ 'LIB_EXT': '.' + module.full_path().split('.')[-1],
+ }
+)
+
+foreach filename : data_filenames
+ if filename.endswith('.in')
+ configure_file(
+ configuration: config,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename.substring(0, -3),
+ )
+ else
+ configure_file(
+ copy: true,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename,
+ )
+ endif
+endforeach
diff --git a/plugins/eg-fifths.lv2/waf b/plugins/eg-fifths.lv2/waf
deleted file mode 120000
index 59a1ac9..0000000
--- a/plugins/eg-fifths.lv2/waf
+++ /dev/null
@@ -1 +0,0 @@
-../../waf \ No newline at end of file
diff --git a/plugins/eg-fifths.lv2/wscript b/plugins/eg-fifths.lv2/wscript
deleted file mode 100644
index 8b2991b..0000000
--- a/plugins/eg-fifths.lv2/wscript
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-from waflib.extras import autowaf as autowaf
-import re
-
-# Variables for 'waf dist'
-APPNAME = 'eg-fifths.lv2'
-VERSION = '1.0.0'
-
-# Mandatory variables
-top = '.'
-out = 'build'
-
-def options(opt):
- opt.load('compiler_c')
- opt.load('lv2')
- autowaf.set_options(opt)
-
-def configure(conf):
- conf.load('compiler_c', cache=True)
- conf.load('lv2', cache=True)
- conf.load('autowaf', cache=True)
-
- conf.check_pkg('lv2 >= 1.2.1', uselib_store='LV2')
-
-def build(bld):
- bundle = 'eg-fifths.lv2'
-
- # Build manifest.ttl by substitution (for portable lib extension)
- bld(features = 'subst',
- source = 'manifest.ttl.in',
- target = 'lv2/%s/%s' % (bundle, 'manifest.ttl'),
- install_path = '${LV2DIR}/%s' % bundle,
- LIB_EXT = bld.env.LV2_LIB_EXT)
-
- # Copy other data files to build bundle (build/eg-fifths.lv2)
- for i in ['fifths.ttl']:
- bld(features = 'subst',
- is_copy = True,
- source = i,
- target = 'lv2/%s/%s' % (bundle, i),
- install_path = '${LV2DIR}/%s' % bundle)
-
- # Build plugin library
- obj = bld(features = 'c cshlib lv2lib',
- source = 'fifths.c',
- name = 'fifths',
- target = 'lv2/%s/fifths' % bundle,
- install_path = '${LV2DIR}/%s' % bundle,
- use = 'LV2')
diff --git a/plugins/eg-metro.lv2/meson.build b/plugins/eg-metro.lv2/meson.build
new file mode 100644
index 0000000..f881eca
--- /dev/null
+++ b/plugins/eg-metro.lv2/meson.build
@@ -0,0 +1,41 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+plugin_sources = files('metro.c')
+bundle_name = 'eg-metro.lv2'
+data_filenames = ['manifest.ttl.in', 'metro.ttl']
+
+module = shared_library(
+ 'metro',
+ plugin_sources,
+ c_args: c_suppressions,
+ dependencies: [lv2_dep, m_dep],
+ gnu_symbol_visibility: 'hidden',
+ install: true,
+ install_dir: lv2dir / bundle_name,
+ name_prefix: '',
+)
+
+config = configuration_data(
+ {
+ 'LIB_EXT': '.' + module.full_path().split('.')[-1],
+ }
+)
+
+foreach filename : data_filenames
+ if filename.endswith('.in')
+ configure_file(
+ configuration: config,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename.substring(0, -3),
+ )
+ else
+ configure_file(
+ copy: true,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename,
+ )
+ endif
+endforeach
diff --git a/plugins/eg-metro.lv2/metro.c b/plugins/eg-metro.lv2/metro.c
index 87a9029..c89c542 100644
--- a/plugins/eg-metro.lv2/metro.c
+++ b/plugins/eg-metro.lv2/metro.c
@@ -212,7 +212,7 @@ static void
play(Metro* self, uint32_t begin, uint32_t end)
{
float* const output = self->ports.output;
- const uint32_t frames_per_beat = 60.0f / self->bpm * self->rate;
+ const uint32_t frames_per_beat = (uint32_t)(60.0f / self->bpm * self->rate);
if (self->speed == 0.0f) {
memset(output, 0, (end - begin) * sizeof(float));
@@ -289,7 +289,7 @@ update_position(Metro* self, const LV2_Atom_Object* obj)
const float frames_per_beat = (float)(60.0 / self->bpm * self->rate);
const float bar_beats = ((LV2_Atom_Float*)beat)->body;
const float beat_beats = bar_beats - floorf(bar_beats);
- self->elapsed_len = beat_beats * frames_per_beat;
+ self->elapsed_len = (uint32_t)(beat_beats * frames_per_beat);
if (self->elapsed_len < self->attack_len) {
self->state = STATE_ATTACK;
} else if (self->elapsed_len < self->attack_len + self->decay_len) {
@@ -313,7 +313,7 @@ run(LV2_Handle instance, uint32_t sample_count)
!lv2_atom_sequence_is_end(&in->body, in->atom.size, ev);
ev = lv2_atom_sequence_next(ev)) {
// Play the click for the time slice from last_t until now
- play(self, last_t, ev->time.frames);
+ play(self, last_t, (uint32_t)ev->time.frames);
// Check if this event is an Object
// (or deprecated Blank to tolerate old hosts)
@@ -327,7 +327,7 @@ run(LV2_Handle instance, uint32_t sample_count)
}
// Update time for next iteration and move to next event
- last_t = ev->time.frames;
+ last_t = (uint32_t)ev->time.frames;
}
// Play for remainder of cycle
@@ -345,8 +345,9 @@ static const LV2_Descriptor descriptor = {
NULL, // extension_data
};
-LV2_SYMBOL_EXPORT const LV2_Descriptor*
- lv2_descriptor(uint32_t index)
+LV2_SYMBOL_EXPORT
+const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
{
return index == 0 ? &descriptor : NULL;
}
diff --git a/plugins/eg-metro.lv2/waf b/plugins/eg-metro.lv2/waf
deleted file mode 120000
index 59a1ac9..0000000
--- a/plugins/eg-metro.lv2/waf
+++ /dev/null
@@ -1 +0,0 @@
-../../waf \ No newline at end of file
diff --git a/plugins/eg-metro.lv2/wscript b/plugins/eg-metro.lv2/wscript
deleted file mode 100644
index 5fb0d07..0000000
--- a/plugins/eg-metro.lv2/wscript
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env python
-from waflib.extras import autowaf as autowaf
-import re
-
-# Variables for 'waf dist'
-APPNAME = 'eg-metro.lv2'
-VERSION = '1.0.0'
-
-# Mandatory variables
-top = '.'
-out = 'build'
-
-def options(opt):
- opt.load('compiler_c')
- opt.load('lv2')
- autowaf.set_options(opt)
-
-def configure(conf):
- conf.load('compiler_c', cache=True)
- conf.load('lv2', cache=True)
- conf.load('autowaf', cache=True)
-
- conf.check_pkg('lv2 >= 0.2.0', uselib_store='LV2')
-
- conf.check(features='c cshlib', lib='m', uselib_store='M', mandatory=False)
-
-def build(bld):
- bundle = 'eg-metro.lv2'
-
- # Build manifest.ttl by substitution (for portable lib extension)
- bld(features = 'subst',
- source = 'manifest.ttl.in',
- target = 'lv2/%s/%s' % (bundle, 'manifest.ttl'),
- install_path = '${LV2DIR}/%s' % bundle,
- LIB_EXT = bld.env.LV2_LIB_EXT)
-
- # Copy other data files to build bundle (build/eg-metro.lv2)
- bld(features = 'subst',
- is_copy = True,
- source = 'metro.ttl',
- target = 'lv2/%s/metro.ttl' % bundle,
- install_path = '${LV2DIR}/%s' % bundle)
-
- # Build plugin library
- obj = bld(features = 'c cshlib lv2lib',
- source = 'metro.c',
- name = 'metro',
- target = 'lv2/%s/metro' % bundle,
- install_path = '${LV2DIR}/%s' % bundle,
- use = ['M', 'LV2'])
diff --git a/plugins/eg-midigate.lv2/meson.build b/plugins/eg-midigate.lv2/meson.build
new file mode 100644
index 0000000..0e35fd1
--- /dev/null
+++ b/plugins/eg-midigate.lv2/meson.build
@@ -0,0 +1,41 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+plugin_sources = files('midigate.c')
+bundle_name = 'eg-midigate.lv2'
+data_filenames = ['manifest.ttl.in', 'midigate.ttl']
+
+module = shared_library(
+ 'midigate',
+ plugin_sources,
+ c_args: c_suppressions,
+ dependencies: [lv2_dep, m_dep],
+ gnu_symbol_visibility: 'hidden',
+ install: true,
+ install_dir: lv2dir / bundle_name,
+ name_prefix: '',
+)
+
+config = configuration_data(
+ {
+ 'LIB_EXT': '.' + module.full_path().split('.')[-1],
+ }
+)
+
+foreach filename : data_filenames
+ if filename.endswith('.in')
+ configure_file(
+ configuration: config,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename.substring(0, -3),
+ )
+ else
+ configure_file(
+ copy: true,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename,
+ )
+ endif
+endforeach
diff --git a/plugins/eg-midigate.lv2/midigate.c b/plugins/eg-midigate.lv2/midigate.c
index 5379440..d98f670 100644
--- a/plugins/eg-midigate.lv2/midigate.c
+++ b/plugins/eg-midigate.lv2/midigate.c
@@ -160,6 +160,9 @@ run(LV2_Handle instance, uint32_t sample_count)
uint32_t offset = 0;
LV2_ATOM_SEQUENCE_FOREACH (self->control, ev) {
+ write_output(self, offset, (uint32_t)(ev->time.frames - offset));
+ offset = (uint32_t)ev->time.frames;
+
if (ev->body.type == self->uris.midi_MidiEvent) {
const uint8_t* const msg = (const uint8_t*)(ev + 1);
switch (lv2_midi_message_type(msg)) {
@@ -185,9 +188,6 @@ run(LV2_Handle instance, uint32_t sample_count)
break;
}
}
-
- write_output(self, offset, ev->time.frames - offset);
- offset = (uint32_t)ev->time.frames;
}
write_output(self, offset, sample_count - offset);
diff --git a/plugins/eg-midigate.lv2/waf b/plugins/eg-midigate.lv2/waf
deleted file mode 120000
index 59a1ac9..0000000
--- a/plugins/eg-midigate.lv2/waf
+++ /dev/null
@@ -1 +0,0 @@
-../../waf \ No newline at end of file
diff --git a/plugins/eg-midigate.lv2/wscript b/plugins/eg-midigate.lv2/wscript
deleted file mode 100644
index 5862721..0000000
--- a/plugins/eg-midigate.lv2/wscript
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-from waflib.extras import autowaf as autowaf
-import re
-
-# Variables for 'waf dist'
-APPNAME = 'eg-midigate.lv2'
-VERSION = '1.0.0'
-
-# Mandatory variables
-top = '.'
-out = 'build'
-
-def options(opt):
- opt.load('compiler_c')
- opt.load('lv2')
- autowaf.set_options(opt)
-
-def configure(conf):
- conf.load('compiler_c', cache=True)
- conf.load('lv2', cache=True)
- conf.load('autowaf', cache=True)
-
- conf.check_pkg('lv2', uselib_store='LV2')
-
-def build(bld):
- bundle = 'eg-midigate.lv2'
-
- # Build manifest.ttl by substitution (for portable lib extension)
- bld(features = 'subst',
- source = 'manifest.ttl.in',
- target = 'lv2/%s/%s' % (bundle, 'manifest.ttl'),
- install_path = '${LV2DIR}/%s' % bundle,
- LIB_EXT = bld.env.LV2_LIB_EXT)
-
- # Copy other data files to build bundle (build/eg-midigate.lv2)
- for i in ['midigate.ttl']:
- bld(features = 'subst',
- is_copy = True,
- source = i,
- target = 'lv2/%s/%s' % (bundle, i),
- install_path = '${LV2DIR}/%s' % bundle)
-
- # Build plugin library
- obj = bld(features = 'c cshlib lv2lib',
- source = 'midigate.c',
- name = 'midigate',
- target = 'lv2/%s/midigate' % bundle,
- install_path = '${LV2DIR}/%s' % bundle,
- uselib = 'LV2')
diff --git a/plugins/eg-params.lv2/meson.build b/plugins/eg-params.lv2/meson.build
new file mode 100644
index 0000000..4c1e576
--- /dev/null
+++ b/plugins/eg-params.lv2/meson.build
@@ -0,0 +1,41 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+plugin_sources = files('params.c')
+bundle_name = 'eg-params.lv2'
+data_filenames = ['manifest.ttl.in', 'params.ttl']
+
+module = shared_library(
+ 'params',
+ plugin_sources,
+ c_args: c_suppressions,
+ dependencies: [lv2_dep, m_dep],
+ gnu_symbol_visibility: 'hidden',
+ install: true,
+ install_dir: lv2dir / bundle_name,
+ name_prefix: '',
+)
+
+config = configuration_data(
+ {
+ 'LIB_EXT': '.' + module.full_path().split('.')[-1],
+ }
+)
+
+foreach filename : data_filenames
+ if filename.endswith('.in')
+ configure_file(
+ configuration: config,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename.substring(0, -3),
+ )
+ else
+ configure_file(
+ copy: true,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename,
+ )
+ endif
+endforeach
diff --git a/plugins/eg-params.lv2/params.c b/plugins/eg-params.lv2/params.c
index 56c39cd..052b43b 100644
--- a/plugins/eg-params.lv2/params.c
+++ b/plugins/eg-params.lv2/params.c
@@ -199,10 +199,10 @@ unmap(Params* self, LV2_URID urid)
{
if (self->unmap) {
return self->unmap->unmap(self->unmap->handle, urid);
- } else {
- snprintf(self->urid_buf, sizeof(self->urid_buf), "%u", urid);
- return self->urid_buf;
}
+
+ snprintf(self->urid_buf, sizeof(self->urid_buf), "%u", urid);
+ return self->urid_buf;
}
static LV2_State_Status
@@ -526,8 +526,9 @@ static const LV2_Descriptor descriptor = {EG_PARAMS_URI,
cleanup,
extension_data};
-LV2_SYMBOL_EXPORT const LV2_Descriptor*
- lv2_descriptor(uint32_t index)
+LV2_SYMBOL_EXPORT
+const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
{
return (index == 0) ? &descriptor : NULL;
}
diff --git a/plugins/eg-params.lv2/state_map.h b/plugins/eg-params.lv2/state_map.h
index f534f60..4a00d2f 100644
--- a/plugins/eg-params.lv2/state_map.h
+++ b/plugins/eg-params.lv2/state_map.h
@@ -48,7 +48,7 @@ state_map_cmp(const void* a, const void* b)
/** Helper macro for terse state map initialisation. */
#define STATE_MAP_INIT(type, ptr) \
- (LV2_ATOM__##type), (sizeof(*ptr) - sizeof(LV2_Atom)), (ptr)
+ (LV2_ATOM__##type), (sizeof(*(ptr)) - sizeof(LV2_Atom)), (ptr)
/**
Initialise a state map.
diff --git a/plugins/eg-params.lv2/wscript b/plugins/eg-params.lv2/wscript
deleted file mode 100644
index 503e8db..0000000
--- a/plugins/eg-params.lv2/wscript
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-from waflib.extras import autowaf as autowaf
-import re
-
-# Variables for 'waf dist'
-APPNAME = 'eg-params.lv2'
-VERSION = '1.0.0'
-
-# Mandatory variables
-top = '.'
-out = 'build'
-
-def options(opt):
- opt.load('compiler_c')
- opt.load('lv2')
- autowaf.set_options(opt)
-
-def configure(conf):
- conf.load('compiler_c', cache=True)
- conf.load('lv2', cache=True)
- conf.load('autowaf', cache=True)
-
- conf.check_pkg('lv2 >= 1.12.1', uselib_store='LV2')
-
-def build(bld):
- bundle = 'eg-params.lv2'
-
- # Build manifest.ttl by substitution (for portable lib extension)
- bld(features = 'subst',
- source = 'manifest.ttl.in',
- target = 'lv2/%s/%s' % (bundle, 'manifest.ttl'),
- install_path = '${LV2DIR}/%s' % bundle,
- LIB_EXT = bld.env.LV2_LIB_EXT)
-
- # Copy other data files to build bundle (build/eg-params.lv2)
- for i in ['params.ttl']:
- bld(features = 'subst',
- is_copy = True,
- source = i,
- target = 'lv2/%s/%s' % (bundle, i),
- install_path = '${LV2DIR}/%s' % bundle)
-
- # Build plugin library
- obj = bld(features = 'c cshlib lv2lib',
- source = 'params.c',
- name = 'params',
- target = 'lv2/%s/params' % bundle,
- install_path = '${LV2DIR}/%s' % bundle,
- use = 'LV2')
diff --git a/plugins/eg-sampler.lv2/manifest.ttl.in b/plugins/eg-sampler.lv2/manifest.ttl.in
index 8a01428..e688256 100644
--- a/plugins/eg-sampler.lv2/manifest.ttl.in
+++ b/plugins/eg-sampler.lv2/manifest.ttl.in
@@ -15,5 +15,5 @@
<http://lv2plug.in/plugins/eg-sampler#ui>
a ui:GtkUI ;
- ui:binary <sampler_ui@LIB_EXT@> ;
+ lv2:binary <sampler_ui@LIB_EXT@> ;
rdfs:seeAlso <sampler.ttl> .
diff --git a/plugins/eg-sampler.lv2/meson.build b/plugins/eg-sampler.lv2/meson.build
new file mode 100644
index 0000000..1283a8f
--- /dev/null
+++ b/plugins/eg-sampler.lv2/meson.build
@@ -0,0 +1,48 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+plugin_sources = files('sampler.c')
+bundle_name = 'eg-sampler.lv2'
+data_filenames = ['manifest.ttl.in', 'sampler.ttl', 'click.wav']
+
+samplerate_dep = dependency('samplerate',
+ version: '>= 0.1.0',
+ required: get_option('plugins'))
+
+sndfile_dep = dependency('sndfile',
+ version: '>= 1.0.0',
+ required: get_option('plugins'))
+
+if samplerate_dep.found() and sndfile_dep.found()
+ module = shared_library(
+ 'sampler',
+ plugin_sources,
+ c_args: c_suppressions,
+ dependencies: [lv2_dep, m_dep, samplerate_dep, sndfile_dep],
+ gnu_symbol_visibility: 'hidden',
+ install: true,
+ install_dir: lv2dir / bundle_name,
+ name_prefix: '',
+ )
+
+ extension = '.' + module.full_path().split('.')[-1]
+ config = configuration_data({'LIB_EXT': extension})
+
+ foreach filename : data_filenames
+ if filename.endswith('.in')
+ configure_file(
+ configuration: config,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename.substring(0, -3),
+ )
+ else
+ configure_file(
+ copy: true,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename,
+ )
+ endif
+ endforeach
+endif
diff --git a/plugins/eg-sampler.lv2/peaks.h b/plugins/eg-sampler.lv2/peaks.h
index ca5328d..7a5f3e3 100644
--- a/plugins/eg-sampler.lv2/peaks.h
+++ b/plugins/eg-sampler.lv2/peaks.h
@@ -153,11 +153,11 @@ peaks_sender_send(PeaksSender* sender,
// eg:offset = OFFSET
lv2_atom_forge_key(forge, uris->peaks_offset);
- lv2_atom_forge_int(forge, sender->current_offset);
+ lv2_atom_forge_int(forge, (int32_t)sender->current_offset);
// eg:total = TOTAL
lv2_atom_forge_key(forge, uris->peaks_total);
- lv2_atom_forge_int(forge, sender->n_peaks);
+ lv2_atom_forge_int(forge, (int32_t)sender->n_peaks);
// eg:magnitudes = Vector<Float>(PEAK, PEAK, ...)
lv2_atom_forge_key(forge, uris->peaks_magnitudes);
diff --git a/plugins/eg-sampler.lv2/sampler.c b/plugins/eg-sampler.lv2/sampler.c
index e7fbbab..c978d2b 100644
--- a/plugins/eg-sampler.lv2/sampler.c
+++ b/plugins/eg-sampler.lv2/sampler.c
@@ -33,6 +33,7 @@
#include "lv2/urid/urid.h"
#include "lv2/worker/worker.h"
+#include <samplerate.h>
#include <sndfile.h>
#include <math.h>
@@ -80,6 +81,7 @@ typedef struct {
bool activated;
bool gain_changed;
bool sample_changed;
+ int sample_rate;
} Sampler;
/**
@@ -96,6 +98,23 @@ typedef struct {
} SampleMessage;
/**
+ Convert an interleaved audio buffer to mono.
+
+ This simply ignores the data on all channels but the first.
+*/
+static sf_count_t
+convert_to_mono(float* data, sf_count_t num_input_frames, uint32_t channels)
+{
+ sf_count_t num_output_frames = 0;
+
+ for (sf_count_t i = 0; i < num_input_frames * channels; i += channels) {
+ data[num_output_frames++] = data[i];
+ }
+
+ return num_output_frames;
+}
+
+/**
Load a new sample and return it.
Since this is of course not a real-time safe action, this is called in the
@@ -103,7 +122,7 @@ typedef struct {
not modified.
*/
static Sample*
-load_sample(LV2_Log_Logger* logger, const char* path)
+load_sample(LV2_Log_Logger* logger, const char* path, const int sample_rate)
{
lv2_log_trace(logger, "Loading %s\n", path);
@@ -115,9 +134,8 @@ load_sample(LV2_Log_Logger* logger, const char* path)
bool error = true;
if (!sndfile || !info->frames) {
lv2_log_error(logger, "Failed to open %s\n", path);
- } else if (info->channels != 1) {
- lv2_log_error(logger, "%s has %d channels\n", path, info->channels);
- } else if (!(data = (float*)malloc(sizeof(float) * info->frames))) {
+ } else if (!(data = (float*)malloc(sizeof(float) * info->frames *
+ info->channels))) {
lv2_log_error(logger, "Failed to allocate memory for sample\n");
} else {
error = false;
@@ -131,9 +149,50 @@ load_sample(LV2_Log_Logger* logger, const char* path)
}
sf_seek(sndfile, 0ul, SEEK_SET);
- sf_read_float(sndfile, data, info->frames);
+ sf_read_float(sndfile, data, info->frames * info->channels);
sf_close(sndfile);
+ if (info->channels != 1) {
+ info->frames = convert_to_mono(data, info->frames, info->channels);
+ info->channels = 1;
+ }
+
+ if (info->samplerate != sample_rate) {
+ lv2_log_trace(logger,
+ "Converting from %d Hz to %d Hz\n",
+ info->samplerate,
+ sample_rate);
+
+ const double src_ratio = (double)sample_rate / (double)info->samplerate;
+ const double output_length = ceil((double)info->frames * src_ratio);
+ const long output_frames = (long)output_length;
+ float* const output_buffer = (float*)malloc(sizeof(float) * output_frames);
+
+ SRC_DATA src_data = {
+ data,
+ output_buffer,
+ info->frames,
+ output_frames,
+ 0,
+ 0,
+ 0,
+ src_ratio,
+ };
+
+ if (src_simple(&src_data, SRC_SINC_BEST_QUALITY, 1) != 0) {
+ lv2_log_error(logger, "Sample rate conversion failed\n");
+ free(output_buffer);
+ } else {
+ // Replace original data with converted buffer
+ free(data);
+ data = output_buffer;
+ info->frames = src_data.output_frames_gen;
+ }
+ } else {
+ lv2_log_trace(
+ logger, "Sample matches the current rate of %d Hz\n", sample_rate);
+ }
+
// Fill sample struct and return it
sample->data = data;
sample->path = (char*)malloc(path_len + 1);
@@ -184,7 +243,7 @@ work(LV2_Handle instance,
}
// Load sample.
- Sample* sample = load_sample(&self->logger, path);
+ Sample* sample = load_sample(&self->logger, path, self->sample_rate);
if (sample) {
// Send new sample to run() to be applied
respond(handle, sizeof(Sample*), &sample);
@@ -280,8 +339,9 @@ instantiate(const LV2_Descriptor* descriptor,
lv2_atom_forge_init(&self->forge, self->map);
peaks_sender_init(&self->psend, self->map);
- self->gain = 1.0f;
- self->gain_dB = 0.0f;
+ self->gain = 1.0f;
+ self->gain_dB = 0.0f;
+ self->sample_rate = (int)rate;
return (LV2_Handle)self;
}
@@ -348,7 +408,9 @@ handle_event(Sampler* self, LV2_Atom_Event* ev)
if (!property) {
lv2_log_error(&self->logger, "Set message with no property\n");
return;
- } else if (property->type != uris->atom_URID) {
+ }
+
+ if (property->type != uris->atom_URID) {
lv2_log_error(&self->logger, "Set property is not a URID\n");
return;
}
@@ -438,20 +500,19 @@ run(LV2_Handle instance, uint32_t sample_count)
// Start a sequence in the notify output port.
lv2_atom_forge_sequence_head(&self->forge, &self->notify_frame, 0);
- // Send update to UI if gain or sample has changed due to state restore
- if (self->gain_changed || self->sample_changed) {
+ // Send update to UI if gain has changed due to state restore
+ if (self->gain_changed) {
lv2_atom_forge_frame_time(&self->forge, 0);
+ write_set_gain(&self->forge, &self->uris, self->gain_dB);
+ self->gain_changed = false;
+ }
- if (self->gain_changed) {
- write_set_gain(&self->forge, &self->uris, self->gain_dB);
- self->gain_changed = false;
- }
-
- if (self->sample_changed) {
- write_set_file(
- &self->forge, &self->uris, self->sample->path, self->sample->path_len);
- self->sample_changed = false;
- }
+ // Send update to UI if sample has changed due to state restore
+ if (self->sample_changed) {
+ lv2_atom_forge_frame_time(&self->forge, 0);
+ write_set_file(
+ &self->forge, &self->uris, self->sample->path, self->sample->path_len);
+ self->sample_changed = false;
}
// Iterate over incoming events, emitting audio along the way
@@ -553,10 +614,13 @@ restore(LV2_Handle instance,
uint32_t valflags = 0;
const void* value =
retrieve(handle, self->uris.eg_sample, &size, &type, &valflags);
+
if (!value) {
lv2_log_error(&self->logger, "Missing eg:sample\n");
return LV2_STATE_ERR_NO_PROPERTY;
- } else if (type != self->uris.atom_Path) {
+ }
+
+ if (type != self->uris.atom_Path) {
lv2_log_error(&self->logger, "Non-path eg:sample\n");
return LV2_STATE_ERR_BAD_TYPE;
}
@@ -569,7 +633,7 @@ restore(LV2_Handle instance,
if (!self->activated || !schedule) {
// No scheduling available, load sample immediately
lv2_log_trace(&self->logger, "Synchronous restore\n");
- Sample* sample = load_sample(&self->logger, path);
+ Sample* sample = load_sample(&self->logger, path, self->sample_rate);
if (sample) {
free_sample(self, self->sample);
self->sample = sample;
@@ -593,11 +657,14 @@ restore(LV2_Handle instance,
// Get param:gain from state
value = retrieve(handle, self->uris.param_gain, &size, &type, &valflags);
+
if (!value) {
// Not an error, since older versions did not save this property
lv2_log_note(&self->logger, "Missing param:gain\n");
return LV2_STATE_SUCCESS;
- } else if (type != self->uris.atom_Float) {
+ }
+
+ if (type != self->uris.atom_Float) {
lv2_log_error(&self->logger, "Non-float param:gain\n");
return LV2_STATE_ERR_BAD_TYPE;
}
@@ -614,11 +681,15 @@ extension_data(const char* uri)
{
static const LV2_State_Interface state = {save, restore};
static const LV2_Worker_Interface worker = {work, work_response, NULL};
+
if (!strcmp(uri, LV2_STATE__interface)) {
return &state;
- } else if (!strcmp(uri, LV2_WORKER__interface)) {
+ }
+
+ if (!strcmp(uri, LV2_WORKER__interface)) {
return &worker;
}
+
return NULL;
}
diff --git a/plugins/eg-sampler.lv2/sampler_ui.c b/plugins/eg-sampler.lv2/sampler_ui.c
index 533e720..630fc22 100644
--- a/plugins/eg-sampler.lv2/sampler_ui.c
+++ b/plugins/eg-sampler.lv2/sampler_ui.c
@@ -365,7 +365,7 @@ port_event(LV2UI_Handle handle,
const LV2_Atom_Object* obj = (const LV2_Atom_Object*)atom;
if (obj->body.otype == ui->uris.patch_Set) {
const char* path = read_set_file(&ui->uris, obj);
- if (path && (!ui->filename || strcmp(path, ui->filename))) {
+ if (path && (!ui->filename || !!strcmp(path, ui->filename))) {
g_free(ui->filename);
ui->filename = g_strdup(path);
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(ui->file_button),
@@ -447,11 +447,15 @@ extension_data(const char* uri)
{
static const LV2UI_Show_Interface show = {ui_show, ui_hide};
static const LV2UI_Idle_Interface idle = {ui_idle};
+
if (!strcmp(uri, LV2_UI__showInterface)) {
return &show;
- } else if (!strcmp(uri, LV2_UI__idleInterface)) {
+ }
+
+ if (!strcmp(uri, LV2_UI__idleInterface)) {
return &idle;
}
+
return NULL;
}
diff --git a/plugins/eg-sampler.lv2/waf b/plugins/eg-sampler.lv2/waf
deleted file mode 120000
index 59a1ac9..0000000
--- a/plugins/eg-sampler.lv2/waf
+++ /dev/null
@@ -1 +0,0 @@
-../../waf \ No newline at end of file
diff --git a/plugins/eg-sampler.lv2/wscript b/plugins/eg-sampler.lv2/wscript
deleted file mode 100644
index 8c640c1..0000000
--- a/plugins/eg-sampler.lv2/wscript
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/env python
-from waflib.extras import autowaf as autowaf
-import re
-
-# Variables for 'waf dist'
-APPNAME = 'eg-sampler.lv2'
-VERSION = '1.0.0'
-
-# Mandatory variables
-top = '.'
-out = 'build'
-
-def options(opt):
- opt.load('compiler_c')
- opt.load('lv2')
- autowaf.set_options(opt)
-
-def configure(conf):
- conf.load('compiler_c', cache=True)
- conf.load('lv2', cache=True)
- conf.load('autowaf', cache=True)
-
- conf.check_pkg('lv2 >= 1.2.1', uselib_store='LV2')
- conf.check_pkg('sndfile >= 1.0.0', uselib_store='SNDFILE')
- conf.check_pkg('gtk+-2.0 >= 2.18.0',
- uselib_store='GTK2',
- system=True,
- mandatory=False)
- conf.check(features='c cshlib', lib='m', uselib_store='M', mandatory=False)
-
-def build(bld):
- bundle = 'eg-sampler.lv2'
-
- # Build manifest.ttl by substitution (for portable lib extension)
- bld(features = 'subst',
- source = 'manifest.ttl.in',
- target = 'lv2/%s/%s' % (bundle, 'manifest.ttl'),
- install_path = '${LV2DIR}/%s' % bundle,
- LIB_EXT = bld.env.LV2_LIB_EXT)
-
- # Copy other data files to build bundle (build/eg-sampler.lv2)
- for i in ['sampler.ttl', 'click.wav']:
- bld(features = 'subst',
- is_copy = True,
- source = i,
- target = 'lv2/%s/%s' % (bundle, i),
- install_path = '${LV2DIR}/%s' % bundle)
-
- # Build plugin library
- obj = bld(features = 'c cshlib lv2lib',
- source = 'sampler.c',
- name = 'sampler',
- target = 'lv2/%s/sampler' % bundle,
- install_path = '${LV2DIR}/%s' % bundle,
- use = ['M', 'SNDFILE', 'LV2'])
-
- # Build UI library
- if bld.env.HAVE_GTK2:
- obj = bld(features = 'c cshlib lv2lib',
- source = 'sampler_ui.c',
- name = 'sampler_ui',
- target = 'lv2/%s/sampler_ui' % bundle,
- install_path = '${LV2DIR}/%s' % bundle,
- use = ['GTK2', 'LV2'])
diff --git a/plugins/eg-scope.lv2/examploscope.c b/plugins/eg-scope.lv2/examploscope.c
index ec013a1..8bc4ca1 100644
--- a/plugins/eg-scope.lv2/examploscope.c
+++ b/plugins/eg-scope.lv2/examploscope.c
@@ -249,7 +249,7 @@ run(LV2_Handle handle, uint32_t n_samples)
// Add UI state as properties
lv2_atom_forge_key(&self->forge, self->uris.ui_spp);
- lv2_atom_forge_int(&self->forge, self->ui_spp);
+ lv2_atom_forge_int(&self->forge, (int32_t)self->ui_spp);
lv2_atom_forge_key(&self->forge, self->uris.ui_amp);
lv2_atom_forge_float(&self->forge, self->ui_amp);
lv2_atom_forge_key(&self->forge, self->uris.param_sampleRate);
@@ -295,7 +295,8 @@ run(LV2_Handle handle, uint32_t n_samples)
for (uint32_t c = 0; c < self->n_channels; ++c) {
if (self->ui_active) {
// If UI is active, send raw audio data to UI
- tx_rawaudio(&self->forge, &self->uris, c, n_samples, self->input[c]);
+ tx_rawaudio(
+ &self->forge, &self->uris, (int32_t)c, n_samples, self->input[c]);
}
// If not processing audio in-place, forward audio
if (self->input[c] != self->output[c]) {
diff --git a/plugins/eg-scope.lv2/examploscope_ui.c b/plugins/eg-scope.lv2/examploscope_ui.c
index e601843..8a9b588 100644
--- a/plugins/eg-scope.lv2/examploscope_ui.c
+++ b/plugins/eg-scope.lv2/examploscope_ui.c
@@ -261,7 +261,9 @@ on_expose_event(GtkWidget* widget, GdkEventExpose* ev, gpointer data)
for (uint32_t i = start; i < end; ++i) {
if (i == chn->idx) {
continue;
- } else if (i % 2) {
+ }
+
+ if (i % 2) {
cairo_line_to(cr, i - .5, CYPOS(chn->data_min[i]));
cairo_line_to(cr, i - .5, CYPOS(chn->data_max[i]));
++pathlength;
diff --git a/plugins/eg-scope.lv2/manifest.ttl.in b/plugins/eg-scope.lv2/manifest.ttl.in
index a64aff1..66c3c9d 100644
--- a/plugins/eg-scope.lv2/manifest.ttl.in
+++ b/plugins/eg-scope.lv2/manifest.ttl.in
@@ -17,5 +17,5 @@
# ==== Gtk 2.0 UI ====
<http://lv2plug.in/plugins/eg-scope#ui>
a ui:GtkUI ;
- ui:binary <examploscope_ui@LIB_EXT@> ;
+ lv2:binary <examploscope_ui@LIB_EXT@> ;
rdfs:seeAlso <examploscope.ttl> .
diff --git a/plugins/eg-scope.lv2/meson.build b/plugins/eg-scope.lv2/meson.build
new file mode 100644
index 0000000..ecf01b2
--- /dev/null
+++ b/plugins/eg-scope.lv2/meson.build
@@ -0,0 +1,41 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+plugin_sources = files('examploscope.c')
+bundle_name = 'eg-scope.lv2'
+data_filenames = ['manifest.ttl.in', 'examploscope.ttl.in']
+
+module = shared_library(
+ 'examploscope',
+ plugin_sources,
+ c_args: c_suppressions,
+ dependencies: [lv2_dep, m_dep],
+ gnu_symbol_visibility: 'hidden',
+ install: true,
+ install_dir: lv2dir / bundle_name,
+ name_prefix: '',
+)
+
+config = configuration_data(
+ {
+ 'LIB_EXT': '.' + module.full_path().split('.')[-1],
+ }
+)
+
+foreach filename : data_filenames
+ if filename.endswith('.in')
+ configure_file(
+ configuration: config,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename.substring(0, -3),
+ )
+ else
+ configure_file(
+ copy: true,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename,
+ )
+ endif
+endforeach
diff --git a/plugins/eg-scope.lv2/wscript b/plugins/eg-scope.lv2/wscript
deleted file mode 100644
index 4333502..0000000
--- a/plugins/eg-scope.lv2/wscript
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/env python
-from waflib.extras import autowaf as autowaf
-import re
-
-# Variables for 'waf dist'
-APPNAME = 'eg-scope.lv2'
-VERSION = '1.0.0'
-
-# Mandatory variables
-top = '.'
-out = 'build'
-
-def options(opt):
- opt.load('compiler_c')
- opt.load('lv2')
- autowaf.set_options(opt)
-
-def configure(conf):
- conf.load('compiler_c', cache=True)
- conf.load('lv2', cache=True)
- conf.load('autowaf', cache=True)
-
- conf.check_pkg('lv2 >= 1.2.1', uselib_store='LV2')
- conf.check_pkg('cairo >= 1.8.10', uselib_store='CAIRO')
- conf.check_pkg('gtk+-2.0 >= 2.18.0',
- uselib_store='GTK2',
- system=True,
- mandatory=False)
-
-def build(bld):
- bundle = 'eg-scope.lv2'
-
- # Build manifest.ttl by substitution (for portable lib extension)
- for i in ['manifest.ttl', 'examploscope.ttl']:
- bld(features = 'subst',
- source = i + '.in',
- target = 'lv2/%s/%s' % (bundle, i),
- install_path = '${LV2DIR}/%s' % bundle,
- LIB_EXT = bld.env.LV2_LIB_EXT)
-
- # Build plugin library
- obj = bld(features = 'c cshlib lv2lib',
- source = 'examploscope.c',
- name = 'examploscope',
- target = 'lv2/%s/examploscope' % bundle,
- install_path = '${LV2DIR}/%s' % bundle,
- use = 'LV2')
-
- # Build UI library
- if bld.env.HAVE_GTK2:
- obj = bld(features = 'c cshlib lv2lib',
- source = 'examploscope_ui.c',
- name = 'examploscope_ui',
- target = 'lv2/%s/examploscope_ui' % bundle,
- install_path = '${LV2DIR}/%s' % bundle,
- use = 'GTK2 CAIRO LV2')
diff --git a/plugins/literasc.py b/plugins/literasc.py
index 0bcd8f2..74b13a7 100755
--- a/plugins/literasc.py
+++ b/plugins/literasc.py
@@ -1,127 +1,143 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-# Literasc, a simple literate programming tool for C, C++, and Turtle.
-# Copyright 2012 David Robillard <d@drobilla.net>
-#
-# Unlike many LP tools, this tool uses normal source code as input, there is no
-# tangle/weave and no special file format. The literate parts of the program
-# are written in comments, which are emitted as paragraphs of regular text
-# interleaved with code. Asciidoc is both the comment and output syntax.
+#!/usr/bin/env python3
+
+# Copyright 2012-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: ISC
+
+"""
+A simple literate programming tool for C, C++, and Turtle.
+
+Unlike many LP tools, this tool uses normal source code as input, there is no
+tangle/weave and no special file format. The literate parts of the program are
+written in comments, which are emitted as paragraphs of regular text
+interleaved with code. Asciidoc is both the comment and output syntax.
+"""
import os
import re
import sys
+
def format_text(text):
- 'Format a text (comment) fragment and return it as a marked up string'
- return '\n\n' + re.sub('\n *', '\n', text.strip()) + '\n\n'
+ "Format a text (comment) fragment and return it as a marked up string."
+ return "\n\n" + re.sub("\n *", "\n", text.strip()) + "\n\n"
+
def format_code(lang, code):
- if code.strip() == '':
+ "Format a block of code and return it as a marked up string."
+
+ if code.strip() == "":
return code
- head = '[source,%s]' % lang
- sep = '-' * len(head) + '\n'
- return head + '\n' + sep + code.strip('\n') + '\n' + sep
+ head = f"[source,{lang}]"
+ code = code.strip("\n")
+ sep = "-" * len(head)
+ return "\n".join([head, sep, code, sep]) + "\n"
+
-def format_c_source(filename, file):
- output = '=== %s ===\n' % os.path.basename(filename)
- chunk = ''
- prev_c = 0
- in_comment = False
+def format_c_source(filename, in_file):
+ "Format an annotated C source file as a marked up string."
+
+ output = f"=== {os.path.basename(filename)} ===\n"
+ chunk = ""
+ prev_c = 0
+ in_comment = False
in_comment_start = False
- n_stars = 0
- code = ''
- for line in file:
- code += line
+ n_stars = 0
+ code = "".join(in_file)
# Skip initial license comment
- if code[0:2] == '/*':
- code = code[code.find('*/') + 2:]
+ if code[0:2] == "/*":
+ end = code.find("*/") + 2
+ code = code[end:]
- for c in code:
- if prev_c == '/' and c == '*':
+ def last_chunk(chunk):
+ length = len(chunk) - 1
+ return chunk[0:length]
+
+ for char in code:
+ if prev_c == "/" and char == "*":
in_comment_start = True
n_stars = 1
elif in_comment_start:
- if c == '*':
+ if char == "*":
n_stars += 1
else:
if n_stars > 1:
- output += format_code('c', chunk[0:len(chunk) - 1])
- chunk = ''
+ output += format_code("c", last_chunk(chunk))
+ chunk = ""
in_comment = True
else:
- chunk += '*' + c
+ chunk += "*" + char
in_comment_start = False
- elif in_comment and prev_c == '*' and c == '/':
+ elif in_comment and prev_c == "*" and char == "/":
if n_stars > 1:
- output += format_text(chunk[0:len(chunk) - 1])
+ output += format_text(last_chunk(chunk))
else:
- output += format_code('c', '/* ' + chunk[0:len(chunk) - 1] + '*/')
+ output += format_code("c", "/* " + last_chunk(chunk) + "*/")
in_comment = False
in_comment_start = False
- chunk = ''
- elif in_comment_start and c == '*':
- n_stars += 1
+ chunk = ""
else:
- chunk += c
- prev_c = c
+ chunk += char
+
+ prev_c = char
+
+ return output + format_code("c", chunk)
- return output + format_code('c', chunk)
-def format_ttl_source(filename, file):
- output = '=== %s ===\n' % os.path.basename(filename)
+def format_ttl_source(filename, in_file):
+ "Format an annotated Turtle source file as a marked up string."
+
+ output = f"=== {os.path.basename(filename)} ===\n"
in_comment = False
- chunk = ''
- for line in file:
- is_comment = line.strip().startswith('#')
+ chunk = ""
+ for line in in_file:
+ is_comment = line.strip().startswith("#")
if in_comment:
if is_comment:
- chunk += line.strip().lstrip('# ') + ' \n'
+ chunk += line.strip().lstrip("# ") + " \n"
else:
output += format_text(chunk)
in_comment = False
chunk = line
else:
if is_comment:
- output += format_code('turtle', chunk)
+ output += format_code("turtle", chunk)
in_comment = True
- chunk = line.strip().lstrip('# ') + ' \n'
+ chunk = line.strip().lstrip("# ") + " \n"
else:
chunk += line
if in_comment:
return output + format_text(chunk)
- else:
- return output + format_code('turtle', chunk)
+
+ return output + format_code("turtle", chunk)
+
def gen(out, filenames):
+ "Write markup generated from filenames to an output file."
+
for filename in filenames:
- file = open(filename)
- if not file:
- sys.stderr.write('Failed to open file %s\n' % filename)
- continue
-
- if filename.endswith('.c') or filename.endswith('.h'):
- out.write(format_c_source(filename, file))
- elif filename.endswith('.ttl') or filename.endswith('.ttl.in'):
- out.write(format_ttl_source(filename, file))
- elif filename.endswith('.txt'):
- for line in file:
- out.write(line)
- out.write('\n')
- else:
- sys.stderr.write("Unknown source format `%s'" % (
- filename[filename.find('.'):]))
+ with open(filename, "r", encoding="utf-8") as in_file:
+ if filename.endswith(".c") or filename.endswith(".h"):
+ out.write(format_c_source(filename, in_file))
+ elif filename.endswith(".ttl") or filename.endswith(".ttl.in"):
+ out.write(format_ttl_source(filename, in_file))
+ elif filename.endswith(".txt"):
+ for line in in_file:
+ out.write(line)
+ out.write("\n")
+ else:
+ sys.stderr.write(
+ f"Unknown source format `{filename.splitext()[1]}`\n"
+ )
- file.close()
if __name__ == "__main__":
if len(sys.argv) < 2:
- sys.stderr.write('Usage: %s FILENAME...\n' % sys.argv[1])
+ sys.stderr.write(f"Usage: {sys.argv[0]} OUT_FILE IN_FILE...\n")
sys.exit(1)
- gen(sys.argv[1:])
+ with open(sys.argv[1], "w", encoding="utf-8") as out_file:
+ gen(out_file, sys.argv[2:])
diff --git a/plugins/meson.build b/plugins/meson.build
new file mode 100644
index 0000000..08b3feb
--- /dev/null
+++ b/plugins/meson.build
@@ -0,0 +1,82 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+if not get_option('plugins').disabled()
+ m_dep = cc.find_library('m', required: false)
+
+ subdir('eg-amp.lv2')
+ subdir('eg-fifths.lv2')
+ subdir('eg-metro.lv2')
+ subdir('eg-midigate.lv2')
+ subdir('eg-params.lv2')
+ subdir('eg-sampler.lv2')
+ subdir('eg-scope.lv2')
+endif
+
+if not get_option('docs').disabled()
+ literasc_py = files('literasc.py')
+ asciidoc = find_program('asciidoc', required: get_option('docs'))
+
+ if asciidoc.found()
+ book_inputs = files(
+ 'README.txt',
+ 'eg-amp.lv2/README.txt',
+ 'eg-amp.lv2/amp.c',
+ 'eg-amp.lv2/amp.ttl',
+ 'eg-fifths.lv2/README.txt',
+ 'eg-fifths.lv2/fifths.c',
+ 'eg-fifths.lv2/fifths.ttl',
+ 'eg-fifths.lv2/uris.h',
+ 'eg-metro.lv2/README.txt',
+ 'eg-metro.lv2/metro.c',
+ 'eg-metro.lv2/metro.ttl',
+ 'eg-midigate.lv2/README.txt',
+ 'eg-midigate.lv2/midigate.c',
+ 'eg-midigate.lv2/midigate.ttl',
+ 'eg-params.lv2/README.txt',
+ 'eg-params.lv2/params.c',
+ 'eg-params.lv2/params.ttl',
+ 'eg-params.lv2/state_map.h',
+ 'eg-sampler.lv2/README.txt',
+ 'eg-sampler.lv2/atom_sink.h',
+ 'eg-sampler.lv2/peaks.h',
+ 'eg-sampler.lv2/sampler.c',
+ 'eg-sampler.lv2/sampler.ttl',
+ 'eg-sampler.lv2/sampler_ui.c',
+ 'eg-sampler.lv2/uris.h',
+ 'eg-scope.lv2/README.txt',
+ 'eg-scope.lv2/examploscope.c',
+ 'eg-scope.lv2/examploscope_ui.c',
+ 'eg-scope.lv2/uris.h',
+ )
+
+ # Compile book sources into book.txt asciidoc source
+ book_txt = custom_target(
+ 'book.txt',
+ command: [
+ literasc_py,
+ '@OUTPUT@',
+ '@INPUT@',
+ ],
+ input: book_inputs,
+ output: 'book.txt',
+ )
+
+ # Run asciidoc to generate book.html
+ book_html = custom_target(
+ 'book.html',
+ build_by_default: true,
+ command: [
+ asciidoc,
+ '-a', 'stylesdir=' + lv2_source_root / 'doc' / 'style',
+ '-a', 'source-highlighter=pygments',
+ '-a', 'pygments-style=' + lv2_source_root / 'doc' / 'style' / 'style.css',
+ '-b', 'html',
+ '-o', '@OUTPUT@',
+ '@INPUT@',
+ ],
+ input: book_txt,
+ output: 'book.html',
+ )
+ endif
+endif
diff --git a/plugins/wscript b/plugins/wscript
deleted file mode 100644
index f5f6571..0000000
--- a/plugins/wscript
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-import os
-
-from waflib.extras import autowaf as autowaf
-import waflib.Logs as Logs
-
-import literasc
-
-def confgure(conf):
- pass
-
-def bld_book_src(task):
- filenames = []
- for i in task.inputs:
- filenames += [i.abspath()]
-
- literasc.gen(open(task.outputs[0].abspath(), 'w'), filenames)
-
-def build(bld):
- files = [bld.path.find_node('README.txt')]
- for i in ['eg-amp.lv2',
- 'eg-midigate.lv2',
- 'eg-fifths.lv2',
- 'eg-metro.lv2',
- 'eg-sampler.lv2',
- 'eg-scope.lv2',
- 'eg-params.lv2']:
- files += bld.path.ant_glob('%s/*.txt' % i)
- files += bld.path.ant_glob('%s/manifest.ttl*' % i)
- files += bld.path.ant_glob('%s/*.ttl' % i)
- files += bld.path.ant_glob('%s/*.c' % i)
- files += bld.path.ant_glob('%s/*.h' % i)
-
- # Compile book sources into book.txt asciidoc source
- bld(rule = bld_book_src,
- source = files,
- target = 'book.txt')
-
- # Run asciidoc to generate book.html
- stylesdir = bld.path.find_node('../doc/').abspath()
- pygments_style = bld.path.find_node('../doc/style.css').abspath()
- bld(rule = 'asciidoc -a stylesdir=%s -a source-highlighter=pygments -a pygments-style=%s -b html -o ${TGT} ${SRC}' % (
- stylesdir, pygments_style),
- source = 'book.txt',
- target = 'book.html')
diff --git a/schemas.lv2/dcs.ttl b/schemas.lv2/dcs.ttl
index b961190..4c62ed9 100644
--- a/schemas.lv2/dcs.ttl
+++ b/schemas.lv2/dcs.ttl
@@ -1,266 +1,67 @@
-# This ontology.
-@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix dcterms: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
-# Related
-@prefix event: <http://purl.org/NET/c4dm/event.owl#> .
-@prefix doap: <http://usefulinc.com/ns/doap#> .
-@prefix dbug: <http://ontologi.es/doap-bugs#> .
-
-# Stock imports.
-@prefix dct: <http://purl.org/dc/terms/> .
-@prefix foaf: <http://xmlns.com/foaf/0.1/> .
-@prefix owl: <http://www.w3.org/2002/07/owl#> .
-@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
-@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
-
-## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
+<>
+ rdfs:comment "Minimal DOAP Change Sets vocabulary used by LV2." .
-<http://tobyinkster.co.uk/#i> a foaf:Person .
+<http://tobyinkster.co.uk/#i>
+ a foaf:Person .
dcs:
a owl:Ontology ;
- rdfs:label "DOAP Change Sets"@en ;
- dct:description "An ontology that extends DOAP to describe changesets."@en ;
- dct:created "2010-01-08"^^xsd:date ;
- dct:issued "2010-01-08"^^xsd:date ;
- dct:modified "2010-01-08"^^xsd:date ,
- "2010-01-27"^^xsd:date ,
- "2011-02-15"^^xsd:date , # dcs:Documentation, dcs:Packaging, dcs:SecurityFix, dcs:SecurityRegression
- "2012-04-25"^^xsd:date , # dcs:thanks
- "2012-06-20"^^xsd:date , # dcs:released-by
- "2013-09-03"^^xsd:date , # dcs:Tests, dcs:BackCompat
- "2015-01-15"^^xsd:date , # Syntax errors, add description
- "2015-04-05"^^xsd:date ; # use dcterms, trim imports (drobilla, for LV2)
- dct:creator <http://tobyinkster.co.uk/#i> .
-
-<>
- a foaf:Document ;
- foaf:primaryTopic dcs: .
-
-dcs:ChangeSet
- a owl:Class ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "Change Set"@en ;
- rdfs:comment "A collection of changes. Not necessarily disjoint with foaf:Document!"@en ;
- rdfs:subClassOf rdf:Bag .
-
-dcs:ToDoList
- a owl:Class ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "To-Do List"@en ;
- rdfs:comment "A collection of planned changes."@en ;
- rdfs:subClassOf dcs:ChangeSet .
-
-dcs:WishList
- a owl:Class ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "Wish List"@en ;
- rdfs:comment "A collection of desired changes."@en ;
- rdfs:subClassOf dcs:ChangeSet .
+ dcterms:contributor <http://drobilla.net/drobilla#me> ;
+ dcterms:created "2010-01-08"^^xsd:date ;
+ dcterms:creator <http://tobyinkster.co.uk/#i> ;
+ dcterms:description "An ontology that extends DOAP to describe changesets." ;
+ dcterms:modified "2022-07-07"^^xsd:date ;
+ rdfs:label "DOAP Change Sets" .
dcs:Change
a owl:Class ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "Change"@en ;
- rdfs:comment "A change to something. Use rdfs:label to briefly describe the change. Use rdfs:comment for additional information."@en .
-
-dcs:Addition
- a owl:Class ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "Addition"@en ;
- rdfs:comment "A change that added a new feature."@en ;
- rdfs:subClassOf dcs:Change .
-
-dcs:Removal
- a owl:Class ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "Addition"@en ;
- rdfs:comment "A change that removed a feature."@en ;
- rdfs:subClassOf dcs:Change .
+ rdfs:comment "A change to something." ;
+ rdfs:label "Change" ;
+ rdfs:subClassOf [
+ a owl:Restriction ;
+ rdfs:comment "A change must have a plain literal label." ;
+ owl:onProperty rdfs:label ;
+ owl:someValuesFrom rdf:PlainLiteral
+ ] .
-dcs:Bugfix
- a owl:Class ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "Bugfix"@en ;
- rdfs:comment "A change that fixed a problem with an existing feature."@en ;
- rdfs:subClassOf dcs:Change .
-
-dcs:Update
- a owl:Class ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "Update"@en ;
- rdfs:comment "A change that brought a feature into compliance with policy or other changes in the external world."@en ;
- rdfs:subClassOf dcs:Change .
-
-dcs:Regression
- a owl:Class ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "Regression"@en ;
- rdfs:comment "A change that caused a problem with an existing feature."@en ;
- rdfs:subClassOf dcs:Change .
-
-dcs:Documentation
- a owl:Class ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "Documentation Change"@en ;
- rdfs:subClassOf dcs:Change .
-
-dcs:Packaging
- a owl:Class ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "Packaging Change"@en ;
- rdfs:subClassOf dcs:Change .
-
-dcs:SecurityFix
- a owl:Class ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "Security Fix"@en ;
- rdfs:comment "A change that fixed or improved a security problem."@en ;
- rdfs:subClassOf dcs:Change .
-
-dcs:SecurityRegression
- a owl:Class ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "Security Regression"@en ;
- rdfs:comment "A change that created or worsened a security problem."@en ;
- rdfs:subClassOf dcs:Change , dcs:Regression .
-
-dcs:Tests
+dcs:ChangeSet
a owl:Class ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "Tests"@en ;
- rdfs:comment "A change to the test suite."@en ;
- rdfs:subClassOf dcs:Change.
+ rdfs:comment "A collection of changes." ;
+ rdfs:label "Change Set" ;
+ rdfs:subClassOf rdf:Bag .
-dcs:BackCompat
- a owl:Class ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "Backwards Compatibility"@en ;
- rdfs:comment "A change that breaks backwards compatibility, changing documented or tested behaviour."@en ;
- rdfs:subClassOf dcs:Change.
+dcs:blame
+ a owl:ObjectProperty ;
+ rdfs:label "blame" ;
+ rdfs:subPropertyOf dcs:thanks .
dcs:changeset
a owl:ObjectProperty ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "change set"@en ;
- rdfs:comment "A change set may be associated with a particular software version in which those changes were released; or with an event which caused those changes."@en ;
+ rdfs:comment "The change set of a version." ;
rdfs:domain doap:Version ;
+ rdfs:label "change set" ;
rdfs:range dcs:ChangeSet .
-dcs:versus
- a owl:ObjectProperty ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "versus"@en ;
- rdfs:comment "The previous version or event which a changeset has changed from."@en ;
- rdfs:domain dcs:ChangeSet ;
- rdfs:range doap:Version .
-
dcs:item
a owl:ObjectProperty ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "item"@en ;
- rdfs:comment "A change within a change set."@en ;
+ rdfs:comment "A change in a change set." ;
rdfs:domain dcs:ChangeSet ;
+ rdfs:label "item" ;
rdfs:range dcs:Change ;
rdfs:subPropertyOf rdfs:member .
-dcs:file
- a owl:ObjectProperty ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "file"@en ;
- rdfs:comment "A file involved in the change."@en ;
- rdfs:domain dcs:Change .
-
-dbug:Issue
- a rdfs:Class ;
- rdfs:label "Issue"@en .
-
-dcs:fixes
- a owl:ObjectProperty ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "fixes"@en ;
- rdfs:comment "A bug fixed by the change."@en ;
- rdfs:domain dcs:Bugfix ;
- rdfs:range dbug:Issue .
-
-dcs:implements
- a owl:ObjectProperty ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "implements"@en ;
- rdfs:domain dcs:Addition ;
- rdfs:range doap:Specification .
-
-dcs:restores
- a owl:ObjectProperty ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "restores"@en ;
- rdfs:comment "An association between a regression and a later bugfix that fixes it."@en ;
- rdfs:domain dcs:Bugfix ;
- rdfs:range dcs:Regression .
-
-dcs:blame
- a owl:ObjectProperty ;
- rdfs:isDefinedBy dcs: ;
- rdfs:subPropertyOf dcs:thanks ;
- rdfs:label "blame"@en .
-
dcs:thanks
a owl:ObjectProperty ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "thanks"@en ;
- rdfs:comment "More general than dcs:blame - could be used e.g. to indicate who financially sponsored a new feature."@en ;
rdfs:domain dcs:Change ;
+ rdfs:label "thanks" ;
rdfs:range foaf:Agent .
-dcs:checkin
- a owl:DatatypeProperty ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "checkin"@en ;
- rdfs:comment "The identifier used by the project's version control system that records when this change was made."@en ;
- rdfs:domain dcs:Change ;
- rdfs:range xsd:string .
-
-dcs:milestone
- a owl:ObjectProperty ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "milestone"@en ;
- rdfs:domain dcs:ChangeSet ;
- rdfs:range doap:Version .
-
-dcs:tasks
- a owl:ObjectProperty ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "tasks"@en ;
- rdfs:domain foaf:Agent ;
- rdfs:range dcs:ToDoList .
-
-dcs:wishes
- a owl:ObjectProperty ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "wishes"@en ;
- rdfs:domain foaf:Person ;
- rdfs:range dcs:WishList .
-
-dcs:requires
- a owl:ObjectProperty ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "requires"@en ;
- rdfs:comment "Indicates that the subject Change cannot/could not be completed without the object Change."@en ;
- rdfs:domain dcs:Change ;
- rdfs:range dcs:Change .
-
-dcs:timescale
- a owl:DatatypeProperty ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "timescale"@en ;
- rdfs:comment "Human-readable description of the approximate time a change/feature should be complete by."@en ;
- rdfs:domain dcs:Change ;
- rdfs:range xsd:string .
-
-dcs:released-by
- a owl:ObjectProperty ;
- rdfs:isDefinedBy dcs: ;
- rdfs:label "released by"@en ;
- rdfs:domain doap:Version ;
- rdfs:range foaf:Person .
diff --git a/schemas.lv2/dct.ttl b/schemas.lv2/dcterms.ttl
index d8fd196..f6a5d06 100644
--- a/schemas.lv2/dct.ttl
+++ b/schemas.lv2/dcterms.ttl
@@ -337,3 +337,4 @@ dcterms:title
rdfs:isDefinedBy dcterms: ;
rdfs:label "title"@en-us ;
rdfs:range rdfs:Literal .
+
diff --git a/schemas.lv2/doap.ttl b/schemas.lv2/doap.ttl
index c8daf59..b806d31 100644
--- a/schemas.lv2/doap.ttl
+++ b/schemas.lv2/doap.ttl
@@ -1,4 +1,4 @@
-@prefix dct: <http://purl.org/dc/terms/> .
+@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix doap: <http://usefulinc.com/ns/doap#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@@ -14,7 +14,7 @@ doap:
décrit en utilisant RDF Schema du W3C et OWL."""@fr ,
"Slovník Description of a Project (DOAP, Popis projektu), popsaný použitím W3C RDF Schema a Web Ontology Language."@cs ,
"The Description of a Project (DOAP) vocabulary, described using W3C RDF Schema and the Web Ontology Language." ;
- dct:title "Description of a Project (DOAP) vocabulary" ;
+ dcterms:title "Description of a Project (DOAP) vocabulary" ;
owl:imports foaf: ;
foaf:maker [
a foaf:Person ;
diff --git a/schemas.lv2/foaf.ttl b/schemas.lv2/foaf.ttl
index 83a1e7e..17dcc13 100644
--- a/schemas.lv2/foaf.ttl
+++ b/schemas.lv2/foaf.ttl
@@ -2,578 +2,611 @@
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
-@prefix dct: <http://purl.org/dc/terms/> .
+@prefix dcterms: <http://purl.org/dc/terms/> .
-<http://xmlns.com/foaf/0.1/>
- a owl:Ontology ;
- dct:description "The Friend of a Friend (FOAF) RDF vocabulary, described using W3C RDF Schema and the Web Ontology Language." ;
- dct:title "Friend of a Friend (FOAF) vocabulary" ;
+foaf:
+ a owl:Ontology ;
+ dcterms:description "The Friend of a Friend (FOAF) RDF vocabulary, described using W3C RDF Schema and the Web Ontology Language." ;
+ dcterms:title "Friend of a Friend (FOAF) vocabulary" ;
rdfs:comment "This version of the FOAF vocabulary has been slightly trimmed for LV2." .
foaf:Agent
- a rdfs:Class, owl:Class ;
- rdfs:comment "An agent (eg. person, group, software or physical artifact)." ;
- rdfs:label "Agent" ;
- owl:equivalentClass <http://purl.org/dc/terms/Agent> .
+ a rdfs:Class ,
+ owl:Class ;
+ rdfs:comment "An agent (eg. person, group, software or physical artifact)." ;
+ rdfs:label "Agent" ;
+ owl:equivalentClass dcterms:Agent .
foaf:Document
- a rdfs:Class, owl:Class ;
- rdfs:comment "A document." ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "Document" ;
- owl:disjointWith foaf:Organization, foaf:Project .
+ a rdfs:Class ,
+ owl:Class ;
+ rdfs:comment "A document." ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "Document" ;
+ owl:disjointWith foaf:Organization ,
+ foaf:Project .
foaf:Group
- a rdfs:Class, owl:Class ;
- rdfs:comment "A class of Agents." ;
- rdfs:label "Group" ;
- rdfs:subClassOf foaf:Agent .
+ a rdfs:Class ,
+ owl:Class ;
+ rdfs:comment "A class of Agents." ;
+ rdfs:label "Group" ;
+ rdfs:subClassOf foaf:Agent .
foaf:Image
- a rdfs:Class, owl:Class ;
- rdfs:comment "An image." ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "Image" ;
- rdfs:subClassOf foaf:Document .
+ a rdfs:Class ,
+ owl:Class ;
+ rdfs:comment "An image." ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "Image" ;
+ rdfs:subClassOf foaf:Document .
foaf:LabelProperty
- a rdfs:Class, owl:Class ;
- rdfs:comment "A foaf:LabelProperty is any RDF property with textual values that serve as labels." ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "Label Property" .
+ a rdfs:Class ,
+ owl:Class ;
+ rdfs:comment "A foaf:LabelProperty is any RDF property with textual values that serve as labels." ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "Label Property" .
foaf:OnlineAccount
- a rdfs:Class, owl:Class ;
- rdfs:comment "An online account." ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "Online Account" ;
- rdfs:subClassOf owl:Thing .
+ a rdfs:Class ,
+ owl:Class ;
+ rdfs:comment "An online account." ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "Online Account" ;
+ rdfs:subClassOf owl:Thing .
foaf:OnlineChatAccount
- a rdfs:Class, owl:Class ;
- rdfs:comment "An online chat account." ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "Online Chat Account" ;
- rdfs:subClassOf foaf:OnlineAccount .
+ a rdfs:Class ,
+ owl:Class ;
+ rdfs:comment "An online chat account." ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "Online Chat Account" ;
+ rdfs:subClassOf foaf:OnlineAccount .
foaf:OnlineEcommerceAccount
- a rdfs:Class, owl:Class ;
- rdfs:comment "An online e-commerce account." ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "Online E-commerce Account" ;
- rdfs:subClassOf foaf:OnlineAccount .
+ a rdfs:Class ,
+ owl:Class ;
+ rdfs:comment "An online e-commerce account." ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "Online E-commerce Account" ;
+ rdfs:subClassOf foaf:OnlineAccount .
foaf:OnlineGamingAccount
- a rdfs:Class, owl:Class ;
- rdfs:comment "An online gaming account." ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "Online Gaming Account" ;
- rdfs:subClassOf foaf:OnlineAccount .
+ a rdfs:Class ,
+ owl:Class ;
+ rdfs:comment "An online gaming account." ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "Online Gaming Account" ;
+ rdfs:subClassOf foaf:OnlineAccount .
foaf:Organization
- a rdfs:Class, owl:Class ;
- rdfs:comment "An organization." ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "Organization" ;
- rdfs:subClassOf foaf:Agent ;
- owl:disjointWith foaf:Document, foaf:Person .
+ a rdfs:Class ,
+ owl:Class ;
+ rdfs:comment "An organization." ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "Organization" ;
+ rdfs:subClassOf foaf:Agent ;
+ owl:disjointWith foaf:Document ,
+ foaf:Person .
foaf:Person
- a rdfs:Class, owl:Class ;
- rdfs:comment "A person." ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "Person" ;
- rdfs:subClassOf foaf:Agent ;
- owl:disjointWith foaf:Organization, foaf:Project .
+ a rdfs:Class ,
+ owl:Class ;
+ rdfs:comment "A person." ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "Person" ;
+ rdfs:subClassOf foaf:Agent ;
+ owl:disjointWith foaf:Organization ,
+ foaf:Project .
foaf:PersonalProfileDocument
- a rdfs:Class, owl:Class ;
- rdfs:comment "A personal profile RDF document." ;
- rdfs:label "PersonalProfileDocument" ;
- rdfs:subClassOf foaf:Document .
+ a rdfs:Class ,
+ owl:Class ;
+ rdfs:comment "A personal profile RDF document." ;
+ rdfs:label "PersonalProfileDocument" ;
+ rdfs:subClassOf foaf:Document .
foaf:Project
- a rdfs:Class, owl:Class ;
- rdfs:comment "A project (a collective endeavour of some kind)." ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "Project" ;
- owl:disjointWith foaf:Document, foaf:Person .
+ a rdfs:Class ,
+ owl:Class ;
+ rdfs:comment "A project (a collective endeavour of some kind)." ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "Project" ;
+ owl:disjointWith foaf:Document ,
+ foaf:Person .
foaf:account
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "Indicates an account held by this agent." ;
- rdfs:domain foaf:Agent ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "account" ;
- rdfs:range foaf:OnlineAccount .
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:comment "Indicates an account held by this agent." ;
+ rdfs:domain foaf:Agent ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "account" ;
+ rdfs:range foaf:OnlineAccount .
foaf:accountName
- a rdf:Property, owl:DatatypeProperty ;
- rdfs:comment "Indicates the name (identifier) associated with this online account." ;
- rdfs:domain foaf:OnlineAccount ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "account name" ;
- rdfs:range rdfs:Literal .
+ a rdf:Property ,
+ owl:DatatypeProperty ;
+ rdfs:comment "Indicates the name (identifier) associated with this online account." ;
+ rdfs:domain foaf:OnlineAccount ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "account name" ;
+ rdfs:range rdfs:Literal .
foaf:accountServiceHomepage
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "Indicates a homepage of the service provide for this online account." ;
- rdfs:domain foaf:OnlineAccount ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "account service homepage" ;
- rdfs:range foaf:Document .
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:comment "Indicates a homepage of the service provide for this online account." ;
+ rdfs:domain foaf:OnlineAccount ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "account service homepage" ;
+ rdfs:range foaf:Document .
foaf:age
- a rdf:Property, owl:DatatypeProperty, owl:FunctionalProperty ;
- rdfs:comment "The age in years of some agent." ;
- rdfs:domain foaf:Agent ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "age" ;
- rdfs:range rdfs:Literal .
+ a rdf:Property ,
+ owl:DatatypeProperty ,
+ owl:FunctionalProperty ;
+ rdfs:comment "The age in years of some agent." ;
+ rdfs:domain foaf:Agent ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "age" ;
+ rdfs:range rdfs:Literal .
foaf:aimChatID
- a rdf:Property, owl:DatatypeProperty, owl:InverseFunctionalProperty ;
- rdfs:comment "An AIM chat ID" ;
- rdfs:domain foaf:Agent ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "AIM chat ID" ;
- rdfs:range rdfs:Literal ;
- rdfs:subPropertyOf foaf:nick .
+ a rdf:Property ,
+ owl:DatatypeProperty ,
+ owl:InverseFunctionalProperty ;
+ rdfs:comment "An AIM chat ID" ;
+ rdfs:domain foaf:Agent ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "AIM chat ID" ;
+ rdfs:range rdfs:Literal ;
+ rdfs:subPropertyOf foaf:nick .
foaf:birthday
- a rdf:Property, owl:DatatypeProperty, owl:FunctionalProperty ;
- rdfs:comment "The birthday of this Agent, represented in mm-dd string form, eg. '12-31'." ;
- rdfs:domain foaf:Agent ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "birthday" ;
- rdfs:range rdfs:Literal .
+ a rdf:Property ,
+ owl:DatatypeProperty ,
+ owl:FunctionalProperty ;
+ rdfs:comment """The birthday of this Agent, represented in mm-dd string form, eg. '12-31'.""" ;
+ rdfs:domain foaf:Agent ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "birthday" ;
+ rdfs:range rdfs:Literal .
foaf:currentProject
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "A current project this person works on." ;
- rdfs:domain foaf:Person ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "current project" ;
- rdfs:range owl:Thing .
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:comment "A current project this person works on." ;
+ rdfs:domain foaf:Person ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "current project" ;
+ rdfs:range owl:Thing .
foaf:depiction
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "A depiction of some thing." ;
- rdfs:domain owl:Thing ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "depiction" ;
- rdfs:range foaf:Image ;
- owl:inverseOf foaf:depicts .
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:comment "A depiction of some thing." ;
+ rdfs:domain owl:Thing ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "depiction" ;
+ rdfs:range foaf:Image ;
+ owl:inverseOf foaf:depicts .
foaf:depicts
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "A thing depicted in this representation." ;
- rdfs:domain foaf:Image ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "depicts" ;
- rdfs:range owl:Thing ;
- owl:inverseOf foaf:depiction .
-
-foaf:dnaChecksum
- a rdf:Property, owl:DatatypeProperty ;
- rdfs:comment "A checksum for the DNA of some thing. Joke." ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "DNA checksum" ;
- rdfs:range rdfs:Literal .
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:comment "A thing depicted in this representation." ;
+ rdfs:domain foaf:Image ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "depicts" ;
+ rdfs:range owl:Thing ;
+ owl:inverseOf foaf:depiction .
foaf:familyName
- a rdf:Property, owl:DatatypeProperty ;
- rdfs:comment "The family name of some person." ;
- rdfs:domain foaf:Person ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "familyName" ;
- rdfs:range rdfs:Literal .
+ a rdf:Property ,
+ owl:DatatypeProperty ;
+ rdfs:comment "The family name of some person." ;
+ rdfs:domain foaf:Person ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "familyName" ;
+ rdfs:range rdfs:Literal .
foaf:firstName
- a rdf:Property, owl:DatatypeProperty ;
- rdfs:comment "The first name of a person." ;
- rdfs:domain foaf:Person ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "firstName" ;
- rdfs:range rdfs:Literal .
-
-foaf:fundedBy
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "An organization funding a project or person." ;
- rdfs:domain owl:Thing ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "funded by" ;
- rdfs:range owl:Thing .
-
-foaf:geekcode
- a rdf:Property, owl:DatatypeProperty ;
- rdfs:comment "A textual geekcode for this person, see http://www.geekcode.com/geek.html" ;
- rdfs:domain foaf:Person ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "geekcode" ;
- rdfs:range rdfs:Literal .
+ a rdf:Property ,
+ owl:DatatypeProperty ;
+ rdfs:comment "The first name of a person." ;
+ rdfs:domain foaf:Person ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "firstName" ;
+ rdfs:range rdfs:Literal .
foaf:gender
- a rdf:Property, owl:DatatypeProperty, owl:FunctionalProperty ;
- rdfs:comment "The gender of this Agent (typically but not necessarily 'male' or 'female')." ;
- rdfs:domain foaf:Agent ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "gender" ;
- rdfs:range rdfs:Literal .
+ a rdf:Property ,
+ owl:DatatypeProperty ,
+ owl:FunctionalProperty ;
+ rdfs:comment """The gender of this Agent (typically but not necessarily 'male' or 'female').""" ;
+ rdfs:domain foaf:Agent ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "gender" ;
+ rdfs:range rdfs:Literal .
foaf:givenName
- a rdf:Property, owl:DatatypeProperty ;
- rdfs:comment "The given name of some person." ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "Given name" .
-
-foaf:givenname
- a rdf:Property, owl:DatatypeProperty ;
- rdfs:comment "The given name of some person." ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "Given name" .
-
-foaf:holdsAccount
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "Indicates an account held by this agent." ;
- rdfs:domain foaf:Agent ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "account" ;
- rdfs:range foaf:OnlineAccount .
+ a rdf:Property ,
+ owl:DatatypeProperty ;
+ rdfs:comment "The given name of some person." ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "Given name" .
foaf:homepage
- a rdf:Property, owl:InverseFunctionalProperty, owl:ObjectProperty ;
- rdfs:comment "A homepage for some thing." ;
- rdfs:domain owl:Thing ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "homepage" ;
- rdfs:range foaf:Document ;
- rdfs:subPropertyOf foaf:isPrimaryTopicOf, foaf:page .
+ a rdf:Property ,
+ owl:InverseFunctionalProperty ,
+ owl:ObjectProperty ;
+ rdfs:comment "A homepage for some thing." ;
+ rdfs:domain owl:Thing ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "homepage" ;
+ rdfs:range foaf:Document ;
+ rdfs:subPropertyOf foaf:isPrimaryTopicOf ,
+ foaf:page .
foaf:icqChatID
- a rdf:Property, owl:DatatypeProperty, owl:InverseFunctionalProperty ;
- rdfs:comment "An ICQ chat ID" ;
- rdfs:domain foaf:Agent ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "ICQ chat ID" ;
- rdfs:range rdfs:Literal ;
- rdfs:subPropertyOf foaf:nick .
+ a rdf:Property ,
+ owl:DatatypeProperty ,
+ owl:InverseFunctionalProperty ;
+ rdfs:comment "An ICQ chat ID" ;
+ rdfs:domain foaf:Agent ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "ICQ chat ID" ;
+ rdfs:range rdfs:Literal ;
+ rdfs:subPropertyOf foaf:nick .
foaf:img
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "An image that can be used to represent some thing (ie. those depictions which are particularly representative of something, eg. one's photo on a homepage)." ;
- rdfs:domain foaf:Person ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "image" ;
- rdfs:range foaf:Image ;
- rdfs:subPropertyOf foaf:depiction .
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:comment """An image that can be used to represent some thing (ie. those depictions which are particularly representative of something, eg. one's photo on a homepage).""" ;
+ rdfs:domain foaf:Person ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "image" ;
+ rdfs:range foaf:Image ;
+ rdfs:subPropertyOf foaf:depiction .
foaf:interest
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "A page about a topic of interest to this person." ;
- rdfs:domain foaf:Agent ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "interest" ;
- rdfs:range foaf:Document .
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:comment "A page about a topic of interest to this person." ;
+ rdfs:domain foaf:Agent ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "interest" ;
+ rdfs:range foaf:Document .
foaf:isPrimaryTopicOf
- a rdf:Property, owl:InverseFunctionalProperty ;
- rdfs:comment "A document that this thing is the primary topic of." ;
- rdfs:domain owl:Thing ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "is primary topic of" ;
- rdfs:range foaf:Document ;
- rdfs:subPropertyOf foaf:page ;
- owl:inverseOf foaf:primaryTopic .
+ a rdf:Property ,
+ owl:InverseFunctionalProperty ;
+ rdfs:comment "A document that this thing is the primary topic of." ;
+ rdfs:domain owl:Thing ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "is primary topic of" ;
+ rdfs:range foaf:Document ;
+ rdfs:subPropertyOf foaf:page ;
+ owl:inverseOf foaf:primaryTopic .
foaf:jabberID
- a rdf:Property, owl:DatatypeProperty, owl:InverseFunctionalProperty ;
- rdfs:comment "A jabber ID for something." ;
- rdfs:domain foaf:Agent ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "jabber ID" ;
- rdfs:range rdfs:Literal .
+ a rdf:Property ,
+ owl:DatatypeProperty ,
+ owl:InverseFunctionalProperty ;
+ rdfs:comment "A jabber ID for something." ;
+ rdfs:domain foaf:Agent ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "jabber ID" ;
+ rdfs:range rdfs:Literal .
foaf:knows
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "A person known by this person (indicating some level of reciprocated interaction between the parties)." ;
- rdfs:domain foaf:Person ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "knows" ;
- rdfs:range foaf:Person .
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:comment "A person known by this person (indicating some level of reciprocated interaction between the parties)." ;
+ rdfs:domain foaf:Person ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "knows" ;
+ rdfs:range foaf:Person .
foaf:lastName
- a rdf:Property, owl:DatatypeProperty ;
- rdfs:comment "The last name of a person." ;
- rdfs:domain foaf:Person ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "lastName" ;
- rdfs:range rdfs:Literal .
+ a rdf:Property ,
+ owl:DatatypeProperty ;
+ rdfs:comment "The last name of a person." ;
+ rdfs:domain foaf:Person ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "lastName" ;
+ rdfs:range rdfs:Literal .
foaf:logo
- a rdf:Property, owl:InverseFunctionalProperty, owl:ObjectProperty ;
- rdfs:comment "A logo representing some thing." ;
- rdfs:domain owl:Thing ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "logo" ;
- rdfs:range owl:Thing .
+ a rdf:Property ,
+ owl:InverseFunctionalProperty ,
+ owl:ObjectProperty ;
+ rdfs:comment "A logo representing some thing." ;
+ rdfs:domain owl:Thing ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "logo" ;
+ rdfs:range owl:Thing .
foaf:made
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "Something that was made by this agent." ;
- rdfs:domain foaf:Agent ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "made" ;
- rdfs:range owl:Thing ;
- owl:inverseOf foaf:maker .
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:comment "Something that was made by this agent." ;
+ rdfs:domain foaf:Agent ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "made" ;
+ rdfs:range owl:Thing ;
+ owl:inverseOf foaf:maker .
foaf:maker
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "An agent that made this thing." ;
- rdfs:domain owl:Thing ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "maker" ;
- rdfs:range foaf:Agent ;
- owl:equivalentProperty <http://purl.org/dc/terms/creator> ;
- owl:inverseOf foaf:made .
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:comment "An agent that made this thing." ;
+ rdfs:domain owl:Thing ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "maker" ;
+ rdfs:range foaf:Agent ;
+ owl:equivalentProperty dcterms:creator ;
+ owl:inverseOf foaf:made .
foaf:mbox
- a rdf:Property, owl:InverseFunctionalProperty, owl:ObjectProperty ;
- rdfs:comment "A personal mailbox, ie. an Internet mailbox associated with exactly one owner, the first owner of this mailbox. This is a 'static inverse functional property', in that there is (across time and change) at most one individual that ever has any particular value for foaf:mbox." ;
- rdfs:domain foaf:Agent ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "personal mailbox" ;
- rdfs:range owl:Thing .
+ a rdf:Property ,
+ owl:InverseFunctionalProperty ,
+ owl:ObjectProperty ;
+ rdfs:comment """A personal mailbox, ie. an Internet mailbox associated with exactly one owner, the first owner of this mailbox. This is a 'static inverse functional property', in that there is (across time and change) at most one individual that ever has any particular value for foaf:mbox.""" ;
+ rdfs:domain foaf:Agent ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "personal mailbox" ;
+ rdfs:range owl:Thing .
foaf:mbox_sha1sum
- a rdf:Property, owl:DatatypeProperty, owl:InverseFunctionalProperty ;
- rdfs:comment "The sha1sum of the URI of an Internet mailbox associated with exactly one owner, the first owner of the mailbox." ;
- rdfs:domain foaf:Agent ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "sha1sum of a personal mailbox URI name" ;
- rdfs:range rdfs:Literal .
+ a rdf:Property ,
+ owl:DatatypeProperty ,
+ owl:InverseFunctionalProperty ;
+ rdfs:comment "The sha1sum of the URI of an Internet mailbox associated with exactly one owner, the first owner of the mailbox." ;
+ rdfs:domain foaf:Agent ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "sha1sum of a personal mailbox URI name" ;
+ rdfs:range rdfs:Literal .
foaf:member
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "Indicates a member of a Group" ;
- rdfs:domain foaf:Group ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "member" ;
- rdfs:range foaf:Agent .
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:comment "Indicates a member of a Group" ;
+ rdfs:domain foaf:Group ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "member" ;
+ rdfs:range foaf:Agent .
foaf:membershipClass
- a rdf:Property, owl:AnnotationProperty ;
- rdfs:comment "Indicates the class of individuals that are a member of a Group" ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "membershipClass" .
+ a rdf:Property ,
+ owl:AnnotationProperty ;
+ rdfs:comment "Indicates the class of individuals that are a member of a Group" ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "membershipClass" .
foaf:msnChatID
- a rdf:Property, owl:DatatypeProperty, owl:InverseFunctionalProperty ;
- rdfs:comment "An MSN chat ID" ;
- rdfs:domain foaf:Agent ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "MSN chat ID" ;
- rdfs:range rdfs:Literal ;
- rdfs:subPropertyOf foaf:nick .
+ a rdf:Property ,
+ owl:DatatypeProperty ,
+ owl:InverseFunctionalProperty ;
+ rdfs:comment "An MSN chat ID" ;
+ rdfs:domain foaf:Agent ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "MSN chat ID" ;
+ rdfs:range rdfs:Literal ;
+ rdfs:subPropertyOf foaf:nick .
foaf:myersBriggs
- a rdf:Property, owl:DatatypeProperty ;
- rdfs:comment "A Myers Briggs (MBTI) personality classification." ;
- rdfs:domain foaf:Person ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "myersBriggs" ;
- rdfs:range rdfs:Literal .
+ a rdf:Property ,
+ owl:DatatypeProperty ;
+ rdfs:comment "A Myers Briggs (MBTI) personality classification." ;
+ rdfs:domain foaf:Person ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "myersBriggs" ;
+ rdfs:range rdfs:Literal .
foaf:name
- a rdf:Property, owl:DatatypeProperty ;
- rdfs:comment "A name for some thing." ;
- rdfs:domain owl:Thing ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "name" ;
- rdfs:range rdfs:Literal ;
- rdfs:subPropertyOf rdfs:label .
+ a rdf:Property ,
+ owl:DatatypeProperty ;
+ rdfs:comment "A name for some thing." ;
+ rdfs:domain owl:Thing ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "name" ;
+ rdfs:range rdfs:Literal ;
+ rdfs:subPropertyOf rdfs:label .
foaf:nick
- a rdf:Property, owl:DatatypeProperty ;
- rdfs:comment "A short informal nickname characterising an agent (includes login identifiers, IRC and other chat nicknames)." ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "nickname" .
+ a rdf:Property ,
+ owl:DatatypeProperty ;
+ rdfs:comment "A short informal nickname characterising an agent (includes login identifiers, IRC and other chat nicknames)." ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "nickname" .
foaf:openid
- a rdf:Property, owl:InverseFunctionalProperty, owl:ObjectProperty ;
- rdfs:comment "An OpenID for an Agent." ;
- rdfs:domain foaf:Agent ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "openid" ;
- rdfs:range foaf:Document ;
- rdfs:subPropertyOf foaf:isPrimaryTopicOf .
+ a rdf:Property ,
+ owl:InverseFunctionalProperty ,
+ owl:ObjectProperty ;
+ rdfs:comment "An OpenID for an Agent." ;
+ rdfs:domain foaf:Agent ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "openid" ;
+ rdfs:range foaf:Document ;
+ rdfs:subPropertyOf foaf:isPrimaryTopicOf .
foaf:page
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "A page or document about this thing." ;
- rdfs:domain owl:Thing ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "page" ;
- rdfs:range foaf:Document ;
- owl:inverseOf foaf:topic .
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:comment "A page or document about this thing." ;
+ rdfs:domain owl:Thing ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "page" ;
+ rdfs:range foaf:Document ;
+ owl:inverseOf foaf:topic .
foaf:pastProject
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "A project this person has previously worked on." ;
- rdfs:domain foaf:Person ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "past project" ;
- rdfs:range owl:Thing .
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:comment "A project this person has previously worked on." ;
+ rdfs:domain foaf:Person ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "past project" ;
+ rdfs:range owl:Thing .
foaf:phone
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "A phone, specified using fully qualified tel: URI scheme (refs: http://www.w3.org/Addressing/schemes.html#tel)." ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "phone" .
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:comment "A phone, specified using fully qualified tel: URI scheme (refs: http://www.w3.org/Addressing/schemes.html#tel)." ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "phone" .
foaf:plan
- a rdf:Property, owl:DatatypeProperty ;
- rdfs:comment "A .plan comment, in the tradition of finger and '.plan' files." ;
- rdfs:domain foaf:Person ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "plan" ;
- rdfs:range rdfs:Literal .
+ a rdf:Property ,
+ owl:DatatypeProperty ;
+ rdfs:comment """A .plan comment, in the tradition of finger and '.plan' files.""" ;
+ rdfs:domain foaf:Person ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "plan" ;
+ rdfs:range rdfs:Literal .
foaf:primaryTopic
- a rdf:Property, owl:FunctionalProperty, owl:ObjectProperty ;
- rdfs:comment "The primary topic of some page or document." ;
- rdfs:domain foaf:Document ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "primary topic" ;
- rdfs:range owl:Thing ;
- owl:inverseOf foaf:isPrimaryTopicOf .
+ a rdf:Property ,
+ owl:FunctionalProperty ,
+ owl:ObjectProperty ;
+ rdfs:comment "The primary topic of some page or document." ;
+ rdfs:domain foaf:Document ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "primary topic" ;
+ rdfs:range owl:Thing ;
+ owl:inverseOf foaf:isPrimaryTopicOf .
foaf:publications
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "A link to the publications of this person." ;
- rdfs:domain foaf:Person ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "publications" ;
- rdfs:range foaf:Document .
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:comment "A link to the publications of this person." ;
+ rdfs:domain foaf:Person ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "publications" ;
+ rdfs:range foaf:Document .
foaf:schoolHomepage
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "A homepage of a school attended by the person." ;
- rdfs:domain foaf:Person ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "schoolHomepage" ;
- rdfs:range foaf:Document .
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:comment "A homepage of a school attended by the person." ;
+ rdfs:domain foaf:Person ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "schoolHomepage" ;
+ rdfs:range foaf:Document .
foaf:sha1
- a rdf:Property, owl:DatatypeProperty ;
- rdfs:comment "A sha1sum hash, in hex." ;
- rdfs:domain foaf:Document ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "sha1sum (hex)" .
+ a rdf:Property ,
+ owl:DatatypeProperty ;
+ rdfs:comment "A sha1sum hash, in hex." ;
+ rdfs:domain foaf:Document ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "sha1sum (hex)" .
foaf:skypeID
- a rdf:Property, owl:DatatypeProperty ;
- rdfs:comment "A Skype ID" ;
- rdfs:domain foaf:Agent ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "Skype ID" ;
- rdfs:range rdfs:Literal ;
- rdfs:subPropertyOf foaf:nick .
+ a rdf:Property ,
+ owl:DatatypeProperty ;
+ rdfs:comment "A Skype ID" ;
+ rdfs:domain foaf:Agent ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "Skype ID" ;
+ rdfs:range rdfs:Literal ;
+ rdfs:subPropertyOf foaf:nick .
foaf:status
- a rdf:Property, owl:DatatypeProperty ;
- rdfs:comment "A string expressing what the user is happy for the general public (normally) to know about their current activity." ;
- rdfs:domain foaf:Agent ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "status" ;
- rdfs:range rdfs:Literal .
-
-foaf:surname
- a rdf:Property, owl:DatatypeProperty ;
- rdfs:comment "The surname of some person." ;
- rdfs:domain foaf:Person ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "Surname" ;
- rdfs:range rdfs:Literal .
-
-foaf:theme
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "A theme." ;
- rdfs:domain owl:Thing ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "theme" ;
- rdfs:range owl:Thing .
+ a rdf:Property ,
+ owl:DatatypeProperty ;
+ rdfs:comment "A string expressing what the user is happy for the general public (normally) to know about their current activity." ;
+ rdfs:domain foaf:Agent ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "status" ;
+ rdfs:range rdfs:Literal .
foaf:thumbnail
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "A derived thumbnail image." ;
- rdfs:domain foaf:Image ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "thumbnail" ;
- rdfs:range foaf:Image .
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:comment "A derived thumbnail image." ;
+ rdfs:domain foaf:Image ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "thumbnail" ;
+ rdfs:range foaf:Image .
foaf:tipjar
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "A tipjar document for this agent, describing means for payment and reward." ;
- rdfs:domain foaf:Agent ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "tipjar" ;
- rdfs:range foaf:Document ;
- rdfs:subPropertyOf foaf:page .
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:comment "A tipjar document for this agent, describing means for payment and reward." ;
+ rdfs:domain foaf:Agent ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "tipjar" ;
+ rdfs:range foaf:Document ;
+ rdfs:subPropertyOf foaf:page .
foaf:title
- a rdf:Property, owl:DatatypeProperty ;
- rdfs:comment "Title (Mr, Mrs, Ms, Dr. etc)" ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "title" .
+ a rdf:Property ,
+ owl:DatatypeProperty ;
+ rdfs:comment "Title (Mr, Mrs, Ms, Dr. etc)" ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "title" .
foaf:topic
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "A topic of some page or document." ;
- rdfs:domain foaf:Document ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "topic" ;
- rdfs:range owl:Thing ;
- owl:inverseOf foaf:page .
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:comment "A topic of some page or document." ;
+ rdfs:domain foaf:Document ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "topic" ;
+ rdfs:range owl:Thing ;
+ owl:inverseOf foaf:page .
foaf:topic_interest
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "A thing of interest to this person." ;
- rdfs:domain foaf:Agent ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "topic_interest" ;
- rdfs:range owl:Thing .
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:comment "A thing of interest to this person." ;
+ rdfs:domain foaf:Agent ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "topic_interest" ;
+ rdfs:range owl:Thing .
foaf:weblog
- a rdf:Property, owl:InverseFunctionalProperty, owl:ObjectProperty ;
- rdfs:comment "A weblog of some thing (whether person, group, company etc.)." ;
- rdfs:domain foaf:Agent ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "weblog" ;
- rdfs:range foaf:Document ;
- rdfs:subPropertyOf foaf:page .
+ a rdf:Property ,
+ owl:InverseFunctionalProperty ,
+ owl:ObjectProperty ;
+ rdfs:comment "A weblog of some thing (whether person, group, company etc.)." ;
+ rdfs:domain foaf:Agent ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "weblog" ;
+ rdfs:range foaf:Document ;
+ rdfs:subPropertyOf foaf:page .
foaf:workInfoHomepage
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "A work info homepage of some person; a page about their work for some organization." ;
- rdfs:domain foaf:Person ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "work info homepage" ;
- rdfs:range foaf:Document .
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:comment "A work info homepage of some person; a page about their work for some organization." ;
+ rdfs:domain foaf:Person ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "work info homepage" ;
+ rdfs:range foaf:Document .
foaf:workplaceHomepage
- a rdf:Property, owl:ObjectProperty ;
- rdfs:comment "A workplace homepage of some person; the homepage of an organization they work for." ;
- rdfs:domain foaf:Person ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "workplace homepage" ;
- rdfs:range foaf:Document .
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:comment "A workplace homepage of some person; the homepage of an organization they work for." ;
+ rdfs:domain foaf:Person ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "workplace homepage" ;
+ rdfs:range foaf:Document .
foaf:yahooChatID
- a rdf:Property, owl:DatatypeProperty, owl:InverseFunctionalProperty ;
- rdfs:comment "A Yahoo chat ID" ;
- rdfs:domain foaf:Agent ;
- rdfs:isDefinedBy <http://xmlns.com/foaf/0.1/> ;
- rdfs:label "Yahoo chat ID" ;
- rdfs:range rdfs:Literal ;
- rdfs:subPropertyOf foaf:nick .
+ a rdf:Property ,
+ owl:DatatypeProperty ,
+ owl:InverseFunctionalProperty ;
+ rdfs:comment "A Yahoo chat ID" ;
+ rdfs:domain foaf:Agent ;
+ rdfs:isDefinedBy foaf: ;
+ rdfs:label "Yahoo chat ID" ;
+ rdfs:range rdfs:Literal ;
+ rdfs:subPropertyOf foaf:nick .
+
diff --git a/schemas.lv2/manifest.ttl b/schemas.lv2/manifest.ttl
index 2dbcbd4..ed11c1a 100644
--- a/schemas.lv2/manifest.ttl
+++ b/schemas.lv2/manifest.ttl
@@ -7,7 +7,7 @@
<http://purl.org/dc/terms/>
a owl:Ontology ;
- rdfs:seeAlso <dct.ttl> .
+ rdfs:seeAlso <dcterms.ttl> .
<http://usefulinc.com/ns/doap#>
a owl:Ontology ;
@@ -21,7 +21,7 @@
a owl:Ontology ;
rdfs:seeAlso <owl.ttl> .
-<http://www.w3.org/2000/01/rdf-schema#>
+rdfs:
a owl:Ontology ;
rdfs:seeAlso <rdfs.ttl> .
@@ -32,3 +32,4 @@
<http://www.w3.org/2001/XMLSchema#>
a owl:Ontology ;
rdfs:seeAlso <xsd.ttl> .
+
diff --git a/schemas.lv2/meson.build b/schemas.lv2/meson.build
new file mode 100644
index 0000000..fb7bed5
--- /dev/null
+++ b/schemas.lv2/meson.build
@@ -0,0 +1,16 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+schema_data = files(
+ 'dcs.ttl',
+ 'dcterms.ttl',
+ 'doap.ttl',
+ 'foaf.ttl',
+ 'manifest.ttl',
+ 'owl.ttl',
+ 'rdf.ttl',
+ 'rdfs.ttl',
+ 'xsd.ttl',
+)
+
+install_data(schema_data, install_dir: lv2dir / 'schemas.lv2')
diff --git a/schemas.lv2/owl.ttl b/schemas.lv2/owl.ttl
index 3f1c86e..26bd0e8 100644
--- a/schemas.lv2/owl.ttl
+++ b/schemas.lv2/owl.ttl
@@ -2,12 +2,12 @@
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
-@prefix dct: <http://purl.org/dc/terms/> .
+@prefix dcterms: <http://purl.org/dc/terms/> .
<http://www.w3.org/2002/07/owl>
- dct:title "The OWL 2 Schema vocabulary (OWL 2)" ;
- a owl:Ontology ;
- rdfs:comment """
+ dcterms:title "The OWL 2 Schema vocabulary (OWL 2)" ;
+ a owl:Ontology ;
+ rdfs:comment """
This ontology partially describes the built-in classes and
properties that together form the basis of the RDF/XML syntax of OWL 2.
The content of this ontology is based on Tables 6.1 and 6.2
@@ -25,591 +25,597 @@
will cause it to become an OWL 2 Full ontology and may have other,
unexpected, consequences.
""" ;
- rdfs:isDefinedBy <http://www.w3.org/TR/owl2-mapping-to-rdf/>, <http://www.w3.org/TR/owl2-rdf-based-semantics/>, <http://www.w3.org/TR/owl2-syntax/> ;
- rdfs:seeAlso <http://www.w3.org/TR/owl2-rdf-based-semantics/#table-axiomatic-classes>, <http://www.w3.org/TR/owl2-rdf-based-semantics/#table-axiomatic-properties> ;
- owl:imports rdfs: ;
- owl:versionIRI <http://www.w3.org/2002/07/owl> ;
- owl:versionInfo "$Date: 2009/11/15 10:54:12 $" .
+ rdfs:isDefinedBy <http://www.w3.org/TR/owl2-mapping-to-rdf/> ,
+ <http://www.w3.org/TR/owl2-rdf-based-semantics/> ,
+ <http://www.w3.org/TR/owl2-syntax/> ;
+ rdfs:seeAlso <http://www.w3.org/TR/owl2-rdf-based-semantics/#table-axiomatic-classes> ,
+ <http://www.w3.org/TR/owl2-rdf-based-semantics/#table-axiomatic-properties> ;
+ owl:imports rdfs: ;
+ owl:versionIRI <http://www.w3.org/2002/07/owl> ;
+ owl:versionInfo "$Date: 2009/11/15 10:54:12 $" .
owl:AllDifferent
- a rdfs:Class ;
- rdfs:comment "The class of collections of pairwise different individuals." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "AllDifferent" ;
- rdfs:subClassOf rdfs:Resource .
+ a rdfs:Class ;
+ rdfs:comment "The class of collections of pairwise different individuals." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "AllDifferent" ;
+ rdfs:subClassOf rdfs:Resource .
owl:AllDisjointClasses
- a rdfs:Class ;
- rdfs:comment "The class of collections of pairwise disjoint classes." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "AllDisjointClasses" ;
- rdfs:subClassOf rdfs:Resource .
+ a rdfs:Class ;
+ rdfs:comment "The class of collections of pairwise disjoint classes." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "AllDisjointClasses" ;
+ rdfs:subClassOf rdfs:Resource .
owl:AllDisjointProperties
- a rdfs:Class ;
- rdfs:comment "The class of collections of pairwise disjoint properties." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "AllDisjointProperties" ;
- rdfs:subClassOf rdfs:Resource .
+ a rdfs:Class ;
+ rdfs:comment "The class of collections of pairwise disjoint properties." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "AllDisjointProperties" ;
+ rdfs:subClassOf rdfs:Resource .
owl:Annotation
- a rdfs:Class ;
- rdfs:comment "The class of annotated annotations for which the RDF serialization consists of an annotated subject, predicate and object." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "Annotation" ;
- rdfs:subClassOf rdfs:Resource .
+ a rdfs:Class ;
+ rdfs:comment "The class of annotated annotations for which the RDF serialization consists of an annotated subject, predicate and object." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "Annotation" ;
+ rdfs:subClassOf rdfs:Resource .
owl:AnnotationProperty
- a rdfs:Class ;
- rdfs:comment "The class of annotation properties." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "AnnotationProperty" ;
- rdfs:subClassOf rdf:Property .
+ a rdfs:Class ;
+ rdfs:comment "The class of annotation properties." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "AnnotationProperty" ;
+ rdfs:subClassOf rdf:Property .
owl:AsymmetricProperty
- a rdfs:Class ;
- rdfs:comment "The class of asymmetric properties." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "AsymmetricProperty" ;
- rdfs:subClassOf owl:ObjectProperty .
+ a rdfs:Class ;
+ rdfs:comment "The class of asymmetric properties." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "AsymmetricProperty" ;
+ rdfs:subClassOf owl:ObjectProperty .
owl:Axiom
- a rdfs:Class ;
- rdfs:comment "The class of annotated axioms for which the RDF serialization consists of an annotated subject, predicate and object." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "Axiom" ;
- rdfs:subClassOf rdfs:Resource .
+ a rdfs:Class ;
+ rdfs:comment "The class of annotated axioms for which the RDF serialization consists of an annotated subject, predicate and object." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "Axiom" ;
+ rdfs:subClassOf rdfs:Resource .
owl:Class
- a rdfs:Class ;
- rdfs:comment "The class of OWL classes." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "Class" ;
- rdfs:subClassOf rdfs:Class .
+ a rdfs:Class ;
+ rdfs:comment "The class of OWL classes." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "Class" ;
+ rdfs:subClassOf rdfs:Class .
owl:DatatypeProperty
- a rdfs:Class ;
- rdfs:comment "The class of data properties." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "DatatypeProperty" ;
- rdfs:subClassOf rdf:Property .
+ a rdfs:Class ;
+ rdfs:comment "The class of data properties." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "DatatypeProperty" ;
+ rdfs:subClassOf rdf:Property .
owl:DeprecatedClass
- a rdfs:Class ;
- rdfs:comment "The class of deprecated classes." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "DeprecatedClass" ;
- rdfs:subClassOf rdfs:Class .
+ a rdfs:Class ;
+ rdfs:comment "The class of deprecated classes." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "DeprecatedClass" ;
+ rdfs:subClassOf rdfs:Class .
owl:DeprecatedProperty
- a rdfs:Class ;
- rdfs:comment "The class of deprecated properties." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "DeprecatedProperty" ;
- rdfs:subClassOf rdf:Property .
+ a rdfs:Class ;
+ rdfs:comment "The class of deprecated properties." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "DeprecatedProperty" ;
+ rdfs:subClassOf rdf:Property .
owl:FunctionalProperty
- a rdfs:Class ;
- rdfs:comment "The class of functional properties." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "FunctionalProperty" ;
- rdfs:subClassOf rdf:Property .
+ a rdfs:Class ;
+ rdfs:comment "The class of functional properties." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "FunctionalProperty" ;
+ rdfs:subClassOf rdf:Property .
owl:InverseFunctionalProperty
- a rdfs:Class ;
- rdfs:comment "The class of inverse-functional properties." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "InverseFunctionalProperty" ;
- rdfs:subClassOf owl:ObjectProperty .
+ a rdfs:Class ;
+ rdfs:comment "The class of inverse-functional properties." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "InverseFunctionalProperty" ;
+ rdfs:subClassOf owl:ObjectProperty .
owl:IrreflexiveProperty
- a rdfs:Class ;
- rdfs:comment "The class of irreflexive properties." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "IrreflexiveProperty" ;
- rdfs:subClassOf owl:ObjectProperty .
+ a rdfs:Class ;
+ rdfs:comment "The class of irreflexive properties." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "IrreflexiveProperty" ;
+ rdfs:subClassOf owl:ObjectProperty .
owl:NamedIndividual
- a rdfs:Class ;
- rdfs:comment "The class of named individuals." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "NamedIndividual" ;
- rdfs:subClassOf owl:Thing .
+ a rdfs:Class ;
+ rdfs:comment "The class of named individuals." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "NamedIndividual" ;
+ rdfs:subClassOf owl:Thing .
owl:NegativePropertyAssertion
- a rdfs:Class ;
- rdfs:comment "The class of negative property assertions." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "NegativePropertyAssertion" ;
- rdfs:subClassOf rdfs:Resource .
+ a rdfs:Class ;
+ rdfs:comment "The class of negative property assertions." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "NegativePropertyAssertion" ;
+ rdfs:subClassOf rdfs:Resource .
owl:Nothing
- a owl:Class ;
- rdfs:comment "This is the empty class." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "Nothing" ;
- rdfs:subClassOf owl:Thing .
+ a owl:Class ;
+ rdfs:comment "This is the empty class." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "Nothing" ;
+ rdfs:subClassOf owl:Thing .
owl:ObjectProperty
- a rdfs:Class ;
- rdfs:comment "The class of object properties." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "ObjectProperty" ;
- rdfs:subClassOf rdf:Property .
+ a rdfs:Class ;
+ rdfs:comment "The class of object properties." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "ObjectProperty" ;
+ rdfs:subClassOf rdf:Property .
owl:Ontology
- a rdfs:Class ;
- rdfs:comment "The class of ontologies." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "Ontology" ;
- rdfs:subClassOf rdfs:Resource .
+ a rdfs:Class ;
+ rdfs:comment "The class of ontologies." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "Ontology" ;
+ rdfs:subClassOf rdfs:Resource .
owl:OntologyProperty
- a rdfs:Class ;
- rdfs:comment "The class of ontology properties." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "OntologyProperty" ;
- rdfs:subClassOf rdf:Property .
+ a rdfs:Class ;
+ rdfs:comment "The class of ontology properties." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "OntologyProperty" ;
+ rdfs:subClassOf rdf:Property .
owl:ReflexiveProperty
- a rdfs:Class ;
- rdfs:comment "The class of reflexive properties." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "ReflexiveProperty" ;
- rdfs:subClassOf owl:ObjectProperty .
+ a rdfs:Class ;
+ rdfs:comment "The class of reflexive properties." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "ReflexiveProperty" ;
+ rdfs:subClassOf owl:ObjectProperty .
owl:Restriction
- a rdfs:Class ;
- rdfs:comment "The class of property restrictions." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "Restriction" ;
- rdfs:subClassOf owl:Class .
+ a rdfs:Class ;
+ rdfs:comment "The class of property restrictions." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "Restriction" ;
+ rdfs:subClassOf owl:Class .
owl:SymmetricProperty
- a rdfs:Class ;
- rdfs:comment "The class of symmetric properties." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "SymmetricProperty" ;
- rdfs:subClassOf owl:ObjectProperty .
+ a rdfs:Class ;
+ rdfs:comment "The class of symmetric properties." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "SymmetricProperty" ;
+ rdfs:subClassOf owl:ObjectProperty .
owl:Thing
- a owl:Class ;
- rdfs:comment "The class of OWL individuals." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "Thing" .
+ a owl:Class ;
+ rdfs:comment "The class of OWL individuals." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "Thing" .
owl:TransitiveProperty
- a rdfs:Class ;
- rdfs:comment "The class of transitive properties." ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "TransitiveProperty" ;
- rdfs:subClassOf owl:ObjectProperty .
+ a rdfs:Class ;
+ rdfs:comment "The class of transitive properties." ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "TransitiveProperty" ;
+ rdfs:subClassOf owl:ObjectProperty .
owl:allValuesFrom
- a rdf:Property ;
- rdfs:comment "The property that determines the class that a universal property restriction refers to." ;
- rdfs:domain owl:Restriction ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "all values from" ;
- rdfs:range rdfs:Class .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the class that a universal property restriction refers to." ;
+ rdfs:domain owl:Restriction ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "all values from" ;
+ rdfs:range rdfs:Class .
owl:annotatedProperty
- a rdf:Property ;
- rdfs:comment "The property that determines the predicate of an annotated axiom or annotated annotation." ;
- rdfs:domain rdfs:Resource ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "annotated property" ;
- rdfs:range rdfs:Resource .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the predicate of an annotated axiom or annotated annotation." ;
+ rdfs:domain rdfs:Resource ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "annotated property" ;
+ rdfs:range rdfs:Resource .
owl:annotatedSource
- a rdf:Property ;
- rdfs:comment "The property that determines the subject of an annotated axiom or annotated annotation." ;
- rdfs:domain rdfs:Resource ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "annotated source" ;
- rdfs:range rdfs:Resource .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the subject of an annotated axiom or annotated annotation." ;
+ rdfs:domain rdfs:Resource ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "annotated source" ;
+ rdfs:range rdfs:Resource .
owl:annotatedTarget
- a rdf:Property ;
- rdfs:comment "The property that determines the object of an annotated axiom or annotated annotation." ;
- rdfs:domain rdfs:Resource ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "annotated target" ;
- rdfs:range rdfs:Resource .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the object of an annotated axiom or annotated annotation." ;
+ rdfs:domain rdfs:Resource ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "annotated target" ;
+ rdfs:range rdfs:Resource .
owl:assertionProperty
- a rdf:Property ;
- rdfs:comment "The property that determines the predicate of a negative property assertion." ;
- rdfs:domain owl:NegativePropertyAssertion ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "assertion property" ;
- rdfs:range rdf:Property .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the predicate of a negative property assertion." ;
+ rdfs:domain owl:NegativePropertyAssertion ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "assertion property" ;
+ rdfs:range rdf:Property .
owl:backwardCompatibleWith
- a owl:AnnotationProperty, owl:OntologyProperty ;
- rdfs:comment "The annotation property that indicates that a given ontology is backward compatible with another ontology." ;
- rdfs:domain owl:Ontology ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "backward compatible with" ;
- rdfs:range owl:Ontology .
+ a owl:AnnotationProperty ,
+ owl:OntologyProperty ;
+ rdfs:comment "The annotation property that indicates that a given ontology is backward compatible with another ontology." ;
+ rdfs:domain owl:Ontology ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "backward compatible with" ;
+ rdfs:range owl:Ontology .
owl:bottomDataProperty
- a owl:DatatypeProperty ;
- rdfs:comment "The data property that does not relate any individual to any data value." ;
- rdfs:domain owl:Thing ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "bottom data property" ;
- rdfs:range rdfs:Literal .
+ a owl:DatatypeProperty ;
+ rdfs:comment "The data property that does not relate any individual to any data value." ;
+ rdfs:domain owl:Thing ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "bottom data property" ;
+ rdfs:range rdfs:Literal .
owl:bottomObjectProperty
- a owl:ObjectProperty ;
- rdfs:comment "The object property that does not relate any two individuals." ;
- rdfs:domain owl:Thing ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "bottom object property" ;
- rdfs:range owl:Thing .
+ a owl:ObjectProperty ;
+ rdfs:comment "The object property that does not relate any two individuals." ;
+ rdfs:domain owl:Thing ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "bottom object property" ;
+ rdfs:range owl:Thing .
owl:cardinality
- a rdf:Property ;
- rdfs:comment "The property that determines the cardinality of an exact cardinality restriction." ;
- rdfs:domain owl:Restriction ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "cardinality" ;
- rdfs:range xsd:nonNegativeInteger .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the cardinality of an exact cardinality restriction." ;
+ rdfs:domain owl:Restriction ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "cardinality" ;
+ rdfs:range xsd:nonNegativeInteger .
owl:complementOf
- a rdf:Property ;
- rdfs:comment "The property that determines that a given class is the complement of another class." ;
- rdfs:domain owl:Class ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "complement of" ;
- rdfs:range owl:Class .
+ a rdf:Property ;
+ rdfs:comment "The property that determines that a given class is the complement of another class." ;
+ rdfs:domain owl:Class ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "complement of" ;
+ rdfs:range owl:Class .
owl:datatypeComplementOf
- a rdf:Property ;
- rdfs:comment "The property that determines that a given data range is the complement of another data range with respect to the data domain." ;
- rdfs:domain rdfs:Datatype ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "datatype complement of" ;
- rdfs:range rdfs:Datatype .
+ a rdf:Property ;
+ rdfs:comment "The property that determines that a given data range is the complement of another data range with respect to the data domain." ;
+ rdfs:domain rdfs:Datatype ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "datatype complement of" ;
+ rdfs:range rdfs:Datatype .
owl:deprecated
- a owl:AnnotationProperty ;
- rdfs:comment "The annotation property that indicates that a given entity has been deprecated." ;
- rdfs:domain rdfs:Resource ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "deprecated" ;
- rdfs:range rdfs:Resource .
+ a owl:AnnotationProperty ;
+ rdfs:comment "The annotation property that indicates that a given entity has been deprecated." ;
+ rdfs:domain rdfs:Resource ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "deprecated" ;
+ rdfs:range rdfs:Resource .
owl:differentFrom
- a rdf:Property ;
- rdfs:comment "The property that determines that two given individuals are different." ;
- rdfs:domain owl:Thing ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "different from" ;
- rdfs:range owl:Thing .
+ a rdf:Property ;
+ rdfs:comment "The property that determines that two given individuals are different." ;
+ rdfs:domain owl:Thing ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "different from" ;
+ rdfs:range owl:Thing .
owl:disjointUnionOf
- a rdf:Property ;
- rdfs:comment "The property that determines that a given class is equivalent to the disjoint union of a collection of other classes." ;
- rdfs:domain owl:Class ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "disjoint union of" ;
- rdfs:range rdf:List .
+ a rdf:Property ;
+ rdfs:comment "The property that determines that a given class is equivalent to the disjoint union of a collection of other classes." ;
+ rdfs:domain owl:Class ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "disjoint union of" ;
+ rdfs:range rdf:List .
owl:disjointWith
- a rdf:Property ;
- rdfs:comment "The property that determines that two given classes are disjoint." ;
- rdfs:domain owl:Class ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "disjoint with" ;
- rdfs:range owl:Class .
+ a rdf:Property ;
+ rdfs:comment "The property that determines that two given classes are disjoint." ;
+ rdfs:domain owl:Class ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "disjoint with" ;
+ rdfs:range owl:Class .
owl:distinctMembers
- a rdf:Property ;
- rdfs:comment "The property that determines the collection of pairwise different individuals in a owl:AllDifferent axiom." ;
- rdfs:domain owl:AllDifferent ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "distinct members" ;
- rdfs:range rdf:List .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the collection of pairwise different individuals in a owl:AllDifferent axiom." ;
+ rdfs:domain owl:AllDifferent ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "distinct members" ;
+ rdfs:range rdf:List .
owl:equivalentClass
- a rdf:Property ;
- rdfs:comment "The property that determines that two given classes are equivalent, and that is used to specify datatype definitions." ;
- rdfs:domain rdfs:Class ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "equivalent class" ;
- rdfs:range rdfs:Class .
+ a rdf:Property ;
+ rdfs:comment "The property that determines that two given classes are equivalent, and that is used to specify datatype definitions." ;
+ rdfs:domain rdfs:Class ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "equivalent class" ;
+ rdfs:range rdfs:Class .
owl:equivalentProperty
- a rdf:Property ;
- rdfs:comment "The property that determines that two given properties are equivalent." ;
- rdfs:domain rdf:Property ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "equivalent property" ;
- rdfs:range rdf:Property .
+ a rdf:Property ;
+ rdfs:comment "The property that determines that two given properties are equivalent." ;
+ rdfs:domain rdf:Property ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "equivalent property" ;
+ rdfs:range rdf:Property .
owl:hasKey
- a rdf:Property ;
- rdfs:comment "The property that determines the collection of properties that jointly build a key." ;
- rdfs:domain owl:Class ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "has key" ;
- rdfs:range rdf:List .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the collection of properties that jointly build a key." ;
+ rdfs:domain owl:Class ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "has key" ;
+ rdfs:range rdf:List .
owl:hasSelf
- a rdf:Property ;
- rdfs:comment "The property that determines the property that a self restriction refers to." ;
- rdfs:domain owl:Restriction ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "has self" ;
- rdfs:range rdfs:Resource .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the property that a self restriction refers to." ;
+ rdfs:domain owl:Restriction ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "has self" ;
+ rdfs:range rdfs:Resource .
owl:hasValue
- a rdf:Property ;
- rdfs:comment "The property that determines the individual that a has-value restriction refers to." ;
- rdfs:domain owl:Restriction ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "has value" ;
- rdfs:range rdfs:Resource .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the individual that a has-value restriction refers to." ;
+ rdfs:domain owl:Restriction ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "has value" ;
+ rdfs:range rdfs:Resource .
owl:imports
- a owl:OntologyProperty ;
- rdfs:comment "The property that is used for importing other ontologies into a given ontology." ;
- rdfs:domain owl:Ontology ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "imports" ;
- rdfs:range owl:Ontology .
+ a owl:OntologyProperty ;
+ rdfs:comment "The property that is used for importing other ontologies into a given ontology." ;
+ rdfs:domain owl:Ontology ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "imports" ;
+ rdfs:range owl:Ontology .
owl:incompatibleWith
- a owl:AnnotationProperty, owl:OntologyProperty ;
- rdfs:comment "The annotation property that indicates that a given ontology is incompatible with another ontology." ;
- rdfs:domain owl:Ontology ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "incompatible with" ;
- rdfs:range owl:Ontology .
+ a owl:AnnotationProperty ,
+ owl:OntologyProperty ;
+ rdfs:comment "The annotation property that indicates that a given ontology is incompatible with another ontology." ;
+ rdfs:domain owl:Ontology ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "incompatible with" ;
+ rdfs:range owl:Ontology .
owl:intersectionOf
- a rdf:Property ;
- rdfs:comment "The property that determines the collection of classes or data ranges that build an intersection." ;
- rdfs:domain rdfs:Class ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "intersection of" ;
- rdfs:range rdf:List .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the collection of classes or data ranges that build an intersection." ;
+ rdfs:domain rdfs:Class ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "intersection of" ;
+ rdfs:range rdf:List .
owl:inverseOf
- a rdf:Property ;
- rdfs:comment "The property that determines that two given properties are inverse." ;
- rdfs:domain owl:ObjectProperty ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "inverse of" ;
- rdfs:range owl:ObjectProperty .
+ a rdf:Property ;
+ rdfs:comment "The property that determines that two given properties are inverse." ;
+ rdfs:domain owl:ObjectProperty ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "inverse of" ;
+ rdfs:range owl:ObjectProperty .
owl:maxCardinality
- a rdf:Property ;
- rdfs:comment "The property that determines the cardinality of a maximum cardinality restriction." ;
- rdfs:domain owl:Restriction ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "max cardinality" ;
- rdfs:range xsd:nonNegativeInteger .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the cardinality of a maximum cardinality restriction." ;
+ rdfs:domain owl:Restriction ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "max cardinality" ;
+ rdfs:range xsd:nonNegativeInteger .
owl:maxQualifiedCardinality
- a rdf:Property ;
- rdfs:comment "The property that determines the cardinality of a maximum qualified cardinality restriction." ;
- rdfs:domain owl:Restriction ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "max qualified cardinality" ;
- rdfs:range xsd:nonNegativeInteger .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the cardinality of a maximum qualified cardinality restriction." ;
+ rdfs:domain owl:Restriction ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "max qualified cardinality" ;
+ rdfs:range xsd:nonNegativeInteger .
owl:members
- a rdf:Property ;
- rdfs:comment "The property that determines the collection of members in either a owl:AllDifferent, owl:AllDisjointClasses or owl:AllDisjointProperties axiom." ;
- rdfs:domain rdfs:Resource ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "members" ;
- rdfs:range rdf:List .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the collection of members in either a owl:AllDifferent, owl:AllDisjointClasses or owl:AllDisjointProperties axiom." ;
+ rdfs:domain rdfs:Resource ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "members" ;
+ rdfs:range rdf:List .
owl:minCardinality
- a rdf:Property ;
- rdfs:comment "The property that determines the cardinality of a minimum cardinality restriction." ;
- rdfs:domain owl:Restriction ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "min cardinality" ;
- rdfs:range xsd:nonNegativeInteger .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the cardinality of a minimum cardinality restriction." ;
+ rdfs:domain owl:Restriction ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "min cardinality" ;
+ rdfs:range xsd:nonNegativeInteger .
owl:minQualifiedCardinality
- a rdf:Property ;
- rdfs:comment "The property that determines the cardinality of a minimum qualified cardinality restriction." ;
- rdfs:domain owl:Restriction ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "min qualified cardinality" ;
- rdfs:range xsd:nonNegativeInteger .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the cardinality of a minimum qualified cardinality restriction." ;
+ rdfs:domain owl:Restriction ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "min qualified cardinality" ;
+ rdfs:range xsd:nonNegativeInteger .
owl:onClass
- a rdf:Property ;
- rdfs:comment "The property that determines the class that a qualified object cardinality restriction refers to." ;
- rdfs:domain owl:Restriction ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "on class" ;
- rdfs:range owl:Class .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the class that a qualified object cardinality restriction refers to." ;
+ rdfs:domain owl:Restriction ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "on class" ;
+ rdfs:range owl:Class .
owl:onDataRange
- a rdf:Property ;
- rdfs:comment "The property that determines the data range that a qualified data cardinality restriction refers to." ;
- rdfs:domain owl:Restriction ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "on data range" ;
- rdfs:range rdfs:Datatype .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the data range that a qualified data cardinality restriction refers to." ;
+ rdfs:domain owl:Restriction ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "on data range" ;
+ rdfs:range rdfs:Datatype .
owl:onDatatype
- a rdf:Property ;
- rdfs:comment "The property that determines the datatype that a datatype restriction refers to." ;
- rdfs:domain rdfs:Datatype ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "on datatype" ;
- rdfs:range rdfs:Datatype .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the datatype that a datatype restriction refers to." ;
+ rdfs:domain rdfs:Datatype ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "on datatype" ;
+ rdfs:range rdfs:Datatype .
owl:onProperties
- a rdf:Property ;
- rdfs:comment "The property that determines the n-tuple of properties that a property restriction on an n-ary data range refers to." ;
- rdfs:domain owl:Restriction ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "on properties" ;
- rdfs:range rdf:List .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the n-tuple of properties that a property restriction on an n-ary data range refers to." ;
+ rdfs:domain owl:Restriction ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "on properties" ;
+ rdfs:range rdf:List .
owl:onProperty
- a rdf:Property ;
- rdfs:comment "The property that determines the property that a property restriction refers to." ;
- rdfs:domain owl:Restriction ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "on property" ;
- rdfs:range rdf:Property .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the property that a property restriction refers to." ;
+ rdfs:domain owl:Restriction ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "on property" ;
+ rdfs:range rdf:Property .
owl:oneOf
- a rdf:Property ;
- rdfs:comment "The property that determines the collection of individuals or data values that build an enumeration." ;
- rdfs:domain rdfs:Class ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "one of" ;
- rdfs:range rdf:List .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the collection of individuals or data values that build an enumeration." ;
+ rdfs:domain rdfs:Class ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "one of" ;
+ rdfs:range rdf:List .
owl:priorVersion
- a owl:AnnotationProperty, owl:OntologyProperty ;
- rdfs:comment "The annotation property that indicates the predecessor ontology of a given ontology." ;
- rdfs:domain owl:Ontology ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "prior version" ;
- rdfs:range owl:Ontology .
+ a owl:AnnotationProperty ,
+ owl:OntologyProperty ;
+ rdfs:comment "The annotation property that indicates the predecessor ontology of a given ontology." ;
+ rdfs:domain owl:Ontology ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "prior version" ;
+ rdfs:range owl:Ontology .
owl:propertyChainAxiom
- a rdf:Property ;
- rdfs:comment "The property that determines the n-tuple of properties that build a sub property chain of a given property." ;
- rdfs:domain owl:ObjectProperty ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "property chain axiom" ;
- rdfs:range rdf:List .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the n-tuple of properties that build a sub property chain of a given property." ;
+ rdfs:domain owl:ObjectProperty ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "property chain axiom" ;
+ rdfs:range rdf:List .
owl:propertyDisjointWith
- a rdf:Property ;
- rdfs:comment "The property that determines that two given properties are disjoint." ;
- rdfs:domain rdf:Property ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "property disjoint with" ;
- rdfs:range rdf:Property .
+ a rdf:Property ;
+ rdfs:comment "The property that determines that two given properties are disjoint." ;
+ rdfs:domain rdf:Property ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "property disjoint with" ;
+ rdfs:range rdf:Property .
owl:qualifiedCardinality
- a rdf:Property ;
- rdfs:comment "The property that determines the cardinality of an exact qualified cardinality restriction." ;
- rdfs:domain owl:Restriction ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "qualified cardinality" ;
- rdfs:range xsd:nonNegativeInteger .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the cardinality of an exact qualified cardinality restriction." ;
+ rdfs:domain owl:Restriction ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "qualified cardinality" ;
+ rdfs:range xsd:nonNegativeInteger .
owl:sameAs
- a rdf:Property ;
- rdfs:comment "The property that determines that two given individuals are equal." ;
- rdfs:domain owl:Thing ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "same as" ;
- rdfs:range owl:Thing .
+ a rdf:Property ;
+ rdfs:comment "The property that determines that two given individuals are equal." ;
+ rdfs:domain owl:Thing ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "same as" ;
+ rdfs:range owl:Thing .
owl:someValuesFrom
- a rdf:Property ;
- rdfs:comment "The property that determines the class that an existential property restriction refers to." ;
- rdfs:domain owl:Restriction ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "some values from" ;
- rdfs:range rdfs:Class .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the class that an existential property restriction refers to." ;
+ rdfs:domain owl:Restriction ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "some values from" ;
+ rdfs:range rdfs:Class .
owl:sourceIndividual
- a rdf:Property ;
- rdfs:comment "The property that determines the subject of a negative property assertion." ;
- rdfs:domain owl:NegativePropertyAssertion ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "source individual" ;
- rdfs:range owl:Thing .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the subject of a negative property assertion." ;
+ rdfs:domain owl:NegativePropertyAssertion ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "source individual" ;
+ rdfs:range owl:Thing .
owl:targetIndividual
- a rdf:Property ;
- rdfs:comment "The property that determines the object of a negative object property assertion." ;
- rdfs:domain owl:NegativePropertyAssertion ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "target individual" ;
- rdfs:range owl:Thing .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the object of a negative object property assertion." ;
+ rdfs:domain owl:NegativePropertyAssertion ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "target individual" ;
+ rdfs:range owl:Thing .
owl:targetValue
- a rdf:Property ;
- rdfs:comment "The property that determines the value of a negative data property assertion." ;
- rdfs:domain owl:NegativePropertyAssertion ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "target value" ;
- rdfs:range rdfs:Literal .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the value of a negative data property assertion." ;
+ rdfs:domain owl:NegativePropertyAssertion ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "target value" ;
+ rdfs:range rdfs:Literal .
owl:topDataProperty
- a owl:DatatypeProperty ;
- rdfs:comment "The data property that relates every individual to every data value." ;
- rdfs:domain owl:Thing ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "top data property" ;
- rdfs:range rdfs:Literal .
+ a owl:DatatypeProperty ;
+ rdfs:comment "The data property that relates every individual to every data value." ;
+ rdfs:domain owl:Thing ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "top data property" ;
+ rdfs:range rdfs:Literal .
owl:topObjectProperty
- a owl:ObjectProperty ;
- rdfs:comment "The object property that relates every two individuals." ;
- rdfs:domain owl:Thing ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "top object property" ;
- rdfs:range owl:Thing .
+ a owl:ObjectProperty ;
+ rdfs:comment "The object property that relates every two individuals." ;
+ rdfs:domain owl:Thing ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "top object property" ;
+ rdfs:range owl:Thing .
owl:unionOf
- a rdf:Property ;
- rdfs:comment "The property that determines the collection of classes or data ranges that build a union." ;
- rdfs:domain rdfs:Class ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "union of" ;
- rdfs:range rdf:List .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the collection of classes or data ranges that build a union." ;
+ rdfs:domain rdfs:Class ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "union of" ;
+ rdfs:range rdf:List .
owl:versionIRI
- a owl:OntologyProperty ;
- rdfs:comment "The property that identifies the version IRI of an ontology." ;
- rdfs:domain owl:Ontology ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "version IRI" ;
- rdfs:range owl:Ontology .
+ a owl:OntologyProperty ;
+ rdfs:comment "The property that identifies the version IRI of an ontology." ;
+ rdfs:domain owl:Ontology ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "version IRI" ;
+ rdfs:range owl:Ontology .
owl:versionInfo
- a owl:AnnotationProperty ;
- rdfs:comment "The annotation property that provides version information for an ontology or another OWL construct." ;
- rdfs:domain rdfs:Resource ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "version info" ;
- rdfs:range rdfs:Resource .
+ a owl:AnnotationProperty ;
+ rdfs:comment "The annotation property that provides version information for an ontology or another OWL construct." ;
+ rdfs:domain rdfs:Resource ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "version info" ;
+ rdfs:range rdfs:Resource .
owl:withRestrictions
- a rdf:Property ;
- rdfs:comment "The property that determines the collection of facet-value pairs that define a datatype restriction." ;
- rdfs:domain rdfs:Datatype ;
- rdfs:isDefinedBy <http://www.w3.org/2002/07/owl#> ;
- rdfs:label "with restrictions" ;
- rdfs:range rdf:List .
+ a rdf:Property ;
+ rdfs:comment "The property that determines the collection of facet-value pairs that define a datatype restriction." ;
+ rdfs:domain rdfs:Datatype ;
+ rdfs:isDefinedBy owl: ;
+ rdfs:label "with restrictions" ;
+ rdfs:range rdf:List .
diff --git a/schemas.lv2/rdf.ttl b/schemas.lv2/rdf.ttl
index a4dd8ef..cb758cb 100644
--- a/schemas.lv2/rdf.ttl
+++ b/schemas.lv2/rdf.ttl
@@ -1,129 +1,129 @@
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
-@prefix dct: <http://purl.org/dc/terms/> .
+@prefix dcterms: <http://purl.org/dc/terms/> .
-<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
- dct:description "This is the RDF Schema for the RDF vocabulary defined in the RDF namespace." ;
- dct:title "The RDF Vocabulary (RDF)" ;
- a owl:Ontology ;
- rdfs:seeAlso <http://www.w3.org/2000/01/rdf-schema-more> .
+rdf:
+ a owl:Ontology ;
+ dcterms:description "This is the RDF Schema for the RDF vocabulary defined in the RDF namespace." ;
+ dcterms:title "The RDF Vocabulary (RDF)" ;
+ rdfs:seeAlso <http://www.w3.org/2000/01/rdf-schema-more> .
rdf:Alt
- a rdfs:Class ;
- rdfs:comment "The class of containers of alternatives." ;
- rdfs:isDefinedBy <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ;
- rdfs:label "Alt" ;
- rdfs:subClassOf rdfs:Container .
+ a rdfs:Class ;
+ rdfs:comment "The class of containers of alternatives." ;
+ rdfs:isDefinedBy rdf: ;
+ rdfs:label "Alt" ;
+ rdfs:subClassOf rdfs:Container .
rdf:Bag
- a rdfs:Class ;
- rdfs:comment "The class of unordered containers." ;
- rdfs:isDefinedBy <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ;
- rdfs:label "Bag" ;
- rdfs:subClassOf rdfs:Container .
+ a rdfs:Class ;
+ rdfs:comment "The class of unordered containers." ;
+ rdfs:isDefinedBy rdf: ;
+ rdfs:label "Bag" ;
+ rdfs:subClassOf rdfs:Container .
rdf:List
- a rdfs:Class ;
- rdfs:comment "The class of RDF Lists." ;
- rdfs:isDefinedBy <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ;
- rdfs:label "List" ;
- rdfs:subClassOf rdfs:Resource .
+ a rdfs:Class ;
+ rdfs:comment "The class of RDF Lists." ;
+ rdfs:isDefinedBy rdf: ;
+ rdfs:label "List" ;
+ rdfs:subClassOf rdfs:Resource .
rdf:PlainLiteral
- a rdfs:Datatype ;
- rdfs:comment "The class of plain (i.e. untyped) literal values." ;
- rdfs:isDefinedBy <http://www.w3.org/TR/rdf-plain-literal/> ;
- rdfs:label "Plain Literal" ;
- rdfs:subClassOf rdfs:Literal .
+ a rdfs:Datatype ;
+ rdfs:comment "The class of plain (i.e. untyped) literal values." ;
+ rdfs:isDefinedBy <http://www.w3.org/TR/rdf-plain-literal/> ;
+ rdfs:label "Plain Literal" ;
+ rdfs:subClassOf rdfs:Literal .
rdf:Property
- a rdfs:Class ;
- rdfs:comment "The class of RDF properties." ;
- rdfs:isDefinedBy <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ;
- rdfs:label "Property" ;
- rdfs:subClassOf rdfs:Resource .
+ a rdfs:Class ;
+ rdfs:comment "The class of RDF properties." ;
+ rdfs:isDefinedBy rdf: ;
+ rdfs:label "Property" ;
+ rdfs:subClassOf rdfs:Resource .
rdf:Seq
- a rdfs:Class ;
- rdfs:comment "The class of ordered containers." ;
- rdfs:isDefinedBy <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ;
- rdfs:label "Seq" ;
- rdfs:subClassOf rdfs:Container .
+ a rdfs:Class ;
+ rdfs:comment "The class of ordered containers." ;
+ rdfs:isDefinedBy rdf: ;
+ rdfs:label "Seq" ;
+ rdfs:subClassOf rdfs:Container .
rdf:Statement
- a rdfs:Class ;
- rdfs:comment "The class of RDF statements." ;
- rdfs:isDefinedBy <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ;
- rdfs:label "Statement" ;
- rdfs:subClassOf rdfs:Resource .
+ a rdfs:Class ;
+ rdfs:comment "The class of RDF statements." ;
+ rdfs:isDefinedBy rdf: ;
+ rdfs:label "Statement" ;
+ rdfs:subClassOf rdfs:Resource .
rdf:XMLLiteral
- a rdfs:Datatype ;
- rdfs:comment "The class of XML literal values." ;
- rdfs:isDefinedBy <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ;
- rdfs:label "XML Literal" ;
- rdfs:subClassOf rdfs:Literal .
+ a rdfs:Datatype ;
+ rdfs:comment "The class of XML literal values." ;
+ rdfs:isDefinedBy rdf: ;
+ rdfs:label "XML Literal" ;
+ rdfs:subClassOf rdfs:Literal .
rdf:first
- a rdf:Property ;
- rdfs:comment "The first item in the subject RDF list." ;
- rdfs:domain rdf:List ;
- rdfs:isDefinedBy <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ;
- rdfs:label "first" ;
- rdfs:range rdfs:Resource .
+ a rdf:Property ;
+ rdfs:comment "The first item in the subject RDF list." ;
+ rdfs:domain rdf:List ;
+ rdfs:isDefinedBy rdf: ;
+ rdfs:label "first" ;
+ rdfs:range rdfs:Resource .
rdf:nil
- a rdf:List ;
- rdfs:comment "The empty list, with no items in it. If the rest of a list is nil then the list has no more items in it." ;
- rdfs:isDefinedBy <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ;
- rdfs:label "nil" .
+ a rdf:List ;
+ rdfs:comment "The empty list, with no items in it. If the rest of a list is nil then the list has no more items in it." ;
+ rdfs:isDefinedBy rdf: ;
+ rdfs:label "nil" .
rdf:object
- a rdf:Property ;
- rdfs:comment "The object of the subject RDF statement." ;
- rdfs:domain rdf:Statement ;
- rdfs:isDefinedBy <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ;
- rdfs:label "object" ;
- rdfs:range rdfs:Resource .
+ a rdf:Property ;
+ rdfs:comment "The object of the subject RDF statement." ;
+ rdfs:domain rdf:Statement ;
+ rdfs:isDefinedBy rdf: ;
+ rdfs:label "object" ;
+ rdfs:range rdfs:Resource .
rdf:predicate
- a rdf:Property ;
- rdfs:comment "The predicate of the subject RDF statement." ;
- rdfs:domain rdf:Statement ;
- rdfs:isDefinedBy <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ;
- rdfs:label "predicate" ;
- rdfs:range rdfs:Resource .
+ a rdf:Property ;
+ rdfs:comment "The predicate of the subject RDF statement." ;
+ rdfs:domain rdf:Statement ;
+ rdfs:isDefinedBy rdf: ;
+ rdfs:label "predicate" ;
+ rdfs:range rdfs:Resource .
rdf:rest
- a rdf:Property ;
- rdfs:comment "The rest of the subject RDF list after the first item." ;
- rdfs:domain rdf:List ;
- rdfs:isDefinedBy <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ;
- rdfs:label "rest" ;
- rdfs:range rdf:List .
+ a rdf:Property ;
+ rdfs:comment "The rest of the subject RDF list after the first item." ;
+ rdfs:domain rdf:List ;
+ rdfs:isDefinedBy rdf: ;
+ rdfs:label "rest" ;
+ rdfs:range rdf:List .
rdf:subject
- a rdf:Property ;
- rdfs:comment "The subject of the subject RDF statement." ;
- rdfs:domain rdf:Statement ;
- rdfs:isDefinedBy <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ;
- rdfs:label "subject" ;
- rdfs:range rdfs:Resource .
+ a rdf:Property ;
+ rdfs:comment "The subject of the subject RDF statement." ;
+ rdfs:domain rdf:Statement ;
+ rdfs:isDefinedBy rdf: ;
+ rdfs:label "subject" ;
+ rdfs:range rdfs:Resource .
rdf:type
- a rdf:Property ;
- rdfs:comment "The subject is an instance of a class." ;
- rdfs:domain rdfs:Resource ;
- rdfs:isDefinedBy <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ;
- rdfs:label "type" ;
- rdfs:range rdfs:Class .
+ a rdf:Property ;
+ rdfs:comment "The subject is an instance of a class." ;
+ rdfs:domain rdfs:Resource ;
+ rdfs:isDefinedBy rdf: ;
+ rdfs:label "type" ;
+ rdfs:range rdfs:Class .
rdf:value
- a rdf:Property ;
- rdfs:comment "Idiomatic property used for structured values." ;
- rdfs:domain rdfs:Resource ;
- rdfs:isDefinedBy <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ;
- rdfs:label "value" ;
- rdfs:range rdfs:Resource .
+ a rdf:Property ;
+ rdfs:comment "Idiomatic property used for structured values." ;
+ rdfs:domain rdfs:Resource ;
+ rdfs:isDefinedBy rdf: ;
+ rdfs:label "value" ;
+ rdfs:range rdfs:Resource .
diff --git a/schemas.lv2/rdfs.ttl b/schemas.lv2/rdfs.ttl
index 5f4dcf9..10cfbb7 100644
--- a/schemas.lv2/rdfs.ttl
+++ b/schemas.lv2/rdfs.ttl
@@ -1,124 +1,124 @@
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
-@prefix dct: <http://purl.org/dc/terms/> .
+@prefix dcterms: <http://purl.org/dc/terms/> .
-<http://www.w3.org/2000/01/rdf-schema#>
- dct:title "The RDF Schema vocabulary (RDFS)" ;
- a owl:Ontology ;
- rdfs:seeAlso <http://www.w3.org/2000/01/rdf-schema-more> .
+rdfs:
+ a owl:Ontology ;
+ dcterms:title "The RDF Schema vocabulary (RDFS)" ;
+ rdfs:seeAlso <http://www.w3.org/2000/01/rdf-schema-more> .
rdfs:Class
- a rdfs:Class ;
- rdfs:comment "The class of classes." ;
- rdfs:isDefinedBy <http://www.w3.org/2000/01/rdf-schema#> ;
- rdfs:label "Class" ;
- rdfs:subClassOf rdfs:Resource .
+ a rdfs:Class ;
+ rdfs:comment "The class of classes." ;
+ rdfs:isDefinedBy rdfs: ;
+ rdfs:label "Class" ;
+ rdfs:subClassOf rdfs:Resource .
rdfs:Container
- a rdfs:Class ;
- rdfs:comment "The class of RDF containers." ;
- rdfs:isDefinedBy <http://www.w3.org/2000/01/rdf-schema#> ;
- rdfs:label "Container" ;
- rdfs:subClassOf rdfs:Resource .
+ a rdfs:Class ;
+ rdfs:comment "The class of RDF containers." ;
+ rdfs:isDefinedBy rdfs: ;
+ rdfs:label "Container" ;
+ rdfs:subClassOf rdfs:Resource .
rdfs:ContainerMembershipProperty
- a rdfs:Class ;
- rdfs:comment "The class of container membership properties, rdf:_1, rdf:_2, ..., all of which are sub-properties of 'member'." ;
- rdfs:isDefinedBy <http://www.w3.org/2000/01/rdf-schema#> ;
- rdfs:label "Container Membership Property" ;
- rdfs:subClassOf rdf:Property .
+ a rdfs:Class ;
+ rdfs:comment """The class of container membership properties, rdf:_1, rdf:_2, ..., all of which are sub-properties of 'member'.""" ;
+ rdfs:isDefinedBy rdfs: ;
+ rdfs:label "Container Membership Property" ;
+ rdfs:subClassOf rdf:Property .
rdfs:Datatype
- a rdfs:Class ;
- rdfs:comment "The class of RDF datatypes." ;
- rdfs:isDefinedBy <http://www.w3.org/2000/01/rdf-schema#> ;
- rdfs:label "Datatype" ;
- rdfs:subClassOf rdfs:Class .
+ a rdfs:Class ;
+ rdfs:comment "The class of RDF datatypes." ;
+ rdfs:isDefinedBy rdfs: ;
+ rdfs:label "Datatype" ;
+ rdfs:subClassOf rdfs:Class .
rdfs:Literal
- a rdfs:Class ;
- rdfs:comment "The class of literal values, eg. textual strings and integers." ;
- rdfs:isDefinedBy <http://www.w3.org/2000/01/rdf-schema#> ;
- rdfs:label "Literal" ;
- rdfs:subClassOf rdfs:Resource .
+ a rdfs:Class ;
+ rdfs:comment "The class of literal values, eg. textual strings and integers." ;
+ rdfs:isDefinedBy rdfs: ;
+ rdfs:label "Literal" ;
+ rdfs:subClassOf rdfs:Resource .
rdfs:Resource
- a rdfs:Class ;
- rdfs:comment "The class resource, everything." ;
- rdfs:isDefinedBy <http://www.w3.org/2000/01/rdf-schema#> ;
- rdfs:label "Resource" .
+ a rdfs:Class ;
+ rdfs:comment "The class resource, everything." ;
+ rdfs:isDefinedBy rdfs: ;
+ rdfs:label "Resource" .
rdfs:comment
- a rdf:Property ;
- rdfs:comment "A description of the subject resource." ;
- rdfs:domain rdfs:Resource ;
- rdfs:isDefinedBy <http://www.w3.org/2000/01/rdf-schema#> ;
- rdfs:label "comment" ;
- rdfs:range rdfs:Literal .
+ a rdf:Property ;
+ rdfs:comment "A description of the subject resource." ;
+ rdfs:domain rdfs:Resource ;
+ rdfs:isDefinedBy rdfs: ;
+ rdfs:label "comment" ;
+ rdfs:range rdfs:Literal .
rdfs:domain
- a rdf:Property ;
- rdfs:comment "A domain of the subject property." ;
- rdfs:domain rdf:Property ;
- rdfs:isDefinedBy <http://www.w3.org/2000/01/rdf-schema#> ;
- rdfs:label "domain" ;
- rdfs:range rdfs:Class .
+ a rdf:Property ;
+ rdfs:comment "A domain of the subject property." ;
+ rdfs:domain rdf:Property ;
+ rdfs:isDefinedBy rdfs: ;
+ rdfs:label "domain" ;
+ rdfs:range rdfs:Class .
rdfs:isDefinedBy
- a rdf:Property ;
- rdfs:comment "The definition of the subject resource." ;
- rdfs:domain rdfs:Resource ;
- rdfs:isDefinedBy <http://www.w3.org/2000/01/rdf-schema#> ;
- rdfs:label "is defined by" ;
- rdfs:range rdfs:Resource ;
- rdfs:subPropertyOf rdfs:seeAlso .
+ a rdf:Property ;
+ rdfs:comment "The definition of the subject resource." ;
+ rdfs:domain rdfs:Resource ;
+ rdfs:isDefinedBy rdfs: ;
+ rdfs:label "is defined by" ;
+ rdfs:range rdfs:Resource ;
+ rdfs:subPropertyOf rdfs:seeAlso .
rdfs:label
- a rdf:Property ;
- rdfs:comment "A human-readable name for the subject." ;
- rdfs:domain rdfs:Resource ;
- rdfs:isDefinedBy <http://www.w3.org/2000/01/rdf-schema#> ;
- rdfs:label "label" ;
- rdfs:range rdfs:Literal .
+ a rdf:Property ;
+ rdfs:comment "A human-readable name for the subject." ;
+ rdfs:domain rdfs:Resource ;
+ rdfs:isDefinedBy rdfs: ;
+ rdfs:label "label" ;
+ rdfs:range rdfs:Literal .
rdfs:member
- a rdf:Property ;
- rdfs:comment "A member of the subject resource." ;
- rdfs:domain rdfs:Resource ;
- rdfs:isDefinedBy <http://www.w3.org/2000/01/rdf-schema#> ;
- rdfs:label "member" ;
- rdfs:range rdfs:Resource .
+ a rdf:Property ;
+ rdfs:comment "A member of the subject resource." ;
+ rdfs:domain rdfs:Resource ;
+ rdfs:isDefinedBy rdfs: ;
+ rdfs:label "member" ;
+ rdfs:range rdfs:Resource .
rdfs:range
- a rdf:Property ;
- rdfs:comment "A range of the subject property." ;
- rdfs:domain rdf:Property ;
- rdfs:isDefinedBy <http://www.w3.org/2000/01/rdf-schema#> ;
- rdfs:label "range" ;
- rdfs:range rdfs:Class .
+ a rdf:Property ;
+ rdfs:comment "A range of the subject property." ;
+ rdfs:domain rdf:Property ;
+ rdfs:isDefinedBy rdfs: ;
+ rdfs:label "range" ;
+ rdfs:range rdfs:Class .
rdfs:seeAlso
- a rdf:Property ;
- rdfs:comment "Further information about the subject resource." ;
- rdfs:domain rdfs:Resource ;
- rdfs:isDefinedBy <http://www.w3.org/2000/01/rdf-schema#> ;
- rdfs:label "see also" ;
- rdfs:range rdfs:Resource .
+ a rdf:Property ;
+ rdfs:comment "Further information about the subject resource." ;
+ rdfs:domain rdfs:Resource ;
+ rdfs:isDefinedBy rdfs: ;
+ rdfs:label "see also" ;
+ rdfs:range rdfs:Resource .
rdfs:subClassOf
- a rdf:Property ;
- rdfs:comment "The subject is a subclass of a class." ;
- rdfs:domain rdfs:Class ;
- rdfs:isDefinedBy <http://www.w3.org/2000/01/rdf-schema#> ;
- rdfs:label "sub-class of" ;
- rdfs:range rdfs:Class .
+ a rdf:Property ;
+ rdfs:comment "The subject is a subclass of a class." ;
+ rdfs:domain rdfs:Class ;
+ rdfs:isDefinedBy rdfs: ;
+ rdfs:label "sub-class of" ;
+ rdfs:range rdfs:Class .
rdfs:subPropertyOf
- a rdf:Property ;
- rdfs:comment "The subject is a subproperty of a property." ;
- rdfs:domain rdf:Property ;
- rdfs:isDefinedBy <http://www.w3.org/2000/01/rdf-schema#> ;
- rdfs:label "sub-property of" ;
- rdfs:range rdf:Property .
+ a rdf:Property ;
+ rdfs:comment "The subject is a subproperty of a property." ;
+ rdfs:domain rdf:Property ;
+ rdfs:isDefinedBy rdfs: ;
+ rdfs:label "sub-property of" ;
+ rdfs:range rdf:Property .
diff --git a/scripts/lv2_build_index.py b/scripts/lv2_build_index.py
new file mode 100755
index 0000000..9a287e4
--- /dev/null
+++ b/scripts/lv2_build_index.py
@@ -0,0 +1,256 @@
+#!/usr/bin/env python3
+
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: ISC
+
+"""
+Write an HTML index for a set of LV2 specifications.
+"""
+
+import datetime
+import json
+import os
+import time
+import sys
+import argparse
+import subprocess
+
+import rdflib
+
+
+doap = rdflib.Namespace("http://usefulinc.com/ns/doap#")
+lv2 = rdflib.Namespace("http://lv2plug.in/ns/lv2core#")
+owl = rdflib.Namespace("http://www.w3.org/2002/07/owl#")
+rdf = rdflib.Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
+
+
+def _subst_file(template_path, output_file, substitutions):
+ "Replace keys with values in a template file and write the result."
+
+ with open(template_path, "r", encoding="utf-8") as template:
+ for line in template:
+ for key, value in substitutions.items():
+ line = line.replace(key, value)
+
+ output_file.write(line)
+
+
+def _load_ttl(data_paths, exclude=None):
+ "Load an RDF model from a Turtle file."
+
+ model = rdflib.ConjunctiveGraph()
+ for path in data_paths:
+ if exclude is None or path not in exclude:
+ try:
+ model.parse(path, format="n3")
+ except SyntaxError as error:
+ sys.stderr.write(f"error: Failed to parse {path}\n")
+ raise error
+
+ return model
+
+
+def _warn(message):
+ "Load a warning message."
+
+ assert not message.startswith("warning: ")
+ assert not message.endswith("\n")
+ sys.stderr.write(message)
+ sys.stderr.write("\n")
+
+
+def _spec_target(spec, root, online=False):
+ "Return the relative link target for a specification."
+
+ target = spec.replace(root, "") if spec.startswith(root) else spec
+
+ return target if online else target + ".html"
+
+
+def _spec_date(model, spec, minor, micro):
+ "Return the date for a release of a specification as an RDF node."
+
+ # Get date
+ date = None
+ for release in model.objects(spec, doap.release):
+ revision = model.value(release, doap.revision, None, any=False)
+ if str(revision) == f"{minor}.{micro}":
+ date = model.value(release, doap.created, None)
+ break
+
+ # Verify that this date is the latest
+ if date is not None:
+ for other_release in model.objects(spec, doap.release):
+ for other_date in model.objects(other_release, doap.created):
+ if other_date is None:
+ _warn(f"{spec} has no doap:created date")
+ elif other_date > date:
+ _warn(f"{spec} {minor}.{micro} ({date}) is an old release")
+ break
+
+ return date
+
+
+def _spec_link_columns(spec, root, name, online):
+ "Return the first two link columns in a spec row as an HTML string."
+
+ # Find relative link target and stem
+ target = _spec_target(spec, root, online)
+ stem = os.path.splitext(os.path.basename(target))[0]
+
+ # Prefix with a comment to act as a sort key for the row
+ col = f"<!-- {stem} -->"
+
+ # Specification
+ col += f'<td><a rel="rdfs:seeAlso" href="{target}">{name}</a></td>'
+
+ # API
+ col += '<td><a rel="rdfs:seeAlso"'
+ col += f' href="../html/group__{stem}.html">{name}'
+ col += "</a></td>"
+
+ return col
+
+
+def _spec_description_column(model, spec):
+ "Return the description column in a spec row as an HTML string."
+
+ shortdesc = model.value(spec, doap.shortdesc, None, any=False)
+
+ return "<td>" + str(shortdesc) + "</td>" if shortdesc else "<td></td>"
+
+
+def index_row(model, spec, root_uri, online):
+ "Return the row for a spec as an HTML string."
+
+ # Get version
+ minor = 0
+ micro = 0
+ try:
+ minor = int(model.value(spec, lv2.minorVersion, None, any=False))
+ micro = int(model.value(spec, lv2.microVersion, None, any=False))
+ except rdflib.exceptions.UniquenessError:
+ _warn(f"{spec} has no unique valid version")
+ return ""
+
+ # Check that date is present and valid
+ if _spec_date(model, spec, minor, micro) is None:
+ _warn(f"{spec} has no doap:created date")
+ return ""
+
+ row = "<tr>"
+
+ # Specification and API
+ row += _spec_link_columns(
+ spec,
+ root_uri,
+ model.value(spec, doap.name, None).replace("LV2 ", ""),
+ online,
+ )
+
+ # Description
+ row += _spec_description_column(model, spec)
+
+ # Version
+ row += f"<td>{minor}.{micro}</td>"
+
+ # Status
+ deprecated = model.value(spec, owl.deprecated, None)
+ deprecated = deprecated and str(deprecated) not in ["0", "false"]
+ if minor == 0:
+ row += '<td><span class="error">Experimental</span></td>'
+ elif deprecated:
+ row += '<td><span class="warning">Deprecated</span></td>'
+ elif micro % 2 == 0:
+ row += '<td><span class="success">Stable</span></td>'
+ else:
+ row += '<td><span class="warning">Development</span></td>'
+
+ row += "</tr>"
+
+ return row
+
+
+def build_index(
+ lv2_source_root,
+ lv2_version,
+ input_paths,
+ root_uri,
+ online,
+):
+ "Build the LV2 specification index and write it to stdout."
+
+ model = _load_ttl(input_paths)
+
+ # Get date for this version, and list of all LV2 distributions
+ proj = rdflib.URIRef("http://lv2plug.in/ns/lv2")
+ date = None
+ for row in model.triples([proj, doap.release, None]):
+ revision = model.value(row[2], doap.revision, None)
+ created = model.value(row[2], doap.created, None)
+ if str(revision) == lv2_version:
+ date = created
+
+ dist = model.value(row[2], doap["file-release"], None)
+ if not dist or not created:
+ _warn(f"{proj} has no file release")
+
+ rows = []
+ for spec in model.triples([None, rdf.type, lv2.Specification]):
+ rows += [index_row(model, spec[0], root_uri, online)]
+
+ if date is None:
+ now = int(os.environ.get("SOURCE_DATE_EPOCH", time.time()))
+ date = datetime.datetime.utcfromtimestamp(now).strftime("%F")
+
+ _subst_file(
+ os.path.join(lv2_source_root, "doc", "index.html.in"),
+ sys.stdout,
+ {
+ "@ROWS@": "\n".join(sorted(rows)),
+ "@LV2_VERSION@": lv2_version,
+ "@DATE@": date,
+ },
+ )
+
+
+if __name__ == "__main__":
+ ap = argparse.ArgumentParser(
+ usage="%(prog)s [OPTION]... INPUT_PATH...",
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+
+ ap.add_argument("--lv2-version", help="LV2 release version")
+ ap.add_argument("--lv2-source-root", help="path to LV2 source root")
+ ap.add_argument(
+ "--root-uri",
+ default="http://lv2plug.in/ns/",
+ help="root URI for specifications",
+ )
+ ap.add_argument(
+ "--online",
+ action="store_true",
+ default=False,
+ help="build online documentation",
+ )
+ ap.add_argument("input_paths", nargs="+", help="path to Turtle input file")
+
+ args = ap.parse_args(sys.argv[1:])
+
+ if args.lv2_version is None or args.lv2_source_root is None:
+ introspect_command = ["meson", "introspect", "-a"]
+ project_info = json.loads(
+ subprocess.check_output(introspect_command).decode("utf-8")
+ )
+
+ if args.lv2_version is None:
+ args.lv2_version = project_info["projectinfo"]["version"]
+
+ if args.lv2_source_root is None:
+ meson_build_path = project_info["buildsystem_files"][0]
+ args.lv2_source_root = os.path.relpath(
+ os.path.dirname(meson_build_path)
+ )
+
+ build_index(**vars(args))
diff --git a/scripts/lv2_check_specification.py b/scripts/lv2_check_specification.py
new file mode 100755
index 0000000..0cd296e
--- /dev/null
+++ b/scripts/lv2_check_specification.py
@@ -0,0 +1,248 @@
+#!/usr/bin/env python3
+
+# Copyright 2020-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: ISC
+
+"""
+Check an LV2 specification for issues.
+"""
+
+import argparse
+import os
+import sys
+
+import rdflib
+
+foaf = rdflib.Namespace("http://xmlns.com/foaf/0.1/")
+lv2 = rdflib.Namespace("http://lv2plug.in/ns/lv2core#")
+owl = rdflib.Namespace("http://www.w3.org/2002/07/owl#")
+rdf = rdflib.Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
+rdfs = rdflib.Namespace("http://www.w3.org/2000/01/rdf-schema#")
+
+
+class Checker:
+ "A callable that checks conditions and records pass/fail counts."
+
+ def __init__(self, verbose=False):
+ self.num_checks = 0
+ self.num_errors = 0
+ self.verbose = verbose
+
+ def __call__(self, condition, name):
+ if not condition:
+ sys.stderr.write(f"error: Unmet condition: {name}\n")
+ self.num_errors += 1
+ elif self.verbose:
+ sys.stderr.write(f"note: {name}\n")
+
+ self.num_checks += 1
+ return condition
+
+ def print_summary(self):
+ "Print a summary (if verbose) when all checks are finished."
+
+ if self.verbose:
+ if self.num_errors:
+ sys.stderr.write(f"note: Failed {self.num_errors}/")
+ else:
+ sys.stderr.write("note: Passed all ")
+
+ sys.stderr.write(f"{self.num_checks} checks\n")
+
+
+def _check(condition, name):
+ "Check that condition is true, returning 1 on failure."
+
+ if not condition:
+ sys.stderr.write(f"error: Unmet condition: {name}\n")
+ return 1
+
+ return 0
+
+
+def _has_statement(model, pattern):
+ "Return true if model contains a triple matching pattern."
+
+ for _ in model.triples(pattern):
+ return True
+
+ return False
+
+
+def _has_property(model, subject, predicate):
+ "Return true if subject has any value for predicate in model."
+
+ return model.value(subject, predicate, None) is not None
+
+
+def _check_version(checker, model, spec, is_stable):
+ "Check that the version of a specification is present and valid."
+
+ minor = model.value(spec, lv2.minorVersion, None, any=False)
+ checker(minor is not None, f"{spec} has a lv2:minorVersion")
+
+ micro = model.value(spec, lv2.microVersion, None, any=False)
+ checker(micro is not None, f"{spec} has a lv2:microVersion")
+
+ if is_stable:
+ checker(int(minor) > 0, f"{spec} has a non-zero minor version")
+ checker(int(micro) % 2 == 0, f"{spec} has an even micro version")
+
+
+def _check_specification(checker, spec_dir, is_stable=False):
+ "Check all specification data for errors and omissions."
+
+ # Load manifest
+ manifest_path = os.path.join(spec_dir, "manifest.ttl")
+ model = rdflib.Graph()
+ model.parse(manifest_path, format="n3")
+
+ # Get the specification URI from the manifest
+ spec_uri = model.value(None, rdf.type, lv2.Specification, any=False)
+ if not checker(
+ spec_uri is not None,
+ manifest_path + " declares an lv2:Specification",
+ ):
+ return 1
+
+ # Check that the manifest declares a valid version
+ _check_version(checker, model, spec_uri, is_stable)
+
+ # Get the link to the main document from the manifest
+ document = model.value(spec_uri, rdfs.seeAlso, None, any=False)
+ if not checker(
+ document is not None,
+ manifest_path + " has one rdfs:seeAlso link to the definition",
+ ):
+ return 1
+
+ # Load main document into the model
+ model.parse(document, format="n3")
+
+ # Check that the main data files aren't bloated with extended documentation
+ checker(
+ not _has_statement(model, [None, lv2.documentation, None]),
+ f"{document} has no lv2:documentation",
+ )
+
+ # Load all other directly linked data files (for any other subjects)
+ for link in sorted(model.triples([None, rdfs.seeAlso, None])):
+ if link[2] != document and link[2].endswith(".ttl"):
+ model.parse(link[2], format="n3")
+
+ # Check that all properties have a more specific type
+ for typing in sorted(model.triples([None, rdf.type, rdf.Property])):
+ subject = typing[0]
+
+ checker(isinstance(subject, rdflib.term.URIRef), f"{subject} is a URI")
+
+ if str(subject) == "http://lv2plug.in/ns/ext/patch#value":
+ continue # patch:value is just a "promiscuous" rdf:Property
+
+ types = list(model.objects(subject, rdf.type))
+
+ checker(
+ (owl.DatatypeProperty in types)
+ or (owl.ObjectProperty in types)
+ or (owl.AnnotationProperty in types),
+ f"{subject} is a Datatype, Object, or Annotation property",
+ )
+
+ # Get all subjects that have an explicit rdf:type
+ typed_subjects = set()
+ for typing in model.triples([None, rdf.type, None]):
+ typed_subjects.add(typing[0])
+
+ # Check that all named and typed resources have labels and comments
+ for subject in typed_subjects:
+ if isinstance(
+ subject, rdflib.term.BNode
+ ) or foaf.Person in model.objects(subject, rdf.type):
+ continue
+
+ if checker(
+ _has_property(model, subject, rdfs.label),
+ f"{subject} has a rdfs:label",
+ ):
+ label = str(model.value(subject, rdfs.label, None))
+
+ checker(
+ not label.endswith("."),
+ f"{subject} label has no trailing '.'",
+ )
+ checker(
+ label.find("\n") == -1,
+ f"{subject} label is a single line",
+ )
+ checker(
+ label == label.strip(),
+ f"{subject} label has stripped whitespace",
+ )
+
+ if checker(
+ _has_property(model, subject, rdfs.comment),
+ f"{subject} has a rdfs:comment",
+ ):
+ comment = str(model.value(subject, rdfs.comment, None))
+
+ checker(
+ comment.endswith("."),
+ f"{subject} comment has a trailing '.'",
+ )
+ checker(
+ comment.find("\n") == -1 and comment.find("\r"),
+ f"{subject} comment is a single line",
+ )
+ checker(
+ comment == comment.strip(),
+ f"{subject} comment has stripped whitespace",
+ )
+
+ # Check that lv2:documentation, if present, is proper Markdown
+ documentation = model.value(subject, lv2.documentation, None)
+ if documentation is not None:
+ checker(
+ documentation.datatype == lv2.Markdown,
+ f"{subject} documentation is explicitly Markdown",
+ )
+ checker(
+ str(documentation).startswith("\n\n"),
+ f"{subject} documentation starts with blank line",
+ )
+ checker(
+ str(documentation).endswith("\n\n"),
+ f"{subject} documentation ends with blank line",
+ )
+
+ return checker.num_errors
+
+
+if __name__ == "__main__":
+ ap = argparse.ArgumentParser(
+ usage="%(prog)s [OPTION]... BUNDLE",
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+
+ ap.add_argument(
+ "--stable",
+ action="store_true",
+ help="enable checks for stable release versions",
+ )
+
+ ap.add_argument(
+ "-v", "--verbose", action="store_true", help="print successful checks"
+ )
+
+ ap.add_argument(
+ "BUNDLE", help="path to specification bundle or manifest.ttl"
+ )
+
+ args = ap.parse_args(sys.argv[1:])
+
+ if os.path.basename(args.BUNDLE):
+ args.BUNDLE = os.path.dirname(args.BUNDLE)
+
+ sys.exit(
+ _check_specification(Checker(args.verbose), args.BUNDLE, args.stable)
+ )
diff --git a/scripts/lv2_check_syntax.py b/scripts/lv2_check_syntax.py
new file mode 100755
index 0000000..391e4e1
--- /dev/null
+++ b/scripts/lv2_check_syntax.py
@@ -0,0 +1,85 @@
+#!/usr/bin/env python3
+
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: ISC
+
+"""
+Check that a Turtle file has valid syntax and strict formatting.
+
+This is a strict tool that enforces machine formatting with serdi.
+"""
+
+import argparse
+import difflib
+import filecmp
+import sys
+import tempfile
+import os
+import subprocess
+
+
+def _show_diff(from_lines, to_lines, from_path, to_path):
+ "Show a diff between two files, returning non-zero if they differ."
+
+ differences = False
+ for line in difflib.unified_diff(
+ from_lines,
+ to_lines,
+ fromfile=from_path,
+ tofile=to_path,
+ ):
+ sys.stderr.write(line)
+ differences = True
+
+ return int(differences)
+
+
+def _check_file_equals(patha, pathb):
+ "Check that two files are equal, returning non-zero if they differ."
+
+ for path in (patha, pathb):
+ if not os.access(path, os.F_OK):
+ sys.stderr.write(f"error: missing file {path}")
+ return 1
+
+ if filecmp.cmp(patha, pathb, shallow=False):
+ return 0
+
+ with open(patha, "r", encoding="utf-8") as in_a:
+ with open(pathb, "r", encoding="utf-8") as in_b:
+ return _show_diff(in_a.readlines(), in_b.readlines(), patha, pathb)
+
+
+def run(serdi, filenames):
+ "Check that every file in filenames has valid formatted syntax."
+
+ status = 0
+
+ for filename in filenames:
+ rel_path = os.path.relpath(filename)
+ with tempfile.NamedTemporaryFile(mode="w", delete=False) as out:
+ out_name = out.name
+ command = [serdi, "-o", "turtle", rel_path]
+ subprocess.check_call(command, stdout=out)
+
+ if _check_file_equals(rel_path, out_name):
+ status = 1
+
+ os.remove(out_name)
+
+ return status
+
+
+if __name__ == "__main__":
+ ap = argparse.ArgumentParser(
+ usage="%(prog)s [OPTION]... TURTLE_FILE...",
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+
+ ap.add_argument("--serdi", default="serdi", help="path to serdi")
+ ap.add_argument("TURTLE_FILE", nargs="+", help="input file to check")
+
+ args = ap.parse_args(sys.argv[1:])
+
+ sys.exit(run(args.serdi, args.TURTLE_FILE))
diff --git a/scripts/lv2_write_news.py b/scripts/lv2_write_news.py
new file mode 100755
index 0000000..6ce935c
--- /dev/null
+++ b/scripts/lv2_write_news.py
@@ -0,0 +1,258 @@
+#!/usr/bin/env python3
+
+# Copyright 2020-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: ISC
+
+"""
+Write a NEWS file from RDF data.
+
+The output is in Debian changelog format, which can be parsed by
+dpkg-parsechangelog, among other things.
+"""
+
+import argparse
+import os
+import sys
+import datetime
+import textwrap
+import urllib
+import re
+
+import rdflib
+
+doap = rdflib.Namespace("http://usefulinc.com/ns/doap#")
+dcs = rdflib.Namespace("http://ontologi.es/doap-changeset#")
+rdfs = rdflib.Namespace("http://www.w3.org/2000/01/rdf-schema#")
+foaf = rdflib.Namespace("http://xmlns.com/foaf/0.1/")
+rdf = rdflib.Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
+
+
+def _is_release_version(version):
+ "Return true if `version` is a stable version number."
+
+ if len(version) not in [2, 3] or version[0] == 0:
+ return False
+
+ minor = version[len(version) - 2]
+ micro = version[len(version) - 1]
+
+ return micro % 2 == 0 and (len(version) == 2 or minor % 2 == 0)
+
+
+def _parse_datetime(string):
+ "Parse string as either a datetime or a date."
+
+ try:
+ return datetime.datetime.strptime(string, "%Y-%m-%dT%H:%M:%S%z")
+ except ValueError:
+ return datetime.datetime.strptime(string, "%Y-%m-%d")
+
+
+def _release_entry(graph, release):
+ "Return a news entry for a release."
+
+ revision = graph.value(release, doap.revision, None)
+ date = graph.value(release, doap.created, None)
+ blamee = graph.value(release, dcs.blame, None)
+ changeset = graph.value(release, dcs.changeset, None)
+ dist = graph.value(release, doap["file-release"], None)
+
+ if not revision or not date or not blamee or not changeset:
+ return None
+
+ version = tuple(map(int, revision.split(".")))
+
+ entry = {
+ "version": version,
+ "revision": str(revision),
+ "date": _parse_datetime(date),
+ "status": "stable" if _is_release_version(version) else "unstable",
+ "items": [],
+ }
+
+ if dist is not None:
+ entry["dist"] = dist
+
+ for j in graph.triples([changeset, dcs.item, None]):
+ item = str(graph.value(j[2], rdfs.label, None))
+ entry["items"] += [item]
+
+ entry["blamee_name"] = str(graph.value(blamee, foaf.name, None))
+ entry["blamee_mbox"] = str(graph.value(blamee, foaf.mbox, None))
+ return entry
+
+
+def _project_entries(graph, project):
+ "Return a map from version to news entries for a project"
+
+ entries = {}
+ for link in graph.triples([project, doap.release, None]):
+ entry = _release_entry(graph, link[2])
+ if entry is not None:
+ entries[entry["version"]] = entry
+ else:
+ sys.stderr.write(f"warning: Ignored partial {project} release\n")
+
+ return entries
+
+
+def _read_turtle_news(in_files):
+ "Read news entries from Turtle."
+
+ graph = rdflib.Graph()
+
+ # Parse input files
+ for i in in_files:
+ graph.parse(i)
+
+ # Read news for every project in the data
+ projects = {t[0] for t in graph.triples([None, rdf.type, doap.Project])}
+ entries_by_project = {}
+ for project in projects:
+ # Load any associated files
+ for uri in graph.triples([project, rdfs.seeAlso, None]):
+ if uri[2].endswith(".ttl"):
+ graph.parse(uri[2])
+
+ # Use the symbol from the URI as a name, or failing that, the doap:name
+ name = os.path.basename(urllib.parse.urlparse(str(project)).path)
+ if not name:
+ name = graph.value(project, doap.name, None)
+
+ entries = _project_entries(graph, project)
+ for _, entry in entries.items():
+ entry["name"] = name
+
+ entries_by_project[str(project)] = entries
+
+ return entries_by_project
+
+
+def _write_news_item(out, item):
+ "Write a single item (change) in NEWS format."
+
+ out.write("\n * " + "\n ".join(textwrap.wrap(item, width=74)))
+
+
+def _write_news_entry(out, entry):
+ "Write an entry (version) to out in NEWS format."
+
+ # Summary header
+ summary = f'{entry["name"]} ({entry["revision"]}) {entry["status"]}'
+ out.write(f"{summary}; urgency=medium\n")
+
+ # Individual change items
+ for item in sorted(entry["items"]):
+ _write_news_item(out, item)
+
+ # Trailer line
+ mbox = entry["blamee_mbox"].replace("mailto:", "")
+ author = f'{entry["blamee_name"]} <{mbox}>'
+ date = entry["date"]
+ if date.tzinfo is None: # Assume UTC (dpkg-parsechangelog requires it)
+ date = date.strftime("%a, %d %b %Y %H:%M:%S +0000")
+ else:
+ date = date.strftime("%a, %d %b %Y %H:%M:%S %z")
+
+ out.write(f"\n\n -- {author} {date}\n")
+
+
+def _write_single_project_news(out, entries):
+ "Write a NEWS file for entries of a single project to out."
+
+ revisions = sorted(entries.keys(), reverse=True)
+ for revision in revisions:
+ entry = entries[revision]
+ out.write("\n" if revision != revisions[0] else "")
+ _write_news_entry(out, entry)
+
+
+def _write_meta_project_news(out, top_project, entries_by_project):
+ "Write a NEWS file for a meta-project that contains others."
+
+ top_name = os.path.basename(urllib.parse.urlparse(str(top_project)).path)
+ release_pattern = rf".*/{top_name}-([0-9\.]*).tar.bz2"
+
+ # Pop the entries for the top project
+ top_entries = entries_by_project.pop(top_project)
+
+ # Add items from the other projects to the corresponding top entry
+ for _, entries in entries_by_project.items():
+ for version, entry in entries.items():
+ if "dist" in entry:
+ match = re.match(release_pattern, entry["dist"])
+ if match:
+ version = tuple(map(int, match.group(1).split(".")))
+ for item in entry["items"]:
+ top_entries[version]["items"] += [
+ f'{entry["name"]}: {item}'
+ ]
+
+ for version in sorted(top_entries.keys(), reverse=True):
+ out.write("\n" if version != max(top_entries.keys()) else "")
+ _write_news_entry(out, top_entries[version])
+
+
+def _write_text_news(out, entries_by_project, top_project=None):
+ "Write NEWS in standard Debian changelog format."
+
+ if len(entries_by_project) > 1:
+ if top_project is None:
+ sys.stderr.write("error: --top is required for multi-projects\n")
+ return 1
+
+ _write_meta_project_news(out, top_project, entries_by_project)
+ else:
+ project = next(iter(entries_by_project))
+ _write_single_project_news(out, entries_by_project[project])
+
+ return 0
+
+
+if __name__ == "__main__":
+ ap = argparse.ArgumentParser(
+ usage="%(prog)s [OPTION]... DATA_FILE...",
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+
+ ap.add_argument(
+ "-o",
+ "--output",
+ metavar="OUTPUT_FILE",
+ help="output file path",
+ )
+
+ ap.add_argument(
+ "-t",
+ "--top-project",
+ metavar="OUTPUT_FILE",
+ help="URI of parent meta-project with file releases",
+ )
+
+ ap.add_argument(
+ "DATA_FILE",
+ nargs="+",
+ help="path to a Turtle file with release data",
+ )
+
+ args = ap.parse_args(sys.argv[1:])
+
+ if not args.output and "MESON_DIST_ROOT" in os.environ:
+ args.output = os.path.join(os.getenv("MESON_DIST_ROOT"), "NEWS")
+
+ if not args.output:
+ sys.exit(
+ _write_text_news(
+ sys.stdout, _read_turtle_news(args.DATA_FILE), args.top_project
+ )
+ )
+ else:
+ with open(args.output, "w", encoding="utf-8") as output_file:
+ sys.exit(
+ _write_text_news(
+ output_file,
+ _read_turtle_news(args.DATA_FILE),
+ args.top_project,
+ )
+ )
diff --git a/scripts/meson.build b/scripts/meson.build
new file mode 100644
index 0000000..400d583
--- /dev/null
+++ b/scripts/meson.build
@@ -0,0 +1,9 @@
+# Copyright 2021-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+lv2_scripts = files(
+ 'lv2_build_index.py',
+ 'lv2_check_specification.py',
+ 'lv2_check_syntax.py',
+ 'lv2_write_news.py',
+)
diff --git a/test/.clang-tidy b/test/.clang-tidy
new file mode 100644
index 0000000..f73d7a6
--- /dev/null
+++ b/test/.clang-tidy
@@ -0,0 +1,20 @@
+Checks: >
+ *,
+ -*-else-after-return,
+ -*-magic-numbers,
+ -*-uppercase-literal-suffix,
+ -altera-*,
+ -bugprone-easily-swappable-parameters,
+ -bugprone-macro-parentheses,
+ -bugprone-suspicious-include,
+ -bugprone-suspicious-string-compare,
+ -llvm-header-guard,
+ -llvmlibc-implementation-in-namespace,
+ -llvmlibc-restrict-system-libc-headers,
+ -modernize-use-trailing-return-type,
+ -performance-no-int-to-ptr,
+ -readability-function-cognitive-complexity,
+ -readability-identifier-length,
+WarningsAsErrors: '*'
+HeaderFilterRegex: '.*'
+FormatStyle: file
diff --git a/lv2/atom/atom-test-utils.c b/test/atom_test_utils.c
index ae368c8..ae368c8 100644
--- a/lv2/atom/atom-test-utils.c
+++ b/test/atom_test_utils.c
diff --git a/test/meson.build b/test/meson.build
new file mode 100644
index 0000000..8c5a68a
--- /dev/null
+++ b/test/meson.build
@@ -0,0 +1,137 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+########
+# Data #
+########
+
+# Check for spelling errors
+codespell = find_program('codespell', required: get_option('tests'))
+if codespell.found()
+ ignore = [
+ lv2_source_root / 'doc' / 'style' / 'pygments.css',
+ lv2_source_root / 'lv2specgen' / 'DTD',
+ lv2_source_root / 'schemas.lv2' / 'doap.ttl',
+ ]
+
+ test(
+ 'codespell',
+ codespell,
+ args: [
+ '-d',
+ '-q', '3',
+ '-S', ','.join(ignore),
+ lv2_source_root / 'doc',
+ lv2_source_root / 'lv2',
+ lv2_source_root / 'lv2specgen',
+ lv2_source_root / 'plugins',
+ lv2_source_root / 'schemas.lv2',
+ ],
+ suite: 'data',
+ )
+endif
+
+# Check that specification data is strictly formatted
+serdi = find_program('serdi', required: get_option('tests'))
+if serdi.found() and not meson.is_cross_build()
+ lv2_check_syntax = files(lv2_source_root / 'scripts' / 'lv2_check_syntax.py')
+
+ test('syntax',
+ lv2_check_syntax,
+ args: ['--serdi', serdi.full_path()] + spec_files + schema_data,
+ suite: 'data')
+endif
+
+# Check that specification data validates
+sord_validate = find_program('sord_validate', required: get_option('tests'))
+if sord_validate.found()
+ test('valid',
+ sord_validate,
+ args: spec_files + schema_data,
+ suite: 'data')
+endif
+
+########
+# Code #
+########
+
+# Check that all the headers compile cleanly in C
+test('c',
+ executable(
+ 'test_build_c',
+ files('test_build.c'),
+ c_args: c_suppressions,
+ dependencies: lv2_dep,
+ ),
+ suite: 'build')
+
+# Check that all the headers compile cleanly in C++
+if is_variable('cpp')
+ test('cpp',
+ executable(
+ 'test_build_cpp',
+ files('test_build.cpp'),
+ cpp_args: cpp_suppressions,
+ dependencies: lv2_dep,
+ ),
+ suite: 'build')
+endif
+
+##########
+# Python #
+##########
+
+if get_option('strict')
+ flake8 = find_program('flake8', required: get_option('tests'))
+ pylint = find_program('pylint', required: get_option('tests'))
+ black = find_program('black', required: get_option('tests'))
+
+ # Scripts that don't pass with pylint
+ lax_python_scripts = files(
+ '../lv2specgen/lv2docgen.py',
+ '../lv2specgen/lv2specgen.py',
+ )
+
+ # Scripts that pass with everything including pylint
+ strict_python_scripts = lv2_scripts + files('../plugins/literasc.py')
+
+ all_python_scripts = lax_python_scripts + strict_python_scripts
+
+ if is_variable('black') and black.found()
+ black_opts = ['-l', '79', '-q', '--check']
+ test('black', black, args: black_opts + all_python_scripts, suite: 'scripts')
+ endif
+
+ if is_variable('flake8') and flake8.found()
+ test('flake8', flake8, args: all_python_scripts, suite: 'scripts')
+ endif
+
+ if is_variable('pylint') and pylint.found()
+ test('pylint', pylint, args: strict_python_scripts, suite: 'scripts')
+ endif
+endif
+
+##############
+# Unit Tests #
+##############
+
+test_names = [
+ 'atom',
+ 'forge_overflow',
+]
+
+# Build and run tests
+if not get_option('tests').disabled()
+ foreach test_name : test_names
+ test(
+ test_name,
+ executable(
+ test_name,
+ files('test_@0@.c'.format(test_name)),
+ c_args: c_suppressions,
+ dependencies: lv2_dep,
+ ),
+ suite: 'unit',
+ )
+ endforeach
+endif
diff --git a/lv2/atom/atom-test.c b/test/test_atom.c
index 64f8953..5771694 100644
--- a/lv2/atom/atom-test.c
+++ b/test/test_atom.c
@@ -14,13 +14,13 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "lv2/atom/atom-test-utils.c"
+#include "atom_test_utils.c"
+
#include "lv2/atom/atom.h"
#include "lv2/atom/forge.h"
#include "lv2/atom/util.h"
#include "lv2/urid/urid.h"
-#include <inttypes.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
@@ -73,7 +73,7 @@ main(void)
LV2_Atom_Long* two = (LV2_Atom_Long*)lv2_atom_forge_deref(
&forge, lv2_atom_forge_long(&forge, 2));
if (two->body != 2) {
- return test_fail("%" PRId64 " != 2\n", two->body);
+ return test_fail("%ld != 2\n", (long)two->body);
}
// eg_three = (Float)3.0
diff --git a/test/test_build.c b/test/test_build.c
new file mode 100644
index 0000000..146ad71
--- /dev/null
+++ b/test/test_build.c
@@ -0,0 +1,52 @@
+/*
+ Copyright 2022 David Robillard <d@drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#include "lv2/atom/atom.h" // IWYU pragma: keep
+#include "lv2/atom/forge.h" // IWYU pragma: keep
+#include "lv2/atom/util.h" // IWYU pragma: keep
+#include "lv2/buf-size/buf-size.h" // IWYU pragma: keep
+#include "lv2/core/attributes.h" // IWYU pragma: keep
+#include "lv2/core/lv2.h" // IWYU pragma: keep
+#include "lv2/core/lv2_util.h" // IWYU pragma: keep
+#include "lv2/data-access/data-access.h" // IWYU pragma: keep
+#include "lv2/dynmanifest/dynmanifest.h" // IWYU pragma: keep
+#include "lv2/event/event-helpers.h" // IWYU pragma: keep
+#include "lv2/event/event.h" // IWYU pragma: keep
+#include "lv2/instance-access/instance-access.h" // IWYU pragma: keep
+#include "lv2/log/log.h" // IWYU pragma: keep
+#include "lv2/log/logger.h" // IWYU pragma: keep
+#include "lv2/midi/midi.h" // IWYU pragma: keep
+#include "lv2/morph/morph.h" // IWYU pragma: keep
+#include "lv2/options/options.h" // IWYU pragma: keep
+#include "lv2/parameters/parameters.h" // IWYU pragma: keep
+#include "lv2/patch/patch.h" // IWYU pragma: keep
+#include "lv2/port-groups/port-groups.h" // IWYU pragma: keep
+#include "lv2/port-props/port-props.h" // IWYU pragma: keep
+#include "lv2/presets/presets.h" // IWYU pragma: keep
+#include "lv2/resize-port/resize-port.h" // IWYU pragma: keep
+#include "lv2/state/state.h" // IWYU pragma: keep
+#include "lv2/time/time.h" // IWYU pragma: keep
+#include "lv2/ui/ui.h" // IWYU pragma: keep
+#include "lv2/units/units.h" // IWYU pragma: keep
+#include "lv2/uri-map/uri-map.h" // IWYU pragma: keep
+#include "lv2/urid/urid.h" // IWYU pragma: keep
+#include "lv2/worker/worker.h" // IWYU pragma: keep
+
+int
+main(void)
+{
+ return 0;
+}
diff --git a/test/test_build.cpp b/test/test_build.cpp
new file mode 100644
index 0000000..dc269a6
--- /dev/null
+++ b/test/test_build.cpp
@@ -0,0 +1,67 @@
+/*
+ Copyright 2022 David Robillard <d@drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#if defined(__clang__)
+_Pragma("clang diagnostic push")
+_Pragma("clang diagnostic ignored \"-Wold-style-cast\"")
+_Pragma("clang diagnostic ignored \"-Wzero-as-null-pointer-constant\"")
+#elif defined(__GNUC__)
+_Pragma("GCC diagnostic push")
+_Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=const\"")
+#endif
+
+#include "lv2/atom/atom.h" // IWYU pragma: keep
+#include "lv2/atom/forge.h" // IWYU pragma: keep
+#include "lv2/atom/util.h" // IWYU pragma: keep
+#include "lv2/buf-size/buf-size.h" // IWYU pragma: keep
+#include "lv2/core/attributes.h" // IWYU pragma: keep
+#include "lv2/core/lv2.h" // IWYU pragma: keep
+#include "lv2/core/lv2_util.h" // IWYU pragma: keep
+#include "lv2/data-access/data-access.h" // IWYU pragma: keep
+#include "lv2/dynmanifest/dynmanifest.h" // IWYU pragma: keep
+#include "lv2/event/event-helpers.h" // IWYU pragma: keep
+#include "lv2/event/event.h" // IWYU pragma: keep
+#include "lv2/instance-access/instance-access.h" // IWYU pragma: keep
+#include "lv2/log/log.h" // IWYU pragma: keep
+#include "lv2/log/logger.h" // IWYU pragma: keep
+#include "lv2/midi/midi.h" // IWYU pragma: keep
+#include "lv2/morph/morph.h" // IWYU pragma: keep
+#include "lv2/options/options.h" // IWYU pragma: keep
+#include "lv2/parameters/parameters.h" // IWYU pragma: keep
+#include "lv2/patch/patch.h" // IWYU pragma: keep
+#include "lv2/port-groups/port-groups.h" // IWYU pragma: keep
+#include "lv2/port-props/port-props.h" // IWYU pragma: keep
+#include "lv2/presets/presets.h" // IWYU pragma: keep
+#include "lv2/resize-port/resize-port.h" // IWYU pragma: keep
+#include "lv2/state/state.h" // IWYU pragma: keep
+#include "lv2/time/time.h" // IWYU pragma: keep
+#include "lv2/ui/ui.h" // IWYU pragma: keep
+#include "lv2/units/units.h" // IWYU pragma: keep
+#include "lv2/uri-map/uri-map.h" // IWYU pragma: keep
+#include "lv2/urid/urid.h" // IWYU pragma: keep
+#include "lv2/worker/worker.h" // IWYU pragma: keep
+
+int
+main()
+{
+ return 0;
+}
+
+#if defined(__clang__)
+_Pragma("clang diagnostic pop")
+#elif defined(__GNUC__)
+_Pragma("GCC diagnostic pop")
+#endif
diff --git a/lv2/atom/forge-overflow-test.c b/test/test_forge_overflow.c
index 5741453..e00b40d 100644
--- a/lv2/atom/forge-overflow-test.c
+++ b/test/test_forge_overflow.c
@@ -14,7 +14,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "lv2/atom/atom-test-utils.c"
+#include "atom_test_utils.c"
+
#include "lv2/atom/atom.h"
#include "lv2/atom/forge.h"
#include "lv2/urid/urid.h"
@@ -37,12 +38,12 @@ test_string_overflow(void)
lv2_atom_forge_init(&forge, &map);
// Check that writing increasingly long strings fails at the right point
- for (size_t count = 0; count < MAX_CHARS; ++count) {
+ for (unsigned count = 0; count < MAX_CHARS; ++count) {
lv2_atom_forge_set_buffer(&forge, buf, capacity);
const LV2_Atom_Forge_Ref ref = lv2_atom_forge_string(&forge, str, count);
if (!ref) {
- return test_fail("Failed to write %zu byte string\n", count);
+ return test_fail("Failed to write %u byte string\n", count);
}
}
diff --git a/util/lv2_validate.in b/util/lv2_validate.in
index 2295f98..66fee6b 100755
--- a/util/lv2_validate.in
+++ b/util/lv2_validate.in
@@ -85,7 +85,7 @@ sord_validate \
"$LV2DIR/schemas.lv2/xsd.ttl" \
"$LV2DIR/schemas.lv2/manifest.ttl" \
"$LV2DIR/schemas.lv2/rdf.ttl" \
- "$LV2DIR/schemas.lv2/dct.ttl" \
+ "$LV2DIR/schemas.lv2/dcterms.ttl" \
"$LV2DIR/schemas.lv2/doap.ttl" \
"$LV2DIR/schemas.lv2/rdfs.ttl" \
"$LV2DIR/schemas.lv2/dcs.ttl" \
diff --git a/util/meson.build b/util/meson.build
new file mode 100644
index 0000000..ed43f1e
--- /dev/null
+++ b/util/meson.build
@@ -0,0 +1,12 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+config = configuration_data({'LV2DIR': lv2dir})
+
+lv2_validate = configure_file(
+ configuration: config,
+ input: files('lv2_validate.in'),
+ install_dir: get_option('bindir'),
+ install_mode: 'rwxr-xr-x',
+ output: 'lv2_validate',
+)
diff --git a/waf b/waf
deleted file mode 100755
index 58d14c3..0000000
--- a/waf
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python
-
-# Minimal waf script for projects that include waflib directly
-
-import sys
-import inspect
-import os
-
-try:
- from waflib import Context, Scripting
-except Exception as e:
- sys.stderr.write('error: Failed to import waf (%s)\n' % e)
- if os.path.exists('.git'):
- sys.stderr.write("Are submodules up to date? "
- "Try 'git submodule update --init --recursive'\n")
-
- sys.exit(1)
-
-
-def main():
- script_path = os.path.abspath(inspect.getfile(inspect.getmodule(main)))
- project_path = os.path.dirname(os.path.realpath(script_path))
- Scripting.waf_entry_point(os.getcwd(), Context.WAFVERSION, project_path)
-
-
-if __name__ == '__main__':
- main()
diff --git a/waflib b/waflib
deleted file mode 160000
-Subproject b600c928b221a001faeab7bd92786d0b25714bc
diff --git a/wscript b/wscript
deleted file mode 100644
index 5c7b5fd..0000000
--- a/wscript
+++ /dev/null
@@ -1,849 +0,0 @@
-#!/usr/bin/env python
-
-import os
-import re
-import sys
-
-from waflib import Build, Context, Logs, Options, Scripting, Utils
-from waflib.extras import autowaf as autowaf
-
-# Mandatory waf variables
-APPNAME = 'lv2' # Package name for waf dist
-VERSION = '1.18.3' # Package version for waf dist
-top = '.' # Source directory
-out = 'build' # Build directory
-
-# Release variables
-title = 'LV2'
-uri = 'http://lv2plug.in/ns/lv2'
-dist_pattern = 'http://lv2plug.in/spec/lv2-%d.%d.%d.tar.bz2'
-post_tags = []
-
-# Links for documentation
-list_email = 'devel@lists.lv2plug.in'
-list_page = 'http://lists.lv2plug.in/listinfo.cgi/devel-lv2plug.in'
-
-# Map of specification base name to old URI-style include path
-spec_map = {
- 'atom': 'lv2/lv2plug.in/ns/ext/atom',
- 'buf-size': 'lv2/lv2plug.in/ns/ext/buf-size',
- 'core': 'lv2/lv2plug.in/ns/lv2core',
- 'data-access': 'lv2/lv2plug.in/ns/ext/data-access',
- 'dynmanifest': 'lv2/lv2plug.in/ns/ext/dynmanifest',
- 'event': 'lv2/lv2plug.in/ns/ext/event',
- 'instance-access': 'lv2/lv2plug.in/ns/ext/instance-access',
- 'log': 'lv2/lv2plug.in/ns/ext/log',
- 'midi': 'lv2/lv2plug.in/ns/ext/midi',
- 'morph': 'lv2/lv2plug.in/ns/ext/morph',
- 'options': 'lv2/lv2plug.in/ns/ext/options',
- 'parameters': 'lv2/lv2plug.in/ns/ext/parameters',
- 'patch': 'lv2/lv2plug.in/ns/ext/patch',
- 'port-groups': 'lv2/lv2plug.in/ns/ext/port-groups',
- 'port-props': 'lv2/lv2plug.in/ns/ext/port-props',
- 'presets': 'lv2/lv2plug.in/ns/ext/presets',
- 'resize-port': 'lv2/lv2plug.in/ns/ext/resize-port',
- 'state': 'lv2/lv2plug.in/ns/ext/state',
- 'time': 'lv2/lv2plug.in/ns/ext/time',
- 'ui': 'lv2/lv2plug.in/ns/extensions/ui',
- 'units': 'lv2/lv2plug.in/ns/extensions/units',
- 'uri-map': 'lv2/lv2plug.in/ns/ext/uri-map',
- 'urid': 'lv2/lv2plug.in/ns/ext/urid',
- 'worker': 'lv2/lv2plug.in/ns/ext/worker'}
-
-
-def options(ctx):
- ctx.load('compiler_c')
- ctx.load('compiler_cxx')
- ctx.load('lv2')
- ctx.add_flags(
- ctx.configuration_options(),
- {'no-coverage': 'Do not use gcov for code coverage',
- 'online-docs': 'Build documentation for web hosting',
- 'no-check-links': 'Do not check documentation for broken links',
- 'no-plugins': 'Do not build example plugins',
- 'copy-headers': 'Copy headers instead of linking to bundle'})
-
-
-def configure(conf):
- try:
- conf.load('compiler_c', cache=True)
- except Exception:
- Options.options.build_tests = False
- Options.options.no_plugins = True
-
- try:
- conf.load('compiler_cxx', cache=True)
- except Exception:
- pass
-
- if Options.options.online_docs:
- Options.options.docs = True
-
- conf.load('lv2', cache=True)
- conf.load('autowaf', cache=True)
- autowaf.set_c_lang(conf, 'c99')
-
- if Options.options.strict:
- # Check for programs used by lint target
- conf.find_program("flake8", var="FLAKE8", mandatory=False)
- conf.find_program("clang-tidy", var="CLANG_TIDY", mandatory=False)
- conf.find_program("iwyu_tool", var="IWYU_TOOL", mandatory=False)
-
- if Options.options.ultra_strict:
- autowaf.add_compiler_flags(conf.env, 'c', {
- 'gcc': [
- '-Wno-bad-function-cast',
- ],
- 'clang': [
- '-Wno-bad-function-cast',
- ]
- })
-
- autowaf.add_compiler_flags(conf.env, '*', {
- 'clang': [
- '-Wno-cast-align',
- '-Wno-cast-qual',
- '-Wno-documentation-unknown-command',
- '-Wno-double-promotion',
- '-Wno-float-conversion',
- '-Wno-float-equal',
- '-Wno-implicit-float-conversion',
- '-Wno-padded',
- '-Wno-reserved-id-macro',
- '-Wno-shorten-64-to-32',
- '-Wno-sign-conversion',
- '-Wno-switch-enum',
- '-Wno-unused-parameter',
- ],
- 'gcc': [
- '-Wno-cast-align',
- '-Wno-cast-qual',
- '-Wno-conversion',
- '-Wno-double-promotion',
- '-Wno-float-equal',
- '-Wno-inline',
- '-Wno-padded',
- '-Wno-parentheses',
- '-Wno-suggest-attribute=const',
- '-Wno-suggest-attribute=malloc',
- '-Wno-suggest-attribute=pure',
- '-Wno-switch-enum',
- '-Wno-unused-parameter',
- ],
- 'msvc': [
- '/wd4061', # enumerator in switch is not explicitly handled
- '/wd4100', # unreferenced formal parameter
- '/wd4244', # conversion with possible loss of data
- '/wd4267', # conversion from size_t to a smaller type
- '/wd4310', # cast truncates constant value
- '/wd4365', # signed/unsigned mismatch
- '/wd4464', # relative include path contains ".."
- '/wd4514', # unreferenced inline function has been removed
- '/wd4706', # assignment within conditional expression
- '/wd4710', # function not inlined
- '/wd4711', # function selected for automatic inline expansion
- '/wd4820', # padding added after construct
- '/wd5045', # will insert Spectre mitigation for memory load
- ]
- })
-
- autowaf.add_compiler_flags(conf.env, 'cxx', {
- 'gcc': [
- '-Wno-useless-cast',
- '-Wno-zero-as-null-pointer-constant',
- ],
- 'clang': [
- '-Wno-old-style-cast',
- '-Wno-zero-as-null-pointer-constant',
- ]
- })
-
- if 'mingw' in conf.env.CC[0]:
- autowaf.add_compiler_flags(conf.env, '*', {
- 'gcc': [
- '-Wno-format',
- '-Wno-suggest-attribute=format',
- ],
- })
-
- if conf.env.DEST_OS == 'win32' or not hasattr(os.path, 'relpath'):
- Logs.warn('System does not support linking headers, copying')
- Options.options.copy_headers = True
-
- conf.env.BUILD_TESTS = Options.options.build_tests
- conf.env.BUILD_PLUGINS = not Options.options.no_plugins
- conf.env.COPY_HEADERS = Options.options.copy_headers
- conf.env.ONLINE_DOCS = Options.options.online_docs
-
- if conf.env.DOCS or conf.env.ONLINE_DOCS:
- try:
- conf.find_program('asciidoc')
- conf.env.BUILD_BOOK = True
- except Exception:
- Logs.warn('Asciidoc not found, book will not be built')
-
- if not Options.options.no_check_links:
- if not conf.find_program('linkchecker',
- var='LINKCHECKER', mandatory=False):
- Logs.warn('Documentation will not be checked for broken links')
-
- # Check for gcov library (for test coverage)
- if (conf.env.BUILD_TESTS and
- not Options.options.no_coverage and
- not conf.is_defined('HAVE_GCOV')):
- conf.check_cc(lib='gcov', define_name='HAVE_GCOV', mandatory=False)
-
- if conf.env.BUILD_TESTS:
- conf.find_program('serdi', mandatory=False)
- conf.find_program('sord_validate', mandatory=False)
- conf.find_program('codespell', mandatory=False)
-
- autowaf.set_lib_env(conf, 'lv2', VERSION, has_objects=False)
- autowaf.set_local_lib(conf, 'lv2', has_objects=False)
-
- conf.run_env.append_unique('LV2_PATH',
- [os.path.join(conf.path.abspath(), 'lv2')])
-
- if conf.env.BUILD_PLUGINS:
- for i in ['eg-amp.lv2',
- 'eg-fifths.lv2',
- 'eg-metro.lv2',
- 'eg-midigate.lv2',
- 'eg-params.lv2',
- 'eg-sampler.lv2',
- 'eg-scope.lv2']:
- try:
- path = os.path.join('plugins', i)
- conf.recurse(path)
- conf.env.LV2_BUILD += [path]
- conf.run_env.append_unique(
- 'LV2_PATH', [conf.build_path('plugins/%s/lv2' % i)])
- except Exception as e:
- Logs.warn('Configuration of %s failed (%s)' % (i, e))
-
- autowaf.display_summary(
- conf,
- {'Bundle directory': conf.env.LV2DIR,
- 'Copy (not link) headers': bool(conf.env.COPY_HEADERS),
- 'Version': VERSION})
-
-
-def chop_lv2_prefix(s):
- if s.startswith('lv2/lv2plug.in/'):
- return s[len('lv2/lv2plug.in/'):]
- return s
-
-
-def subst_file(template, output, dict):
- i = open(template, 'r')
- o = open(output, 'w')
- for line in i:
- for key in dict:
- line = line.replace(key, dict[key])
- o.write(line)
- i.close()
- o.close()
-
-
-def specdirs(path):
- return (path.ant_glob('lv2/*', dir=True) +
- path.ant_glob('plugins/*.lv2', dir=True))
-
-
-def ttl_files(path, specdir):
- def abspath(node):
- return node.abspath()
-
- return map(abspath,
- path.ant_glob(specdir.path_from(path) + '/*.ttl'))
-
-
-def load_ttl(files, exclude = []):
- import rdflib
- model = rdflib.ConjunctiveGraph()
- for f in files:
- if f not in exclude:
- model.parse(f, format='n3')
- return model
-
-
-# Task to build extension index
-def build_index(task):
- src_dir = task.inputs[0].parent.parent
- sys.path.append(str(src_dir.find_node('lv2specgen')))
- import rdflib
-
- doap = rdflib.Namespace('http://usefulinc.com/ns/doap#')
-
- model = load_ttl([str(src_dir.find_node('lv2/core/meta.ttl')),
- str(src_dir.find_node('lv2/core/people.ttl'))])
-
- # Get date for this version, and list of all LV2 distributions
- proj = rdflib.URIRef('http://lv2plug.in/ns/lv2')
- date = None
- dists = []
- for r in model.triples([proj, doap.release, None]):
- revision = model.value(r[2], doap.revision, None)
- created = model.value(r[2], doap.created, None)
- if str(revision) == VERSION:
- date = created
-
- dist = model.value(r[2], doap['file-release'], None)
- if dist and created:
- dists += [(created, dist)]
- else:
- print('warning: %s has no file release\n' % proj)
-
- rows = []
- for f in task.inputs:
- if not f.abspath().endswith('index.html.in'):
- rowfile = open(f.abspath(), 'r')
- rows += rowfile.readlines()
- rowfile.close()
-
- if date is None:
- import datetime
- import time
- now = int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))
- date = datetime.datetime.utcfromtimestamp(now).strftime('%F')
-
- subst_file(task.inputs[0].abspath(), task.outputs[0].abspath(),
- {'@ROWS@': ''.join(rows),
- '@LV2_VERSION@': VERSION,
- '@DATE@': date})
-
-
-def build_spec(bld, path):
- name = os.path.basename(path)
- bundle_dir = os.path.join(bld.env.LV2DIR, name + '.lv2')
- include_dir = os.path.join(bld.env.INCLUDEDIR, path)
- old_include_dir = os.path.join(bld.env.INCLUDEDIR, spec_map[name])
-
- # Build test program if applicable
- for test in bld.path.ant_glob(os.path.join(path, '*-test.c')):
- test_lib = []
- test_cflags = ['']
- test_linkflags = ['']
- if bld.is_defined('HAVE_GCOV'):
- test_lib += ['gcov']
- test_cflags += ['--coverage']
- test_linkflags += ['--coverage']
- if bld.env.DEST_OS not in ['darwin', 'win32']:
- test_lib += ['rt']
-
- # Unit test program
- bld(features = 'c cprogram',
- source = test,
- lib = test_lib,
- uselib = 'LV2',
- target = os.path.splitext(str(test.get_bld()))[0],
- install_path = None,
- cflags = test_cflags,
- linkflags = test_linkflags)
-
- # Install bundle
- bld.install_files(bundle_dir,
- bld.path.ant_glob(path + '/?*.*', excl='*.in'))
-
- # Install URI-like includes
- headers = bld.path.ant_glob(path + '/*.h')
- if headers:
- for d in [include_dir, old_include_dir]:
- if bld.env.COPY_HEADERS:
- bld.install_files(d, headers)
- else:
- bld.symlink_as(d,
- os.path.relpath(bundle_dir, os.path.dirname(d)))
-
-
-def build(bld):
- specs = (bld.path.ant_glob('lv2/*', dir=True))
-
- # Copy lv2.h to include directory for backwards compatibility
- old_lv2_h_path = os.path.join(bld.env.INCLUDEDIR, 'lv2.h')
- if bld.env.COPY_HEADERS:
- bld.install_files(os.path.dirname(old_lv2_h_path), 'lv2/core/lv2.h')
- else:
- bld.symlink_as(old_lv2_h_path, 'lv2/core/lv2.h')
-
- # LV2 pkgconfig file
- bld(features = 'subst',
- source = 'lv2.pc.in',
- target = 'lv2.pc',
- install_path = '${LIBDIR}/pkgconfig',
- PREFIX = bld.env.PREFIX,
- INCLUDEDIR = bld.env.INCLUDEDIR,
- VERSION = VERSION)
-
- # Validator
- bld(features = 'subst',
- source = 'util/lv2_validate.in',
- target = 'lv2_validate',
- chmod = Utils.O755,
- install_path = '${BINDIR}',
- LV2DIR = bld.env.LV2DIR)
-
- # Build extensions
- for spec in specs:
- build_spec(bld, spec.path_from(bld.path))
-
- # Build plugins
- for plugin in bld.env.LV2_BUILD:
- bld.recurse(plugin)
-
- # Install lv2specgen
- bld.install_files('${DATADIR}/lv2specgen/',
- ['lv2specgen/style.css',
- 'lv2specgen/template.html'])
- bld.install_files('${DATADIR}/lv2specgen/DTD/',
- bld.path.ant_glob('lv2specgen/DTD/*'))
- bld.install_files('${BINDIR}', 'lv2specgen/lv2specgen.py',
- chmod=Utils.O755)
-
- # Install schema bundle
- bld.install_files('${LV2DIR}/schemas.lv2/',
- bld.path.ant_glob('schemas.lv2/*.ttl'))
-
- if bld.env.ONLINE_DOCS:
- # Generate .htaccess files
- for d in ('ns', 'ns/ext', 'ns/extensions'):
- path = os.path.join(str(bld.path.get_bld()), d)
- bld(features = 'subst',
- source = 'doc/htaccess.in',
- target = os.path.join(path, '.htaccess'),
- install_path = None,
- BASE = '/' + d)
-
- if bld.env.DOCS or bld.env.ONLINE_DOCS:
- # Copy spec files to build dir
- for spec in specs:
- srcpath = spec.path_from(bld.path)
- basename = os.path.basename(srcpath)
- full_path = spec_map[basename]
- name = 'lv2core' if basename == 'core' else basename
- path = chop_lv2_prefix(full_path)
-
- bld(features = 'subst',
- is_copy = True,
- source = os.path.join(srcpath, name + '.ttl'),
- target = path + '.ttl')
-
- # Copy stylesheets to build directory
- for i in ['style.css', 'pygments.css']:
- bld(features = 'subst',
- is_copy = True,
- name = 'copy',
- source = 'doc/%s' % i,
- target = 'aux/%s' % i)
-
- # Build Doxygen documentation (and tags file)
- autowaf.build_dox(bld, 'LV2', VERSION, top, out, 'doc', False)
- bld.add_group()
-
- index_files = []
- for spec in specs:
- # Call lv2specgen to generate spec docs
- srcpath = spec.path_from(bld.path)
- basename = os.path.basename(srcpath)
- full_path = spec_map[basename]
- name = 'lv2core' if basename == 'core' else basename
- ttl_name = name + '.ttl'
- index_file = bld.path.get_bld().make_node('index_rows/' + name)
- index_files += [index_file]
- chopped_path = chop_lv2_prefix(full_path)
-
- assert chopped_path.startswith('ns/')
- root_path = os.path.relpath('/', os.path.dirname(chopped_path[2:]))
- html_path = '%s.html' % chopped_path
- out_dir = os.path.dirname(html_path)
- style_uri = os.path.relpath('aux/style.css', out_dir)
-
- cmd = (str(bld.path.find_node('lv2specgen/lv2specgen.py')) +
- ' --root-uri=http://lv2plug.in/ns/'
- ' --root-path=' + root_path +
- ' --list-email=' + list_email +
- ' --list-page=' + list_page +
- ' --style-uri=' + style_uri +
- ' --docdir=' + os.path.relpath('doc/html', out_dir) +
- ' --tags=%s' % bld.path.get_bld().make_node('doc/tags') +
- ' --index=' + str(index_file) +
- (' --online' if bld.env.ONLINE_DOCS else '') +
- ' ${SRC} ${TGT}')
-
- bld(rule = cmd,
- source = os.path.join(srcpath, ttl_name),
- target = [html_path, index_file],
- shell = False)
-
- # Install documentation
- bld.install_files(
- os.path.join('${DOCDIR}', 'lv2', os.path.dirname(html_path)),
- html_path)
-
- index_files.sort(key=lambda x: x.path_from(bld.path))
- bld.add_group()
-
- # Build extension index
- bld(rule = build_index,
- name = 'index',
- source = ['doc/index.html.in'] + index_files,
- target = 'ns/index.html')
-
- # Install main documentation files
- bld.install_files('${DOCDIR}/lv2/aux/', 'aux/style.css')
- bld.install_files('${DOCDIR}/lv2/ns/', 'ns/index.html')
-
- def check_links(ctx):
- import subprocess
- if ctx.env.LINKCHECKER:
- if subprocess.call([ctx.env.LINKCHECKER[0],
- '--no-status', out]):
- ctx.fatal('Documentation contains broken links')
-
- if bld.cmd == 'build':
- bld.add_post_fun(check_links)
-
- if bld.env.BUILD_TESTS:
- # Generate a compile test file that includes all headers
- def gen_build_test(task):
- with open(task.outputs[0].abspath(), 'w') as out:
- for i in task.inputs:
- out.write('#include "%s"\n' % i.bldpath())
- out.write('int main(void) { return 0; }\n')
-
- bld(rule = gen_build_test,
- source = bld.path.ant_glob('lv2/**/*.h'),
- target = 'build-test.c',
- install_path = None)
-
- bld(features = 'c cprogram',
- source = bld.path.get_bld().make_node('build-test.c'),
- target = 'build-test',
- includes = '.',
- uselib = 'LV2',
- install_path = None)
-
- if 'COMPILER_CXX' in bld.env:
- bld(rule = gen_build_test,
- source = bld.path.ant_glob('lv2/**/*.h'),
- target = 'build-test.cpp',
- install_path = None)
-
- bld(features = 'cxx cxxprogram',
- source = bld.path.get_bld().make_node('build-test.cpp'),
- target = 'build-test-cpp',
- includes = '.',
- uselib = 'LV2',
- install_path = None)
-
- if bld.env.BUILD_BOOK:
- # Build "Programming LV2 Plugins" book from plugin examples
- bld.recurse('plugins')
-
-
-class LintContext(Build.BuildContext):
- fun = cmd = 'lint'
-
-
-def lint(ctx):
- "checks code for style issues"
- import subprocess
- import glob
-
- st = 0
-
- if "FLAKE8" in ctx.env:
- Logs.info("Running flake8")
- st = subprocess.call([ctx.env.FLAKE8[0],
- "wscript",
- "--ignore",
- "E101,E129,W191,E221,W504,E251,E241,E741"])
- else:
- Logs.warn("Not running flake8")
-
- if "IWYU_TOOL" in ctx.env:
- Logs.info("Running include-what-you-use")
- cmd = [ctx.env.IWYU_TOOL[0], "-o", "clang", "-p", "build"]
- output = subprocess.check_output(cmd).decode('utf-8')
- if 'error: ' in output:
- sys.stdout.write(output)
- st += 1
- else:
- Logs.warn("Not running include-what-you-use")
-
- if "CLANG_TIDY" in ctx.env and "clang" in ctx.env.CC[0]:
- Logs.info("Running clang-tidy")
- sources = glob.glob('**/*.h', recursive=True)
- sources = list(map(os.path.abspath, sources))
- procs = []
- for source in sources:
- cmd = [ctx.env.CLANG_TIDY[0], "--quiet", "-p=.", source]
- procs += [subprocess.Popen(cmd, cwd="build")]
-
- for proc in procs:
- stdout, stderr = proc.communicate()
- st += proc.returncode
- else:
- Logs.warn("Not running clang-tidy")
-
- if st != 0:
- sys.exit(st)
-
-
-def test_vocabularies(check, specs, files):
- import rdflib
-
- foaf = rdflib.Namespace('http://xmlns.com/foaf/0.1/')
- lv2 = rdflib.Namespace('http://lv2plug.in/ns/lv2core#')
- owl = rdflib.Namespace('http://www.w3.org/2002/07/owl#')
- rdf = rdflib.Namespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#')
- rdfs = rdflib.Namespace('http://www.w3.org/2000/01/rdf-schema#')
-
- # Check if this is a stable LV2 release to enable additional tests
- version_tuple = tuple(map(int, VERSION.split(".")))
- is_stable = version_tuple[1] % 2 == 0 and version_tuple[2] % 2 == 0
-
- # Check that extended documentation is not in main specification file
- for spec in specs:
- path = str(spec.abspath())
- name = os.path.basename(path)
- name = 'lv2core' if name == 'core' else name
- vocab = os.path.join(path, name + '.ttl')
-
- spec_model = rdflib.ConjunctiveGraph()
- spec_model.parse(vocab, format='n3')
-
- def has_statement(s, p, o):
- for t in spec_model.triples([s, p, o]):
- return True
-
- return False
-
- check(lambda: not has_statement(None, lv2.documentation, None),
- name = name + ".ttl does not contain lv2:documentation")
-
- # Check specification manifests
- for spec in specs:
- path = str(spec.abspath())
- manifest_path = os.path.join(path, 'manifest.ttl')
- manifest_model = rdflib.ConjunctiveGraph()
- manifest_model.parse(manifest_path, format='n3')
-
- uri = manifest_model.value(None, rdf.type, lv2.Specification)
- minor = manifest_model.value(uri, lv2.minorVersion, None)
- micro = manifest_model.value(uri, lv2.microVersion, None)
- check(lambda: uri is not None,
- name = manifest_path + " has a lv2:Specification")
- check(lambda: minor is not None,
- name = manifest_path + " has a lv2:minorVersion")
- check(lambda: micro is not None,
- name = manifest_path + " has a lv2:microVersion")
-
- if is_stable:
- check(lambda: int(minor) > 0,
- name = manifest_path + " has even non-zero minor version")
- check(lambda: int(micro) % 2 == 0,
- name = manifest_path + " has even micro version")
-
- # Load everything into one big model
- model = rdflib.ConjunctiveGraph()
- for f in files:
- model.parse(f, format='n3')
-
- # Check that all named and typed resources have labels and comments
- for r in sorted(model.triples([None, rdf.type, None])):
- subject = r[0]
- if (type(subject) == rdflib.term.BNode or
- foaf.Person in model.objects(subject, rdf.type)):
- continue
-
- def has_property(subject, prop):
- return model.value(subject, prop, None) is not None
-
- check(lambda: has_property(subject, rdfs.label),
- name = '%s has rdfs:label' % subject)
-
- if check(lambda: has_property(subject, rdfs.comment),
- name = '%s has rdfs:comment' % subject):
- comment = str(model.value(subject, rdfs.comment, None))
-
- check(lambda: comment.endswith('.'),
- name = "%s comment ends in '.'" % subject)
- check(lambda: comment.find('\n') == -1,
- name = "%s comment contains no newlines" % subject)
- check(lambda: comment == comment.strip(),
- name = "%s comment has stripped whitespace" % subject)
-
- # Check that lv2:documentation, if present, is proper Markdown
- documentation = model.value(subject, lv2.documentation, None)
- if documentation is not None:
- check(lambda: documentation.datatype == lv2.Markdown,
- name = "%s documentation is explicitly Markdown" % subject)
- check(lambda: str(documentation).startswith('\n\n'),
- name = "%s documentation starts with blank line" % subject)
- check(lambda: str(documentation).endswith('\n\n'),
- name = "%s documentation ends with blank line" % subject)
-
- # Check that all properties are either datatype or object properties
- for r in sorted(model.triples([None, rdf.type, rdf.Property])):
- subject = r[0]
- if str(subject) == 'http://lv2plug.in/ns/ext/patch#value':
- continue # patch:value is just a "promiscuous" rdf:Property
-
- types = list(model.objects(subject, rdf.type))
-
- check(lambda: ((owl.DatatypeProperty in types) or
- (owl.ObjectProperty in types) or
- (owl.AnnotationProperty in types)),
- name = "%s is a Datatype/Object/Annotation property" % subject)
-
-
-def test(tst):
- import tempfile
-
- with tst.group("Data") as check:
- specs = (tst.path.ant_glob('lv2/*', dir=True))
- schemas = list(map(str, tst.path.ant_glob("schemas.lv2/*.ttl")))
- spec_files = list(map(str, tst.path.ant_glob("lv2/**/*.ttl")))
- plugin_files = list(map(str, tst.path.ant_glob("plugins/**/*.ttl")))
- bld_files = list(map(str, tst.path.get_bld().ant_glob("**/*.ttl")))
-
- if "SERDI" in tst.env and sys.platform != 'win32':
- for f in spec_files:
- with tempfile.NamedTemporaryFile(mode="w") as tmp:
- base_dir = os.path.dirname(f)
- cmd = tst.env.SERDI + ["-o", "turtle", f, base_dir]
- check(cmd, stdout=tmp.name)
- check.file_equals(f, tmp.name)
-
- if "SORD_VALIDATE" in tst.env:
- all_files = schemas + spec_files + plugin_files + bld_files
- check(tst.env.SORD_VALIDATE + all_files)
-
- if "CODESPELL" in tst.env:
- spell_ignore = [
- "doc/pygments.css",
- "lv2specgen/DTD/*",
- "schemas.lv2/doap.ttl",
- "waflib",
- ]
-
- spell_ignore_paths = [os.path.join(tst.src_path("."), x)
- for x in spell_ignore]
-
- check(tst.env.CODESPELL + [
- "-d",
- "-q", "3",
- "-S", ','.join(spell_ignore_paths),
- tst.src_path("."),
- ])
-
- try:
- test_vocabularies(check, specs, spec_files)
- except ImportError as e:
- Logs.warn('Not running vocabulary tests (%s)' % e)
-
- with tst.group('Unit') as check:
- pattern = tst.env.cprogram_PATTERN % '**/*-test'
- for test in tst.path.get_bld().ant_glob(pattern):
- check([str(test)])
-
-
-class Dist(Scripting.Dist):
- def execute(self):
- 'Execute but do not call archive() since dist() has already done so.'
- self.recurse([os.path.dirname(Context.g_module.root_path)])
-
- def get_tar_path(self, node):
- 'Resolve symbolic links to avoid broken links in tarball.'
- return os.path.realpath(node.abspath())
-
-
-class DistCheck(Dist, Scripting.DistCheck):
- def execute(self):
- Dist.execute(self)
- self.check()
-
- def archive(self):
- Dist.archive(self)
-
-
-def _get_news_entries(ctx):
- from waflib.extras import autoship
-
- # Get project-level news entries
- lv2_entries = autoship.read_ttl_news('lv2',
- ['lv2/core/meta.ttl',
- 'lv2/core/people.ttl'],
- dist_pattern = dist_pattern)
-
- release_pattern = r'http://lv2plug.in/spec/lv2-([0-9\.]*).tar.bz2'
- current_version = sorted(lv2_entries.keys(), reverse=True)[0]
-
- # Add items from every specification
- for specdir in specdirs(ctx.path):
- name = os.path.basename(specdir.abspath())
- files = list(ttl_files(ctx.path, specdir))
- if name == "core":
- files = [f for f in files if (not f.endswith('/meta.ttl') and
- not f.endswith('/people.ttl') and
- not f.endswith('/manifest.ttl'))]
-
- entries = autoship.read_ttl_news(name, files)
-
- def add_items(lv2_version, name, items):
- for item in items:
- lv2_entries[lv2_version]["items"] += ["%s: %s" % (name, item)]
-
- if entries:
- latest_revision = sorted(entries.keys(), reverse=True)[0]
- for revision, entry in entries.items():
- if "dist" in entry:
- match = re.match(release_pattern, entry["dist"])
- if match:
- # Append news items to corresponding LV2 version
- version = tuple(map(int, match.group(1).split('.')))
- add_items(version, name, entry["items"])
-
- elif revision == latest_revision:
- # Not-yet-released development version, append to current
- add_items(current_version, name, entry["items"])
-
- # Sort news items in each versions
- for revision, entry in lv2_entries.items():
- entry["items"].sort()
-
- return lv2_entries
-
-
-def posts(ctx):
- "generates news posts in Pelican Markdown format"
-
- from waflib.extras import autoship
-
- try:
- os.mkdir(os.path.join(out, 'posts'))
- except Exception:
- pass
-
- autoship.write_posts(_get_news_entries(ctx),
- os.path.join(out, 'posts'),
- {'Author': 'drobilla'})
-
-
-def news(ctx):
- """write an amalgamated NEWS file to the source directory"""
-
- from waflib.extras import autoship
-
- autoship.write_news(_get_news_entries(ctx), 'NEWS')
-
-
-def dist(ctx):
- news(ctx)
- ctx.archive()
-
-
-def distcheck(ctx):
- news(ctx)
- ctx.archive()