summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/pages/host-compatibility.md55
-rw-r--r--content/pages/index.md1
-rw-r--r--host_compatibility.ttl154
-rwxr-xr-xscripts/update_host_compatibility.py262
-rw-r--r--themes/lv2/static/css/main.css29
5 files changed, 501 insertions, 0 deletions
diff --git a/content/pages/host-compatibility.md b/content/pages/host-compatibility.md
new file mode 100644
index 0000000..e6feef1
--- /dev/null
+++ b/content/pages/host-compatibility.md
@@ -0,0 +1,55 @@
+Title: Host Compatibility
+
+This page shows the state of host support for different parts of LV2.
+It is generated from
+[data](//gitlab.com/lv2/site/-/blob/master/host_compatibility.ttl)
+in the [LV2 site repository](//gitlab.com/lv2/site),
+additions and corrections are welcome.
+<h2>Features</h2>
+<table><tr><th>Feature</th><th>Jalv</th><th>Ardour</th><th>Carla</th></tr>
+<tr><td><a href="http://lv2plug.in/ns/ext/buf-size#boundedBlockLength">http://lv2plug.in/ns/ext/buf-size#boundedBlockLength</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/ext/buf-size#coarseBlockLength">http://lv2plug.in/ns/ext/buf-size#coarseBlockLength</a></td><td><span class="error">No</span></td><td><span class="success">Yes</span></td><td><span class="error">No</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/ext/buf-size#fixedBlockLength">http://lv2plug.in/ns/ext/buf-size#fixedBlockLength</a></td><td><span class="success">Yes</span></td><td><span class="error">No</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/ext/buf-size#powerOf2BlockLength">http://lv2plug.in/ns/ext/buf-size#powerOf2BlockLength</a></td><td><span class="success">Yes</span></td><td><span class="error">No</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/ext/data-access">http://lv2plug.in/ns/ext/data-access</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/ext/instance-access">http://lv2plug.in/ns/ext/instance-access</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/ext/log#log">http://lv2plug.in/ns/ext/log#log</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/ext/options#options">http://lv2plug.in/ns/ext/options#options</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/ext/port-props#supportsStrictBounds">http://lv2plug.in/ns/ext/port-props#supportsStrictBounds</a></td><td><span class="error">No</span></td><td><span class="error">No</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/ext/resize-port#resize">http://lv2plug.in/ns/ext/resize-port#resize</a></td><td><span class="error">No</span></td><td><span class="error">No</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/ext/state#freePath">http://lv2plug.in/ns/ext/state#freePath</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/ext/state#loadDefaultState">http://lv2plug.in/ns/ext/state#loadDefaultState</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/ext/state#makePath">http://lv2plug.in/ns/ext/state#makePath</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/ext/state#mapPath">http://lv2plug.in/ns/ext/state#mapPath</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/ext/state#threadSafeRestore">http://lv2plug.in/ns/ext/state#threadSafeRestore</a></td><td><span class="error">No</span></td><td><span class="error">No</span></td><td><span class="error">No</span></td></tr>
+<tr><td><strike><a href="http://lv2plug.in/ns/ext/uri-map">http://lv2plug.in/ns/ext/uri-map</a></strike></td><td><span class="error">No</span></td><td><span class="error">No</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/ext/urid#map">http://lv2plug.in/ns/ext/urid#map</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/ext/urid#unmap">http://lv2plug.in/ns/ext/urid#unmap</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/ext/worker#schedule">http://lv2plug.in/ns/ext/worker#schedule</a></td><td><span class="error">No</span></td><td><span class="error">No</span></td><td><span class="error">No</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/extensions/ui#fixedSize">http://lv2plug.in/ns/extensions/ui#fixedSize</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/extensions/ui#idleInterface">http://lv2plug.in/ns/extensions/ui#idleInterface</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><strike><a href="http://lv2plug.in/ns/extensions/ui#makeSONameResident">http://lv2plug.in/ns/extensions/ui#makeSONameResident</a></strike></td><td><span class="error">No</span></td><td><span class="error">No</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/extensions/ui#noUserResize">http://lv2plug.in/ns/extensions/ui#noUserResize</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/extensions/ui#parent">http://lv2plug.in/ns/extensions/ui#parent</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/extensions/ui#portMap">http://lv2plug.in/ns/extensions/ui#portMap</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/extensions/ui#portSubscribe">http://lv2plug.in/ns/extensions/ui#portSubscribe</a></td><td><span class="error">No</span></td><td><span class="error">No</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/extensions/ui#requestValue">http://lv2plug.in/ns/extensions/ui#requestValue</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><strike><a href="http://lv2plug.in/ns/extensions/ui#resize">http://lv2plug.in/ns/extensions/ui#resize</a></strike></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/extensions/ui#touch">http://lv2plug.in/ns/extensions/ui#touch</a></td><td><span class="error">No</span></td><td><span class="error">No</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/lv2core#hardRTCapable">http://lv2plug.in/ns/lv2core#hardRTCapable</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/lv2core#inPlaceBroken">http://lv2plug.in/ns/lv2core#inPlaceBroken</a></td><td><span class="success">Yes</span></td><td><span class="error">No</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/lv2core#isLive">http://lv2plug.in/ns/lv2core#isLive</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+</table>
+<h2>Port Types</h2>
+<table><tr><th>Port Type</th><th>Jalv</th><th>Ardour</th><th>Carla</th></tr>
+<tr><td><a href="http://lv2plug.in/ns/ext/atom#AtomPort">http://lv2plug.in/ns/ext/atom#AtomPort</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/ext/event#EventPort">http://lv2plug.in/ns/ext/event#EventPort</a></td><td><span class="error">No</span></td><td><span class="error">No</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/ext/morph#AutoMorphPort">http://lv2plug.in/ns/ext/morph#AutoMorphPort</a></td><td><span class="error">No</span></td><td><span class="error">No</span></td><td><span class="error">No</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/ext/morph#MorphPort">http://lv2plug.in/ns/ext/morph#MorphPort</a></td><td><span class="error">No</span></td><td><span class="error">No</span></td><td><span class="error">No</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/lv2core#AudioPort">http://lv2plug.in/ns/lv2core#AudioPort</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/lv2core#CVPort">http://lv2plug.in/ns/lv2core#CVPort</a></td><td><span class="success">Yes</span></td><td><span class="error">No</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/lv2core#ControlPort">http://lv2plug.in/ns/lv2core#ControlPort</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/lv2core#InputPort">http://lv2plug.in/ns/lv2core#InputPort</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+<tr><td><a href="http://lv2plug.in/ns/lv2core#OutputPort">http://lv2plug.in/ns/lv2core#OutputPort</a></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td><td><span class="success">Yes</span></td></tr>
+</table>
+<footer>Generated by <code>update_host_compatibility.py</code> with LV2 1.18.6.</footer>
diff --git a/content/pages/index.md b/content/pages/index.md
index edddded..8dc5ca8 100644
--- a/content/pages/index.md
+++ b/content/pages/index.md
@@ -24,6 +24,7 @@ Documentation
* [Why LV2?](pages/why-lv2.html)
* [Developing with LV2](pages/developing.html)
* [LV2 Specifications](//lv2plug.in/ns/)
+* [Host Compatibility](pages/host-compatibility.html)
* [News](/news.html)
Community
diff --git a/host_compatibility.ttl b/host_compatibility.ttl
new file mode 100644
index 0000000..a76e6e0
--- /dev/null
+++ b/host_compatibility.ttl
@@ -0,0 +1,154 @@
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix compat: <http://drobilla.net/ns/compat#> .
+
+compat:Host
+ a rdfs:Class ;
+ rdfs:label "Host" ;
+ rdfs:subClassOf doap:Project .
+
+compat:Library
+ a rdfs:Class ;
+ rdfs:label "Library" .
+
+compat:implementsFeature
+ a rdf:Property ;
+ rdfs:label "implements feature" ;
+ rdfs:range lv2:Feature .
+
+compat:supportsPortType
+ a rdf:Property ;
+ rdfs:label "implements feature" ;
+ rdfs:range lv2:Port .
+
+compat:usesLibrary
+ a rdf:Property ;
+ rdfs:label "uses library" ;
+ rdfs:range compat:Library .
+
+compat:version
+ a rdf:Property ;
+ rdfs:label "version" ;
+ rdfs:range rdf:PlainLiteral .
+
+<http://drobilla.net/software/jalv>
+ a compat:Host ;
+ rdfs:label "Jalv" ;
+ compat:version "1.6.6" ;
+ compat:implementsFeature <http://lv2plug.in/ns/ext/buf-size#boundedBlockLength> ,
+ <http://lv2plug.in/ns/ext/buf-size#fixedBlockLength> ,
+ <http://lv2plug.in/ns/ext/buf-size#powerOf2BlockLength> ,
+ <http://lv2plug.in/ns/ext/data-access> ,
+ <http://lv2plug.in/ns/ext/instance-access> ,
+ <http://lv2plug.in/ns/ext/log#log> ,
+ <http://lv2plug.in/ns/ext/options#options> ,
+ <http://lv2plug.in/ns/ext/state#loadDefaultState> ,
+ <http://lv2plug.in/ns/ext/urid#map> ,
+ <http://lv2plug.in/ns/ext/urid#unmap> ,
+ <http://lv2plug.in/ns/extensions/ui#fixedSize> ,
+ <http://lv2plug.in/ns/extensions/ui#idleInterface> ,
+ <http://lv2plug.in/ns/extensions/ui#noUserResize> ,
+ <http://lv2plug.in/ns/extensions/ui#parent> ,
+ <http://lv2plug.in/ns/extensions/ui#portMap> ,
+ <http://lv2plug.in/ns/extensions/ui#requestValue> ,
+ <http://lv2plug.in/ns/extensions/ui#resize> ,
+ lv2:hardRTCapable ,
+ lv2:inPlaceBroken ,
+ lv2:isLive ;
+ compat:supportsPortType <http://lv2plug.in/ns/ext/atom#AtomPort> ,
+ lv2:AudioPort ,
+ lv2:CVPort ,
+ lv2:ControlPort ,
+ lv2:InputPort ,
+ lv2:OutputPort ;
+ compat:usesLibrary <http://drobilla.net/software/lilv> ,
+ <http://drobilla.net/software/suil> .
+
+<http://drobilla.net/software/lilv>
+ a compat:Library ;
+ rdfs:label "Lilv" ;
+ compat:implementsFeature <http://lv2plug.in/ns/ext/state#freePath> ,
+ <http://lv2plug.in/ns/ext/state#makePath> ,
+ <http://lv2plug.in/ns/ext/state#mapPath> .
+
+<http://drobilla.net/software/suil>
+ a compat:Library ;
+ rdfs:label "Suil" ;
+ compat:implementsFeature <http://lv2plug.in/ns/extensions/ui#idleInterface> ,
+ <http://lv2plug.in/ns/extensions/ui#parent> ,
+ <http://lv2plug.in/ns/extensions/ui#resize> .
+
+_:ardour
+ a compat:Host ;
+ rdfs:label "Ardour" ;
+ compat:version "1.6.6" ;
+ compat:implementsFeature <http://lv2plug.in/ns/ext/buf-size#boundedBlockLength> ,
+ <http://lv2plug.in/ns/ext/buf-size#coarseBlockLength> ,
+ <http://lv2plug.in/ns/ext/data-access> ,
+ <http://lv2plug.in/ns/ext/instance-access> ,
+ <http://lv2plug.in/ns/ext/log#log> ,
+ <http://lv2plug.in/ns/ext/options#options> ,
+ <http://lv2plug.in/ns/ext/state#loadDefaultState> ,
+ <http://lv2plug.in/ns/ext/urid#map> ,
+ <http://lv2plug.in/ns/ext/urid#unmap> ,
+ <http://lv2plug.in/ns/extensions/ui#fixedSize> ,
+ <http://lv2plug.in/ns/extensions/ui#idleInterface> ,
+ <http://lv2plug.in/ns/extensions/ui#noUserResize> ,
+ <http://lv2plug.in/ns/extensions/ui#parent> ,
+ <http://lv2plug.in/ns/extensions/ui#portMap> ,
+ <http://lv2plug.in/ns/extensions/ui#requestValue> ,
+ <http://lv2plug.in/ns/extensions/ui#resize> ,
+ lv2:hardRTCapable ,
+ lv2:isLive ;
+ compat:supportsPortType <http://lv2plug.in/ns/ext/atom#AtomPort> ,
+ lv2:AudioPort ,
+ lv2:ControlPort ,
+ lv2:InputPort ,
+ lv2:OutputPort ;
+ compat:usesLibrary <http://drobilla.net/software/lilv> ,
+ <http://drobilla.net/software/suil> .
+
+_:carla
+ a compat:Host ;
+ rdfs:label "Carla" ;
+ compat:version "2.4.3" ;
+ compat:implementsFeature <http://lv2plug.in/ns/ext/buf-size#boundedBlockLength> ,
+ <http://lv2plug.in/ns/ext/buf-size#fixedBlockLength> ,
+ <http://lv2plug.in/ns/ext/buf-size#powerOf2BlockLength> ,
+ <http://lv2plug.in/ns/ext/data-access> ,
+ <http://lv2plug.in/ns/ext/instance-access> ,
+ <http://lv2plug.in/ns/ext/log#log> ,
+ <http://lv2plug.in/ns/ext/options#options> ,
+ <http://lv2plug.in/ns/ext/port-props#supportsStrictBounds> ,
+ <http://lv2plug.in/ns/ext/resize-port#resize> ,
+ <http://lv2plug.in/ns/ext/state#freePath> ,
+ <http://lv2plug.in/ns/ext/state#loadDefaultState> ,
+ <http://lv2plug.in/ns/ext/state#makePath> ,
+ <http://lv2plug.in/ns/ext/state#mapPath> ,
+ <http://lv2plug.in/ns/ext/urid#map> ,
+ <http://lv2plug.in/ns/ext/urid#unmap> ,
+ <http://lv2plug.in/ns/extensions/ui#fixedSize> ,
+ <http://lv2plug.in/ns/extensions/ui#fixedSize> ,
+ <http://lv2plug.in/ns/extensions/ui#idleInterface> ,
+ <http://lv2plug.in/ns/extensions/ui#makeSONameResident> ,
+ <http://lv2plug.in/ns/extensions/ui#noUserResize> ,
+ <http://lv2plug.in/ns/extensions/ui#parent> ,
+ <http://lv2plug.in/ns/extensions/ui#portMap> ,
+ <http://lv2plug.in/ns/extensions/ui#portSubscribe> ,
+ <http://lv2plug.in/ns/extensions/ui#requestValue> ,
+ <http://lv2plug.in/ns/extensions/ui#resize> ,
+ <http://lv2plug.in/ns/extensions/ui#touch> ,
+ <http://lv2plug.in/ns/ext/uri-map> ,
+ lv2:hardRTCapable ,
+ lv2:inPlaceBroken ,
+ lv2:isLive ;
+ compat:supportsPortType <http://lv2plug.in/ns/ext/atom#AtomPort> ,
+ <http://lv2plug.in/ns/ext/event#EventPort> ,
+ lv2:AudioPort ,
+ lv2:CVPort ,
+ lv2:ControlPort ,
+ lv2:InputPort ,
+ lv2:OutputPort .
+
diff --git a/scripts/update_host_compatibility.py b/scripts/update_host_compatibility.py
new file mode 100755
index 0000000..84898b0
--- /dev/null
+++ b/scripts/update_host_compatibility.py
@@ -0,0 +1,262 @@
+#!/usr/bin/env python3
+
+"""
+Write an LV2 host compatibility matrix as a Pelican page.
+"""
+
+import argparse
+import os
+import subprocess
+import sys
+
+import rdflib
+
+__author__ = "David Robillard"
+__date__ = "2022-08-15"
+__email__ = "d@drobilla.net"
+__license__ = "ISC"
+__version__ = "0.0.1"
+
+DOC_HEADER = """Title: Host Compatibility
+
+This page shows the state of host support for different parts of LV2.
+It is generated from
+[data](//gitlab.com/lv2/site/-/blob/master/host_compatibility.ttl)
+in the [LV2 site repository](//gitlab.com/lv2/site),
+additions and corrections are welcome.
+"""
+
+compat = rdflib.Namespace("http://drobilla.net/ns/compat#")
+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 TableContext:
+ """Context manager for writing an HTML table."""
+
+ def __init__(self, out):
+ self.out = out
+
+ def __enter__(self):
+ self.out.write("<table>")
+ return self
+
+ def __exit__(self, exc_type, exc_value, exc_traceback):
+ self.out.write("</table>\n")
+
+
+class RowContext:
+ """Context manager for writing a row within an HTML table."""
+
+ def __init__(self, out):
+ self.out = out
+
+ def __enter__(self):
+ self.out.write("<tr>")
+ return self
+
+ def __exit__(self, exc_type, exc_value, exc_traceback):
+ self.out.write("</tr>\n")
+
+ def append(self, col, tag="td"):
+ """Append a column to the row."""
+
+ self.out.write(f"<{tag}>")
+ self.out.write(col)
+ self.out.write(f"</{tag}>")
+
+
+def _default_lv2_path():
+ """Return the default LV2_PATH for the current platform."""
+
+ if sys.platform == "darwin":
+ return os.pathsep.join(
+ [
+ "~/.lv2",
+ "~/Library/Audio/Plug-Ins/LV2",
+ "/usr/local/lib/lv2",
+ "/usr/lib/lv2",
+ "/Library/Audio/Plug-Ins/LV2",
+ ]
+ )
+
+ if sys.platform == "win32":
+ return os.pathsep.join(
+ ["%APPDATA%\\\\LV2", "%COMMONPROGRAMFILES%\\\\LV2"]
+ )
+
+ return os.pathsep.join(["~/.lv2", "/usr/local/lib/lv2", "/usr/lib/lv2"])
+
+
+def _load_specifications(graph, lv2_path):
+ """Load all LV2 specifications from an LV2 path."""
+
+ specs = set()
+
+ for path_entry in lv2_path.split(os.pathsep):
+ directory = os.path.expanduser(os.path.expandvars(path_entry))
+
+ for name in os.listdir(directory):
+ path = os.path.join(directory, name)
+ manifest_path = os.path.join(path, "manifest.ttl")
+ if not os.path.isfile(manifest_path):
+ continue
+
+ manifest = rdflib.Graph()
+ manifest.load(manifest_path, format="turtle")
+
+ for spec in manifest.subjects(rdf.type, lv2.Specification):
+ document = manifest.value(spec, rdfs.seeAlso, any=False)
+ if spec not in specs:
+ specs.add(spec)
+ sys.stderr.write(f"Loading {document}\n")
+ graph.load(document, format="turtle")
+ else:
+ sys.stderr.write(f"warning: Ignoring {document}\n")
+
+
+def _host_implements_feature(graph, host, feature):
+ """Return whether host implements feature, directly or indirectly."""
+
+ if (host, compat.implementsFeature, feature) in graph:
+ return True
+
+ for library in graph.objects(host, compat.usesLibrary):
+ if (library, compat.implementsFeature, feature) in graph:
+ return True
+
+ return False
+
+
+def _spec_link(uri):
+ return f'<a href="{uri}">{uri}</a>'
+
+
+def run(lv2_path, data_filenames, out):
+ """Read compatibility data and generate HTML compatibility tables."""
+
+ graph = rdflib.Graph()
+
+ _load_specifications(graph, lv2_path)
+
+ for data_filename in data_filenames:
+ graph.load(data_filename, format="turtle")
+
+ hosts = list(graph.subjects(rdf.type, compat.Host))
+ features = sorted(list(graph.subjects(rdf.type, lv2.Feature)))
+ port_types = sorted(list(graph.subjects(rdfs.subClassOf, lv2.Port)))
+
+ out.write(DOC_HEADER)
+
+ out.write("<h2>Features</h2>\n")
+ with TableContext(out):
+ with RowContext(out) as row:
+ row.append("Feature", tag="th")
+ for host in hosts:
+ row.append(graph.value(host, rdfs.label), tag="th")
+
+ for feature in features:
+ with RowContext(out) as row:
+ if graph.value(feature, owl.deprecated):
+ row.append(f"<strike>{_spec_link(feature)}</strike>")
+ else:
+ row.append(_spec_link(feature))
+
+ for host in graph.subjects(rdf.type, compat.Host):
+ if _host_implements_feature(graph, host, feature):
+ row.append('<span class="success">Yes</span>')
+ else:
+ row.append('<span class="error">No</span>')
+
+ out.write("<h2>Port Types</h2>\n")
+ with TableContext(out):
+ with RowContext(out) as row:
+ row.append("Port Type", tag="th")
+ for host in hosts:
+ row.append(graph.value(host, rdfs.label), tag="th")
+
+ for port_type in port_types:
+ with RowContext(out) as row:
+ row.append(_spec_link(port_type))
+ for host in graph.subjects(rdf.type, compat.Host):
+ if (host, compat.supportsPortType, port_type) in graph:
+ row.append('<span class="success">Yes</span>')
+ else:
+ row.append('<span class="error">No</span>')
+
+ script_name = os.path.basename(sys.argv[0])
+ version_cmd = ["pkg-config", "--modversion", "lv2"]
+ version = subprocess.check_output(version_cmd, encoding="utf-8").strip()
+ out.write(
+ f"<footer>Generated by <code>{script_name}</code>"
+ f" with LV2 {version}.</footer>\n"
+ )
+
+ return 0
+
+
+def main():
+ """Run the command line tool."""
+
+ scripts_dir = os.path.dirname(os.path.realpath(__file__))
+ top_dir = os.path.dirname(scripts_dir)
+ print(scripts_dir)
+ print(top_dir)
+
+ parser = argparse.ArgumentParser(
+ usage="%(prog)s [OPTION]... [DATA_FILE]",
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+
+ parser.add_argument(
+ "-P",
+ "--lv2-path",
+ help="LV2 path to search, overriding LV2_PATH",
+ )
+
+ parser.add_argument(
+ "-V",
+ "--version",
+ action="store_true",
+ help="print version information and exit",
+ )
+
+ parser.add_argument(
+ "-o",
+ "--output",
+ default=os.path.join(
+ top_dir, "content", "pages", "host-compatibility.md"
+ ),
+ help="output file path (default: content/pages/host-compatibility.md)",
+ )
+
+ parser.add_argument(
+ "data_file",
+ metavar="DATA_FILE",
+ default=["host_compatibility.ttl"],
+ nargs="*",
+ help="Turtle file with compatibility information",
+ )
+
+ args = parser.parse_args(sys.argv[1:])
+ if args.version:
+ print(f"update_host_compatibility.py {__version__}")
+ return 0
+
+ if args.lv2_path is None:
+ args.lv2_path = os.getenv("LV2_PATH")
+
+ if args.lv2_path is None:
+ args.lv2_path = _default_lv2_path()
+
+ sys.stderr.write(f'Searching LV2 path "{args.lv2_path}"\n')
+
+ with open(args.output, "w", encoding="utf-8") as out:
+ return run(args.lv2_path, args.data_file, out)
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/themes/lv2/static/css/main.css b/themes/lv2/static/css/main.css
index c6636e2..237a4cf 100644
--- a/themes/lv2/static/css/main.css
+++ b/themes/lv2/static/css/main.css
@@ -212,10 +212,27 @@ header a#page-title {
color: #444;
}
+footer {
+ margin-top: 2em;
+ font-size: small;
+}
+
#content {
padding: 0;
}
+.error {
+ color: #990A1B;
+}
+
+.warning {
+ color: #7B6000;
+}
+
+.success {
+ color: #546E00;
+}
+
.highlight {
font-family: "SF Mono", Menlo, Consolas, "DejaVu Sans Mono", monospace, fixed;
border: solid 1px #EEE;
@@ -557,6 +574,18 @@ header a#page-title {
color: #DDD;
}
+ .error {
+ color: #DC322F;
+ }
+
+ .warning {
+ color: #B58900;
+ }
+
+ .success {
+ color: #859900;
+ }
+
.highlight {
color: #BBB;
border: solid 1px #444;