diff options
27 files changed, 835 insertions, 522 deletions
@@ -38,7 +38,7 @@ PROJECT_NUMBER = # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. -OUTPUT_DIRECTORY = build/default/doc/doc +OUTPUT_DIRECTORY = build/default/ns/doc # 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 diff --git a/core.lv2/lv2.ttl b/core.lv2/lv2.ttl index c3abdbf..68c8891 100644 --- a/core.lv2/lv2.ttl +++ b/core.lv2/lv2.ttl @@ -1,5 +1,5 @@ # RDF Schema for LV2 plugins -# PROVISIONAL Revision 4 +# PROVISIONAL Revision 4.0pre1 # # This document describes the classes and properties that are defined by the # core LV2 specification. See <http://lv2plug.in> for more information. @@ -70,8 +70,8 @@ more details. doap:shortdesc "An audio plugin interface specification" ; doap:programming-language "C" ; doap:release [ - doap:revision "4" ; - doap:created "2009-08-16" + doap:revision "4.0pre2" ; + doap:created "2010-11-05" ] ; doap:maintainer [ a foaf:Person ; @@ -83,27 +83,29 @@ more details. foaf:name "David Robillard" ; foaf:homepage <http://drobilla.net/> ; rdfs:seeAlso <http://drobilla.net/drobilla.rdf> - ] ; rdfs:comment """ + ] ; + lv2:documentation """ <h4>Overview</h4> +<p> There are a large number of open source and free software synthesis packages in use or development at this time. This API ("LV2") attempts to give programmers the ability to write simple "plugin" audio processors in C/C++ and link them dynamically ("plug" them) into a range of these packages ("hosts"). It should be possible for any host and any plugin to communicate completely through this interface. - +</p><p> This API is deliberately as short and simple as possible. The information required to use a plugin is in a companion data (RDF) file. The shared library portion of the API does not contain enough information to make use of the plugin possible; the data file is mandatory. - +</p><p> Plugins can operate on any type of data. Plugins have "ports" that are inputs or outputs and each plugin is "run" for a "block" corresponding to a short time interval measured in samples. The plugin may assume that all its input and output ports have been connected to the relevant data location (using the connect_port() function) before it is asked to run, unless the port has been set "connection optional" in the plugin's data file. - +</p><p> This "core" specification defines two types of port data, equivalent to those in LADSPA: control rate and audio rate. Audio rate data is communicated using arrays with one <code>float</code> element per sample processed, allowing @@ -112,20 +114,22 @@ rate data is communicated using single <code>float</code> values. Control rate data has a single value at the start of a call to the run() function which is considered valid for the duration of the call to run(). Thus the "control rate" is determined by the block size, controlled by the host. - +</p><p> Plugins reside in shared object files suitable for dynamic linking (e.g. by -dlopen() and family). This file provides one or many plugins via the +dlopen() and family). This object provides one or more <a +href="urn:struct:LV2_Descriptor">plugin descriptors</a> via the lv2_descriptor() function. These plugins can be instantiated to create "plugin instances", which can be connected together to perform tasks. - +</p><p> This API contains very limited error-handling. - -<h4>Threading Rules</h4> Certain hosts may need to call the functions +</p> +<h4>Threading Rules</h4> +<p>Certain hosts may need to call the functions provided by a plugin from multiple threads. For this to be safe, the plugin must be written so that those functions can be executed simultaneously without problems. To facilitate this, the functions provided by a plugin are divided into classes: - +</p> <dl> <dt>Discovery Class</dt> <dd>lv2_descriptor(), extension_data()</dd> @@ -134,11 +138,11 @@ are divided into classes: <dt>Audio Class</dt> <dd>run(), connect_port()</dd> </dl> - +<p> Extensions to this specification which add new functions MUST declare in which of these classes the functions belong, or define new classes for them. The rules that hosts MUST follow are: - +</p> <ul> <li>When a function is running for a plugin instance, no other function in the same class may run for that instance.</li> @@ -147,9 +151,10 @@ The rules that hosts MUST follow are: <li>When a function from the Instantiation class is running for a plugin instance, no other functions for that instance may run.</li> </ul> +<p> Any simultaneous calls that are not explicitly forbidden by these rules are allowed. For example, a host may call run() for two different plugin -instances simultaneously. +instances simultaneously.</p> """ . @@ -242,36 +247,38 @@ language tag. rdfs:comment """ A port MUST have at least one lv2:name which is of type xsd:string. """ ] ; - rdfs:comment """ -The class which represents an LV2 port. + lv2:documentation """ +<p>The class which represents an LV2 port.</p> -In order for it to be used by a host it MUST have at least -the following properties: - rdf:type (with object one of lv2:Port, lv2:InputPort, lv2:OutputPort) - rdf:type (more specific port class, see below) - lv2:index - lv2:symbol - lv2:name +<p>In order for it to be used by a host it MUST have at least +the following properties:</p> +<ul> +<li>rdf:type (with object one of lv2:Port, lv2:InputPort, lv2:OutputPort)</li> +<li>rdf:type (more specific port class, see below)</li> +<li>lv2:index</li> +<li>lv2:symbol</li> +<li>lv2:name</li> +</ul> -All LV2 port descriptions MUST have a property rdf:type where the object is +<p>All LV2 port descriptions MUST have a property rdf:type where the object is one of lv2:Port lv2:InputPort or lv2:OutputPort. Additionally there MUST be at least one other rdf:type property which more specifically describes -type of the port (e.g. lv2:AudioPort). +type of the port (e.g. lv2:AudioPort).</p> -Hosts that do not support a specific port class MUST NOT instantiate the +<p>Hosts that do not support a specific port class MUST NOT instantiate the plugin, unless that port has the connectionOptional property set (in which case the host can simply "connect" that port to NULL). If a host is interested in plugins to insert in a certain signal path (e.g. stereo audio), it SHOULD consider all the classes of a port to determine which ports are most suitable for connection (e.g. by ignoring ports with additional classes the host does -not recognize). +not recognize).</p> -A port has two identifiers - a (numeric) index, and a (textual) symbol. +<p>A port has two identifiers - a (numeric) index, and a (textual) symbol. The index can be used as an identifier at run-time, but persistent references to ports (e.g. in a saved preset) MUST use the symbol. A symbol is guaranteed to refer to the same port on all plugins with a given URI. An index does NOT necessarily refer to the same port on all plugins with a given URI (i.e. the -index for a port may differ between plugin binaries). +index for a port may differ between plugin binaries).</p> """ . lv2:InputPort a rdfs:Class ; @@ -340,39 +347,28 @@ version to distinguish incompatible objects (use the URI for that). #################################### -## Optional Plugin RDF Properties ## +## Documentation ## #################################### -lv2:basicXHTML a rdfs:Class ; - rdfs:seeAlso <http://www.w3.org/TR/xhtml1/> ; - rdfs:seeAlso <http://www.w3.org/TR/xhtml-modularization/> ; - rdfs:comment """ -A very basic subset of XHTML for use with lv2:documentation, intended to be -reasonable for hosts to support for styled inline documentation. - -A literal with this data type is an XHTML 1.0 fragment containing only -tags from the following XHTML modules: text, hypertext, list, basic tables, -image, presentation. See the XHTML and XHTML Modularization specifications -for details. A literal with this data type must be legal to insert as the -body of a <div> tag (free text is allowed). - -If only basicXHTML documentation is given but a host has no facilities for -handling tags, simply stripping tags and inserting newlines after appropriate -tags will yield a somewhat readable plain text version of the documentation. -""" . - lv2:documentation a rdf:Property ; rdfs:domain lv2:Resource ; + rdfs:range rdfs:Literal ; rdfs:label "documentation" ; - rdfs:comment """ -Relates a Plugin to some text/audio/video documentation either online or -included with the plugin package. The value of this property may be either a -URL, or a literal of any type. Literal documentation SHOULD be either plain -text, or lv2:basicXHTML. More advanced documentation should be linked to instead. + rdfs:seeAlso <http://www.w3.org/TR/xhtml-basic/> ; + lv2:documentation """ +<p>Relates a Resource to documentation markup. The value of this property +MUST be a string literal which is a valid XHTML Basic 1.1 fragment suitable +for use as the content of a <div> element. This can be used by +hosts to provide rich online documentation or by tools to generate external +documentation pages. The standard language tagging facility of RDF can be +used to provide multi-lingual documentation.</p> +<p>XHTML Basic is a W3C Recommendation which defines a basic subset of XHTML +intended to be reasonable to implement with limited resources (e.g. on embedded +devices). See <a href="http://www.w3.org/TR/xhtml-basic/#s_xhtmlmodules" +>XHTML Basic, Section 3</a> for a list of legal tags.</p> """ . - ################################### ## Mandatory Port RDF Properties ## ################################### diff --git a/core.lv2/wscript b/core.lv2/wscript index e5680f9..e22249d 100644 --- a/core.lv2/wscript +++ b/core.lv2/wscript @@ -4,7 +4,7 @@ import autowaf import Options # Version of this package (even if built as a child) -LV2CORE_VERSION = '4.0' +LV2CORE_VERSION = '4.0pre1' # Variables for 'waf dist' APPNAME = 'lv2core' diff --git a/doc/style.css b/doc/style.css index 055a707..825671a 100644 --- a/doc/style.css +++ b/doc/style.css @@ -1,180 +1,478 @@ -body { - color: black; - background: white; +html, body { + background-color: #fff; + color: #000; margin: 0; + padding: 0; } - -:link { - color: #00C; - background: transparent; +a:link, a:visited { + text-decoration: none; } - -:visited { - color: #609; - background: transparent; +a:link { + color: #00a; } - -a:active { - color: #C00; - background: transparent; +a:visited { + color: #518; } - -h1, h2, h3, h4, h5, h6 { - text-align: left; +a:hover { + text-decoration: underline; } - -h1, h2 { - background-color: #f2f2f2; - margin-top: 0; - color: #000; - border-bottom: 1px solid #cccccc; +img { + border: 0; +} +h1, h2, h3, h4, h5 { + font-weight: 400; + line-height: 1em; } - h1 { - padding: 1ex; - margin-bottom: 0; + color: #234764; + font-size: 160%; + margin: .7em 0 0; + text-decoration: none; +} +h1 a { + color: #234764; } - h2 { - border-bottom: 1px solid #b2c0dd; - padding: 0.5ex; + color: #366d9c; + font-size: 140%; + font-weight: 700; + margin: 3ex 0 1ex; } - h3 { - padding: 0; - margin: 0 0 0.75ex 0; + color: #366d9c; + font-size: 130%; + margin: 0 0 .75ex; + padding: 0; +} +h4 { + color: #366d9c; + font-size: 120%; + font-style: italic; + margin: 2ex 0 0; + padding: 0; +} +#logoheader { + background-color: #f7f7f7; + border: 0; + border-bottom: 1px solid #999; + height: 84px; + margin: 0; + padding: 1px; + z-index: 1; } - -h2 { - margin: 3ex 0 1ex 0; +#titleheader { + background-color: #f7f7f7; + border: 0; + border-bottom: 1px solid #999; + margin: 0; + padding: 1ex; +} +#title { + color: #366d9c; + font-size: 200%; + font-weight: 700; + margin: .25ex 0 .5ex; + padding: 0; +} +#logo { + height: 63px; + margin-left: 1em; + margin-top: 10px; + width: 100px; +} +#content-body { + border-bottom: 0; + display: block; + font-size: 75%; + left: 0; + margin-left: 2em; + min-width: 660px; + padding: 3px 10px 0 0; + position: absolute; + top: 63px; + width: 93.900002%; + z-index: 0; +} +#body-main { + font-size: 100%; + line-height: 1.4em; + margin-left: 19em; + padding: 0 .55em 40px 0; +} +#left-hand-navigation { + left: 1ex; + position: absolute; + top: 100px; + z-index: 1; +} +#menu { + font-size: 75%; + margin-bottom: 5px; + padding: 0; + width: 16em; +} +#menu ul { + border: 0; + list-style: none; + margin: 0; + padding: 0; +} +#menu ul.level-one a { + background-color: #f5f5f5; + border: 1px solid #dadada; + color: #4b5a6a; + display: block; + margin: 0 0 4px 1.4em; + padding: 2px 2px 2px 4px; + text-transform: uppercase; + width: 13.4em!important; +} +#menu ul.level-one a.selected { + background-color: #FFF; + border-left: 3px solid #ffdb4c; + color: #000; +} +#menu ul.level-two li:first-child a { + border-top: 0; +} +#menu ul.level-two a { + background: none; + background-color: transparent; + border: 0; + border-top: 1px solid #ddd; + color: #3c4b7b; + display: block; + margin: 0 3em 0 1.5em; + padding: .1em; + text-transform: none; + width: 11em!important; +} +#menu ul.level-two a:visited { + color: #4c3b5b; +} +#menu ul.level-one ul.level-two a.selected { + background-color: #FFF; + border-left: 0; + color: #000; + font-weight: 700; +} +#menu li ul { + margin-bottom: 7px; +} +#menu a { + text-decoration: none; +} +#menu ul.level-three a { + border: 0; + color: #5e72a5; + display: block; + font-size: 95%; + margin: 0 3em 0 1.8em; + padding: .1em .1em .1em 1em; + width: 10em!important; +} +#menu ul.level-three li.selected a.selected { + color: #000; + font-weight: 400; +} +#menu ul.level-three { + margin-top: 5px; +} +#left-hand-navigation h4 { + color: #4c5b6b; + font-size: 77%; + margin: .2em 0 .3em; + padding: .4em 0 0 1.5em; +} +#left-hand-navigation h4 a { + color: #4c5b6b; + font-weight: 700; + text-decoration: none; +} +#body-main ul, #body-main li { + margin-left: 1em; + padding-left: 0; +} +#utility-menu { + font-size: 88%; + height: 85px; + margin: 0; + padding: 0; + position: absolute; + right: 4%; + top: 0; + width: 400px; + z-index: 1; +} +#utility-menu a { + color: #436a85; + padding: 0 .5em; + text-decoration: none; +} +#utility-menu a:hover { + text-decoration: underline; +} +#utility-menu #screen-switcher { + bottom: 0; + margin: 0; + padding: 0; + position: absolute; + right: 0; +} +#screen-switcher dl { + margin: 0; + padding: 0; +} +#searchbox { + font-weight: 700; + position: absolute; + right: 0; + text-align: right; + top: 0; + vertical-align: middle; + white-space: nowrap; + width: 28.1em; +} +#search { + color: #a38e60; + padding: 5px 5px 0 0; +} +#search .input-text { + background-color: #FFF; + border: 1px solid #c4cccc; + font-size: 116%; + font-weight: 400; + margin-top: 3px; + vertical-align: top; + width: 11em; +} +#search .input-button { + background-color: #f8f7f7; + border-bottom: 1px solid #6f7777; + border-left: 1px solid #c4cccc; + border-right: 1px solid #6f7777; + border-top: 1px solid #c4cccc; + color: #234; + font-weight: 700; + margin: 3px .4em 0; + padding: 0 .2em; + vertical-align: text-top; +} +input.formbutton { + background-color: #f8f7f7; + border-bottom: 1px solid #6f7777; + border-left: 1px solid #c4cccc; + border-right: 1px solid #6f7777; + border-top: 1px solid #c4cccc; + color: #234; + font-weight: 700; + vertical-align: text-top; +} +.formtextinput { + background-color: #FFF; + border: 1px solid #c4cccc; + font-size: 116%; + font-weight: 400; + vertical-align: top; +} +div#content table { + clear: right; +} +#body-main h1.pageheading { + margin: 40px 0 10px; +} +.content-section { + margin-top: 15px; +} +.content-section h1 { + margin: 0 0 10px; +} +.content-section p { + margin: 0 0 5px; + padding-left: 12px; +} +.content-section .pubdate { + color: #696969; + margin: 0 0 8px; + padding: 0 0 0 12px; +} +blockquote { + border-left: 1px solid #ccc; + margin-left: 1em; + padding-left: 1em; +} +#utility-menu dl { + font-size: 80%; + font-weight: 700; + text-align: right; +} +#utility-menu dd { + display: inline; + font-weight: 400; + margin: 0; + padding: 0 0 0 8px; +} +#utility-menu dd a { + color: #888; + margin: 0; + padding: 0; +} +#utility-menu dt { + margin: 0; +} +#footer { + border-top: 1px dashed #ccc; + bottom: 0; + clear: both; + font-size: 75%; + margin: 3em 0 0; + padding: 1em; + position: relative; + text-align: right; + vertical-align: top; +} +.footer-text { + margin: 0 0 0 0; + vertical-align: top; + color: #444; +} +#searchbox a.reference, #searchbox span.reference { + color: #339; + font-size: 85%; + font-weight: 400; + position: absolute; + right: 8.3em; + text-decoration: none; + top: 2.9em; +} +#content { + font-size: 115%; + min-height: 500px; +} +#body-main .success p { + margin: 4px 8px; +} +body { + background: #FFF; + color: #000; + margin: 0; +} +:link { + background: transparent; + color: #00C; +} +:visited { + background: transparent; + color: #609; +} +a:active { + background: transparent; + color: #C00; +} +.sec { + background-color: #f7f7f7; + border-bottom: 1px solid #CCC; + color: #000; + margin: 1em 0 .5em; + padding: 1ex; } - ul, ol { - margin: 0 1ex 2ex 1ex; + margin: 0 1ex 2ex; } - .content { - margin-left: 1.5em; - margin-right: 1.5em; + margin-left: 1.5em; + margin-right: 1.5em; } - .label { - font-style: italic; - margin: 1ex 0 1ex 0; - } - + font-style: italic; + margin: 1ex 0; +} .index { - margin-left: 1em; + margin-left: 1em; } - .restriction { - margin: 0.5ex 0 2ex 4ex; - background-color: #eee; - padding: 0.25ex; - border: 1px solid #ddd; + border-left: 4px solid #ddd; + margin: .5ex 0 1ex 4ex; + padding: 0 0 0 1ex; } - .description { - margin-bottom: 2ex; + margin-bottom: 2ex; } - .blankdesc { - background-color: #eee; - margin: 0.5em; - border: 1px solid #ddd; + background-color: #eee; + border: 1px solid #ddd; + margin: .5em; } - .blankterm { - padding-right: 0.5em; + padding-right: .5em; } - .specterm { - margin-top: 1ex; - padding: 1ex; - background-color: #fafafa; - border: 1px solid #ddd; -} - -.footer { - margin-top: 3ex; + background-color: #fbfbfb; + border: 1px solid #ddd; + margin-top: 1ex; padding: 1ex; - border-top: solid #4a6aaa 1px; - text-align: right; } - -.footer-text { - font-size: small; - color: #2a3c61; - vertical-align: top; -} - dl { - padding: 0; - margin: 0; + margin: 0; + padding: 0; } - dt { - font-weight: bold ; - margin-top: 0.75ex; + font-weight: 700; + margin-top: .75ex; } - hr { - color: silver; background-color: silver; - height: 1px; border: 0; - margin-top: 1.5ex; + color: silver; + height: 1px; margin-bottom: 1.5ex; + margin-top: 1.5ex; } - div.head { - margin-bottom: 1em; + margin-bottom: 1em; } - div.head h1 { - margin-top: 2em; - clear: both; + clear: both; + margin-top: 2em; } - div.head table { - margin-left: 2em; - margin-top: 2em; -} - -th { - text-align: left; + margin-left: 2em; + margin-top: 2em; } - td { - padding-right: 2ex; + padding-right: 2ex; } - -.meta { - background-color: #f9fafc; +#meta { + border-bottom: 1px solid #c4cfe5; font-size: small; - margin: 0 0 2ex 0; + margin: 0 0 2ex; padding: 1ex 0 1ex 2ex; - border-bottom: 1px solid #c4cfe5; } - .metahead { - padding-right: 1ex; + padding-right: 1ex; } - pre { - margin-left: 2em; - color: #373; + color: #373; + margin-left: 2em; } - code { - color: #373; + color: #373; +} +#menu li, #searchbox form, ul#iconbar li, #body-main .success p a { + display: inline; +} +#menu ul.level-one a:hover, #menu ul.level-two a:hover, #menu ul.level-three a:hover, #left-hand-navigation h4 a:hover { + color: #000; + text-decoration: underline; +} +h1, h2, h3, h4, h5, h6, th { + text-align: left; } - @media aural { dt { - pause-before: 20% + pause-before: 20%; } pre { - speak-punctuation: code + speak-punctuation: code; } } diff --git a/ext/atom.lv2/atom.ttl b/ext/atom.lv2/atom.ttl index 7702d21..ff0cf7e 100644 --- a/ext/atom.lv2/atom.ttl +++ b/ext/atom.lv2/atom.ttl @@ -37,103 +37,104 @@ foaf:homepage <http://drobilla.net/> ; rdfs:seeAlso <http://drobilla.net/drobilla.rdf> ] ; - rdfs:comment """ -This extension defines a generic format for a typed piece of data, called an + lv2:documentation """ +<p>This extension defines a generic format for a typed piece of data, called an "<a href="#Atom">Atom</a>" (e.g. integers, strings, buffers, data structures, etc). Atoms allow LV2 plugins and hosts to communicate, process, serialise, and store values of any type via a generic mechanism (e.g. LV2 ports, events, disk, shared memory, network). Atoms are, with one exception, Plain Old Data (POD) and may be safely copied (e.g. with a simple call to -<code>memcpy</code>). +<code>memcpy</code>).</p> -Since Atom communication can be implemented generically, plugins that +<p>Since Atom communication can be implemented generically, plugins that understand some type can be used together in a host that does not understand that type, and plugins (e.g. routers, delays) can process atoms of unknown -type. +type.</p> -An Atom can be trivially constructed in-place from an +<p>An Atom can be trivially constructed in-place from an <a href="http://lv2plug.in/ns/ext/event#Event">Event</a> as defined by the <a href="http://lv2plug.in/ns/ext/event">LV2 Event</a> extension. In other words, an Event is simply an Atom with a time stamp header. Atoms SHOULD be used anywhere a "value" needs to be stored or communicated, to allow -implementations to be polymorphic and extensible. +implementations to be polymorphic and extensible.</p> -Atoms (the start of the LV2_Atom header) MUST be 32-bit aligned. +<p>Atoms (the start of the LV2_Atom header) MUST be 32-bit aligned.</p> -Optionally, the host MAY implement <a href="#blobSupport">blob support</a>. +<p>Optionally, the host MAY implement <a href="#blobSupport">blob support</a>. A <a href="#Blob">Blob</a> is a dynamically allocated chunk of memory that (unlike an Atom) is not necessarily POD. Blobs are accessed via a <a href="#Reference">Reference</a>, which is a special case of Atom that always has <code>type = 0</code>, is not POD, and can only be copied using host provided functions. This allows plugins and hosts to work with data -of any type at all. +of any type at all.</p> -Atoms can be communicated in many ways. Since an Atom is the payload of an +<p>Atoms can be communicated in many ways. Since an Atom is the payload of an Event, an <a href="http://lv2plug.in/ns/ext/event#EventPort">EventPort</a> can be used for communicating Atoms in realtime with sub-sample time stamp accuracy. This extension also defines two port types for connecting directly -to a single Atom: <a href="ValuePort">ValuePort</a> and <a href="#MessagePort" +to a single Atom: <a href="#ValuePort">ValuePort</a> and <a href="#MessagePort" >MessagePort</a>, which both have the same buffer format but different -semantics (with respect to how the run() callback interprets the Atom). +semantics (with respect to how the run() callback interprets the Atom).</p> -This extension requires the host to support the <a -href="http://lv2plug.in/ns/ext/uri-map">LV2 URI Map</a> extension. +<p>This extension requires the host to support the <a +href="http://lv2plug.in/ns/ext/uri-map">LV2 URI Map</a> extension.</p> """ . atom:Atom a rdfs:Class ; rdfs:label "Atom" ; - rdfs:comment """ -Abstract base class for all atoms. An <a href="urn:struct:LV2_Atom" + lv2:documentation """ +<p>Abstract base class for all atoms. An <a href="urn:struct:LV2_Atom" >LV2_Atom</a> has a 16-bit <code>type</code> and <code>size</code> followed by -a <code>body</code>. +a <code>body</code>.</p> -All concrete Atom types (subclasses of this class) MUST define a precise -binary layout for <code>body</code>. +<p>All concrete Atom types (subclasses of this class) MUST define a precise +binary layout for <code>body</code>.</p> -The <code>type</code> field is the URI of a subclass of Atom mapped to an +<p>The <code>type</code> field is the URI of a subclass of Atom mapped to an integer using the <a href="http://lv2plug.in/ns/ext/uri-map">URI Map</a> extension's <a href="urn:struct:LV2_URI_Map_Feature" >LV2_URI_Map_Feature</a>::uri_to_id with <code>map = "http://lv2plug.in/ns/ext/event"</code>. If a plugin or host does not understand <code>type</code>, that atom SHOULD be gracefully ignored -(though it MAY be copied if it is not a <a href="#Reference">Reference</a>). +(or copied if it is not a <a href="#Reference">Reference</a>).</p> -All atoms are POD by definition except references, which have +<p>All atoms are POD by definition except references, which have <code>type = 0</code>. An Atom MUST NOT contain a Reference. It is safe to copy any non-reference Atom with a simple <code>memcpy</code>, even if -the implementation does not understand <code>type</code>. +the implementation does not understand <code>type</code>.</p> """ . atom:Reference a rdfs:Class ; rdfs:subClassOf atom:Atom ; rdfs:label "Reference" ; - rdfs:comment """ -Reference to a <a href="#Blob">Blob</a>. The actual contents of a Reference + lv2:documentation """ +<p>Reference to a <a href="#Blob">Blob</a>. The actual contents of a Reference are opaque and host specific, and must not be copied, serialized, or otherwise interpreted by a plugin, except via functions provided by the host in -<a href="urn:struct:LV2_Blob_Support">LV2_Blob_Support</a>. +<a href="urn:struct:LV2_Blob_Support">LV2_Blob_Support</a>.</p> -A Reference is a special case of Atom with <code>type = 0</code>. -"Null" is the unique Atom with <code>type = 0</code> and <code>size = 0</code>. +<p>A Reference is a special case of Atom with <code>type = 0</code>. +"Null" is the unique Atom with <code>type = 0</code> and +<code>size = 0</code>.</p> """ . atom:String a rdfs:Class ; rdfs:subClassOf atom:Atom ; rdfs:label "String" ; - rdfs:comment """ -A UTF-8 encoded string, with an optional language tag. An + lv2:documentation """ +<p>A UTF-8 encoded string, with an optional language tag. An <a href="urn:struct:LV2_Atom_String">LV2_Atom_String</a> has an <a href="#ID">ID</a> <code>lang</code> followed by the string data in UTF-8 encoding. The length of the string data in bytes is <code>size - sizeof(uint32_t)</code>, including the terminating NULL character. The <code>lang</code> may be any URI; to describe a human language, use http://lexvo.org/id/term/LANG where LANG is an <a href="http://www.loc.gov/standards/iso639-2/">ISO 693-2</a> or -<a href="http://www.loc.gov/standards/iso639-2/">ISO 693-3</a> language code. +<a href="http://www.loc.gov/standards/iso639-2/">ISO 693-3</a> language code.</p> -For example, "Hello" in English: +<p>For example, "Hello" in English:</p> <pre> struct LV2_Atom { uint16_t type = uri_to_id(atom:String); @@ -151,7 +152,7 @@ struct LV2_Atom { uint32_t lang = uri_to_id("http://lexvo.org/id/term/fr"); char str[] = "Bonjour"; </pre> -or a Turtle string: +<p>or a Turtle string:</p> <pre> struct LV2_Atom { uint16_t type = uri_to_id(atom:String); @@ -166,7 +167,7 @@ char str[] = "<http://example.org/foo> a <http://example.org/Thing& atom:ID a rdfs:Class ; rdfs:subClassOf atom:Atom ; rdfs:label "Integer ID mapped from a URI" ; - rdfs:comment """ + lv2:documentation """ An unsigned 32-bit integer mapped from a URI using the <a href="http://lv2plug.in/ns/ext/uri-map">URI Map</a> extension's <a href="urn:struct:LV2_URI_Map_Feature">LV2_URI_Map_Feature</a>::uri_to_id @@ -177,7 +178,7 @@ with <code>map = NULL</code>. atom:BlankID a rdfs:Class ; rdfs:subClassOf atom:Atom ; rdfs:label "Integer ID for a blank node" ; - rdfs:comment """ + lv2:documentation """ An unsigned 32-bit integer identifier for a blank node. A BlankID is only meaningful within a limited scope (e.g. the Atom in which it appears), and MUST NOT be used as a global identifier. In particular, a BlankID is NOT an @@ -188,17 +189,17 @@ ID, and can not be mapped to/from a URI. atom:Vector a rdfs:Class ; rdfs:subClassOf atom:Atom ; rdfs:label "Vector" ; - rdfs:comment """ -A homogeneous sequence of atoms with equivalent type and size. + lv2:documentation """ +<p>A homogeneous sequence of atoms with equivalent type and size.</p> -An <a href="urn:struct:LV2_Atom_Vector">LV2_Atom_Vector</a> is a +<p>An <a href="urn:struct:LV2_Atom_Vector">LV2_Atom_Vector</a> is a 16-bit <code>elem_count</code> and <code>elem_type</code> followed by <code>elem_count</code> atom bodies of type <code>elem_type</code>. The element type must be a fixed size <a href="#Atom">Atom</a> type, i.e. the -size of each element is the vector's <code>size / elem_count</code>. +size of each element is the vector's <code>size / elem_count</code>.</p> -For example, an atom:Vector containing 42 elements of type atom:Float looks -like this in memory: +<p>For example, an atom:Vector containing 42 elements of type atom:Float looks +like this in memory:</p> <pre> struct LV2_Atom { uint16_t type = uri_to_id(atom:Vector); @@ -214,31 +215,31 @@ float elem_01; float elem_41; </pre> -Note that it is possible to construct a valid Atom for each element +<p>Note that it is possible to construct a valid Atom for each element of the vector, even by an implementation which does not understand -<code>elem_type</code>. +<code>elem_type</code>.</p> -A Vector header is 64-bits, thus the first element of a Vector is 64-bit -aligned if the Vector itself is 64-bit aligned. +<p>A Vector header is 64-bits, thus the first element of a Vector is 64-bit +aligned if the Vector itself is 64-bit aligned.</p> """ . atom:Tuple a rdfs:Class ; rdfs:subClassOf atom:Atom ; rdfs:label "Tuple" ; - rdfs:comment """ -A sequence of <a href="#Atom">atoms</a> with varying <code>type</code> -and <code>size</code>. + lv2:documentation """ +<p>A sequence of <a href="#Atom">atoms</a> with varying <code>type</code> +and <code>size</code>.</p> -The body of a Tuple is simply a sequence of complete atoms, each aligned to -32 bits. +<p>The body of a Tuple is simply a sequence of complete atoms, each aligned to +32 bits.</p> """ . atom:Property a rdfs:Class ; rdfs:subClassOf atom:Atom ; rdfs:label "Property of an Object" ; - rdfs:comment """ + lv2:documentation """ A single property of some <a href="#Object">Object</a>. An <a href="urn:struct:LV2_Atom_Property">LV2_Atom_Property</a> has an <a href="#ID">ID</a> <code>key</code> and @@ -249,30 +250,30 @@ has an <a href="#ID">ID</a> <code>key</code> and atom:Object a rdfs:Class ; rdfs:subClassOf atom:Atom ; rdfs:label "Object" ; - rdfs:comment """ -Abstract base class for an "Object", i.e. an <a href="#Atom">Atom</a> + lv2:documentation """ +<p>Abstract base class for an "Object", i.e. an <a href="#Atom">Atom</a> with a number of <a href="#Property">properties</a>. An <a href="urn:struct:LV2_Object">LV2_Object</a> is an unsigned 32-bit integer <code>context</code> and <code>id</code> followed by a sequence of -<a href="urn:struct:LV2_Atom_Property" >properties</a>. +<a href="urn:struct:LV2_Atom_Property" >properties</a>.</p> -The <code>context</code> is mapped using the <a +<p>The <code>context</code> is mapped using the <a href="http://lv2plug.in/ns/ext/uri-map">URI Map</a> extension's <a href="urn:struct:LV2_URI_Map_Feature">LV2_URI_Map_Feature</a>::uri_to_id -with <code>map = NULL</code>, and may be 0 (the default context). +with <code>map = NULL</code>, and may be 0 (the default context).</p> -Note this is an abstract class, i.e. no Atom can exist with +<p>Note this is an abstract class, i.e. no Atom can exist with <code>type = uri_to_id(atom:Object)</code>. An Object is either a <a href="urn:struct:LV2_Resource">Resource</a> or a <a href="urn:struct:Blank">Blank</a>, but the <code>body</code> always has the same binary format. Thus, both named and anonymous objects can be handled -with common code using only a 64-bit header for both. +with common code using only a 64-bit header for both.</p> """ . atom:Resource a rdfs:Class ; rdfs:subClassOf atom:Object ; - rdfs:comment """ + lv2:documentation """ An <a href="#Object">Object</a> where <code>id</code> is the URI of the resource mapped to an <a href="#ID">ID</a>. """ . @@ -280,7 +281,7 @@ URI of the resource mapped to an <a href="#ID">ID</a>. atom:Blank a rdfs:Class ; rdfs:subClassOf atom:Object ; - rdfs:comment """ + lv2:documentation """ An <a href="#Object">Object</a> where <code>id</code> is the blank node ID of the object, which is only meaningful within a certain limited scope (e.g. the container of the Blank) and MUST NOT be used as a global ID. @@ -291,14 +292,14 @@ In particular, <code>id</code> is NOT an <a href="ID">ID</a>. atom:Model a rdfs:Class ; rdfs:subClassOf atom:Atom ; rdfs:label "Model" ; - rdfs:comment """ + lv2:documentation """ A description of a set of <a href="#Object">objects</a>. In memory, a Model is simply a sequence of objects. """ . atom:Bang a rdfs:Class ; rdfs:subClassOf atom:Atom ; - rdfs:label "Bang (activity) (<code>size = 0</code>)" . + rdfs:label "Bang (activity) (size = 0)" . atom:Byte a rdfs:Class ; @@ -327,7 +328,7 @@ atom:Double a rdfs:Class ; atom:blobSupport a lv2:Feature ; rdfs:label "Blob support" ; - rdfs:comment """ + lv2:documentation """ Support for dynamically allocated blobs. If a host supports this feature, it MUST pass a <a href="urn:struct:LV2_Feature">LV2_Feature</a> with <code>URI</code> http://lv2plug.in/ns/ext/atom#blobSupport @@ -338,46 +339,46 @@ and <code>data</code> pointing to a <a href="urn:struct:LV2_Blob_Support" atom:Blob a rdfs:Class ; rdfs:label "Blob" ; - rdfs:comment """ -Base class for all dynamically allocated blobs. An <a + lv2:documentation """ +<p>Base class for all dynamically allocated blobs. An <a href="urn:struct:LV2_Blob" >LV2_Blob</a> ia an opaque pointer to host data. The type and data of a blob can be accessed via host-provided functions in <a href="urn:struct:LV2_Blob_Support">LV2_Blob_Support</a>. The type of a blob can be any URI that describes a data format. Blobs are -always allocated by the host, and unlike atoms are not necessarily POD. +always allocated by the host, and unlike atoms are not necessarily POD.</p> -Blob data MUST NOT be used in any way by an implementation that does not +<p>Blob data MUST NOT be used in any way by an implementation that does not understand that blob type (unlike Atoms, meaningful type-oblivious use -of a Blob is impossible). +of a Blob is impossible).</p> """ . atom:AtomPort a rdfs:Class ; rdfs:subClassOf lv2:Port ; rdfs:label "Atom Port" ; - rdfs:comment """ -A port which contains an <a href="#Atom">Atom</a>. Ports of this type will + lv2:documentation """ +<p>A port which contains an <a href="#Atom">Atom</a>. Ports of this type will be connected to a 32-bit aligned <a href="urn:struct:LV2_Atom">LV2_Atom</a> -immediately followed by <code>size</code> bytes of data. +immediately followed by <code>size</code> bytes of data.</p> -This is an abstract port type, i.e. a port MUST NOT only be an AtomPort, +<p>This is an abstract port type, i.e. a port MUST NOT only be an AtomPort, but must be a more descriptive type that is a subclass of AtomPort which defines the port's semantics (typically <a href="#ValuePort">ValuePort</a> -or <a href="#MessagePort">MessagePort</a>). +or <a href="#MessagePort">MessagePort</a>).</p> -Before calling a method on the plugin that writes to an AtomPort output, +<p>Before calling a method on the plugin that writes to an AtomPort output, the host MUST set the size of the Atom in that output to the amount of available memory immediately following the Atom header. The plugin MUST write a valid Atom to that port (leaving it untouched is illegal). If there is no reasonable value to write to the port, the plugin MUST write NULL -(the Atom with both <code>type = 0</code> and <code>size = 0</code>). +(the Atom with both <code>type = 0</code> and <code>size = 0</code>).</p> """ . atom:ValuePort a rdfs:Class ; rdfs:subClassOf atom:AtomPort ; rdfs:label "Value Port" ; - rdfs:comment """ + lv2:documentation """ An AtomPort that interprets its data as a persistent and time-independent "value". <ul> @@ -411,7 +412,7 @@ atom:supports a rdf:Property ; rdfs:domain lv2:Port ; rdfs:range atom:Atom ; rdfs:label "supports" ; - rdfs:comment """ + lv2:documentation """ Indicates that a Port supports a certain <a href="#Atom">Atom</a> type. This is distinct from the port type - e.g. the port type ValuePort can hold atoms with many different types. This property is used to describe which diff --git a/ext/contexts.lv2/contexts.ttl b/ext/contexts.lv2/contexts.ttl index ad37d95..187acd0 100644 --- a/ext/contexts.lv2/contexts.ttl +++ b/ext/contexts.lv2/contexts.ttl @@ -35,32 +35,32 @@ a lv2:Specification ; a lv2:Feature ; doap:name "LV2 Contexts" ; - rdfs:comment """ -An extension for LV2 plugins which have several execution contexts. + lv2:documentation """ +<p>An extension for LV2 plugins which have several execution contexts.</p> -Contexts allow plugins to run several tasks in parallel and process port +<p>Contexts allow plugins to run several tasks in parallel and process port input/output in multiple threads. Contexts can be used to add non-realtime functionality to a plugin while still keeping the audio run() method -realtime safe. +realtime safe.</p> -Any host which supports this extension must pass an LV2_Feature to +<p>Any host which supports this extension must pass an LV2_Feature to the plugin's instantiate method with URI http://lv2plug.in/ns/ext/contexts -and a pointer to a +and a pointer to a</p> <pre> struct { void* host_handle; void (*request_run)(void* host_handle, const char* context_uri); } </pre> -where the plugin may call request_run with the given host_handle (from any -context) to demand immediate execution of the context specified. +<p>where the plugin may call request_run with the given host_handle (from any +context) to demand immediate execution of the context specified.</p> -If the host does not support blocking contexts, request_run may be set to NULL, -but plugins which have a :BlockingContext which is :mandatory MUST NOT be -instantiated. If the plugin has ANY context which is :hardRTCapable, -request_run must be realtime safe (as defined by lv2:hardRTCapable). +<p>If the host does not support blocking contexts, request_run may be set to +NULL, but plugins which have a :BlockingContext which is :mandatory MUST NOT +be instantiated. If the plugin has ANY context which is :hardRTCapable, +request_run must be realtime safe (as defined by lv2:hardRTCapable).</p> -Unless otherwise stated, each context (defined by some URI) adds a new +<p>Unless otherwise stated, each context (defined by some URI) adds a new threading class similar to the Audio class defined by LV2. Each context has a run callback and a connect_port callback both in the same class (i.e. can't be called concurrently), but may be called concurrently with functions for other @@ -68,8 +68,8 @@ contexts (excluding the Instantiation class). Context properties such as ctx:hardRTCapable apply to both functions. The host MUST only call the correct connect_port function associated with the context for that port, i.e. it is an error to use the main LV2 connect_port -function on a port with a context other than the main LV2 run function. -"""^^lv2:basicXHTML . +function on a port with a context other than the main LV2 run function.</p> +""" . ########################## @@ -78,21 +78,21 @@ function on a port with a context other than the main LV2 run function. ctx:Context a rdfs:Class ; rdfs:label "LV2 Context" ; - rdfs:comment """ -A potentially concurrent context (callback) on a plugin. + lv2:documentation """ +<p>A potentially concurrent context (callback) on a plugin.</p> -Ports are always associated with a context. If a port has no explicit context -property, then its context is ctx:AudioContext (the default LV2 run() context). +<p>Ports are always associated with a context. If a port has no explicit context +property, then its context is ctx:AudioContext (the default LV2 run() context).</p> -A plugin indicates support for a context by supporting an LV2 Feature with +<p>A plugin indicates support for a context by supporting an LV2 Feature with that context's URI. If a plugin optionally supports a context (e.g. <code><plugin> lv2:optionalFeature ctx:IdleContext .</code>), then all ports associated with that context MUST be lv2:connectionOptional. Thus, hosts that do not support contexts will connect such ports to NULL and the -plugin can run with only a standard LV2 run() context. +plugin can run with only a standard LV2 run() context.</p> -Any plugin that supports any context (optionally or mandatorily) MUST adhere -to the following additional threading rules for LV2_Descriptor.connect_port: +<p>Any plugin that supports any context (optionally or mandatorily) MUST adhere +to the following additional threading rules for LV2_Descriptor.connect_port:</p> <ul> <li>connect_port MUST only be called for a given port from the context associated with that port</li> @@ -100,16 +100,16 @@ associated with that port</li> contexts (but MUST NOT be called concurrently for multiple ports in the same context)</li> </ul> -Note this implies that any shared data access in connect_port may be +<p>Note this implies that any shared data access in connect_port may be accessed concurrently. The plugin is responsible for any synchronisation -or locking necessary to make this possible. +or locking necessary to make this possible.</p> """ . ctx:AudioContext a ctx:Context , lv2:Feature ; rdfs:comment """The context of LV2_Descriptor.run().""" . ctx:MessageContext a ctx:Context , lv2:Feature ; - rdfs:comment """ + lv2:documentation """ A non-realtime context for plugin control via message passing. This context has a run method which takes a bitset of flags for parameters specifying which input and output ports are valid before and after the run method has executed, diff --git a/ext/data-access.lv2/data-access.ttl b/ext/data-access.lv2/data-access.ttl index ce5c849..029854e 100644 --- a/ext/data-access.lv2/data-access.ttl +++ b/ext/data-access.lv2/data-access.ttl @@ -31,8 +31,8 @@ doap:license <http://usefulinc.com/doap/licenses/mit> ; doap:name "LV2 Data Access" ; doap:release [ - doap:revision "1" ; - doap:created "2008-08-11" ; + doap:revision "1.1pre1" ; + doap:created "2010-10-29" ] ; doap:maintainer [ a foaf:Person ; diff --git a/ext/dyn-manifest.lv2/dyn-manifest.ttl b/ext/dyn-manifest.lv2/dyn-manifest.ttl index 84e8f5a..6afb305 100644 --- a/ext/dyn-manifest.lv2/dyn-manifest.ttl +++ b/ext/dyn-manifest.lv2/dyn-manifest.ttl @@ -45,8 +45,8 @@ doap:shortdesc "An LV2-based specification for dynamic data generation." ; doap:programming-language "C" ; doap:release [ - doap:revision "1" ; - doap:created "2009-06-13" + doap:revision "1.1pre1" ; + doap:created "2010-10-29" ] ; doap:maintainer [ a foaf:Person ; diff --git a/ext/event.lv2/event.ttl b/ext/event.lv2/event.ttl index 4f939a4..7c0efba 100644 --- a/ext/event.lv2/event.ttl +++ b/ext/event.lv2/event.ttl @@ -30,10 +30,10 @@ <http://lv2plug.in/ns/ext/event> a lv2:Specification ; doap:license <http://usefulinc.com/doap/licenses/mit> ; doap:name "LV2 Events" ; - rdfs:seeAlso "event-helpers.h" ; + rdfs:seeAlso <event-helpers.h> ; doap:release [ - doap:revision "1" ; - doap:created "2008-04-04" ; + doap:revision "1.1pre1" ; + doap:created "2010-10-29" ] ; doap:maintainer [ a foaf:Person ; @@ -44,7 +44,7 @@ a foaf:Person ; foaf:name "Lars Luthman" ; ] ; - rdfs:comment """ + lv2:documentation """ This extension defines a generic time-stamped event port type, which can be used to create plugins that read and write real-time events, such as MIDI, OSC, or any other type of event payload. The type(s) of event supported by diff --git a/ext/files.lv2/files.ttl b/ext/files.lv2/files.ttl index a83889d..4f1b68b 100644 --- a/ext/files.lv2/files.ttl +++ b/ext/files.lv2/files.ttl @@ -38,51 +38,50 @@ foaf:homepage <http://drobilla.net/> ; rdfs:seeAlso <http://drobilla.net/drobilla.rdf> ] ; - rdfs:comment """ -This extension provides a mechanism for plugins to create new files for + lv2:documentation """ +<p>This extension provides a mechanism for plugins to create new files for storing arbitrary data (e.g. waveforms), which can be persisted using the <a href="http://lv2plug.in/ns/ext/persist">LV2 Persist</a> extension. This allows plugins to work with potentially very large data via files, -and save/restore these files. +and save/restore these files.</p> -The motivating idea behind this extension is that all details of file +<p>The motivating idea behind this extension is that all details of file management must be handled by the host in whatever way is most appropriate for that host. Plugins MUST NOT make any assumption about filesystem locations -beyond what is explicitly guaranteed by this extension. +beyond what is explicitly guaranteed by this extension.</p> -To create a new file, plugins request a filename from the host. This way, +<p>To create a new file, plugins request a filename from the host. This way, the host is aware of files used by the plugin and can use an appropriate location for them that the plugin alone could not know (e.g. using an -appropriate disk volume for recording). +appropriate disk volume for recording).</p> -Plugins may also use pre-existing files from elsewhere on the filesystem. +<p>Plugins may also use pre-existing files from elsewhere on the filesystem. Using the LV2 Persist extension, the host can save both these types of files in an appropriate way (by e.g. storing a link, or copying the file to export -or archive a project). - +or archive a project).</p> """ . files:fileSupport a lv2:Feature ; rdfs:label "Support for plugin-created files" ; - rdfs:comment """ -This feature allows plugins to use pre-existing or newly created files, + lv2:documentation """ +<p>This feature allows plugins to use pre-existing or newly created files, and files them (e.g. across project saves and restores). If a host supports this feature it passes a LV2_Files_FileSupport structure to the plugins instantiate method as a feature (with URI http://lv2plug.in/ns/ext/files#FileSupport). This structure provides a function the plugin can use to create new file names. If and only if the host supports this feature, the plugin MAY files and restore values of -type LV2_FILES_FILENAME. +type LV2_FILES_FILENAME.</p> -A plugin SHOULD use this facility to create any new files it may need +<p>A plugin SHOULD use this facility to create any new files it may need (e.g. samples, waveforms for recording). Plugins MUST NOT expect their state to be correctly restored if they do not use this mechanism to -create new files. +create new files.</p> """ . files:FilePath a atom:AtomType ; rdfs:label "File Path" ; - rdfs:comment """ + lv2:documentation """ The full path to a file on the local filesystem. The format of a files:filePath is a C string (escaped or otherwise restricted in whatever way necessary for the system). This URI (http://lv2plug.in/ns/ext/files#FilePath), diff --git a/ext/host-info.lv2/host-info.ttl b/ext/host-info.lv2/host-info.ttl index 2aac2fc..8289f02 100644 --- a/ext/host-info.lv2/host-info.ttl +++ b/ext/host-info.lv2/host-info.ttl @@ -39,12 +39,12 @@ foaf:homepage <http://drobilla.net/> ; rdfs:seeAlso <http://drobilla.net/drobilla.rdf> ] ; - rdfs:comment """ -This specification defines various properties to represent useful information + lv2:documentation """ +<p>This specification defines various properties to represent useful information about LV2 hosts. Currently, the primary use of this specification is to describe which -extensions are supported by a given host. +extensions are supported by a given host.</p> -The extensions supported by a host can be described like this: +<p>The extensions supported by a host can be described like this:</p> <pre> @prefix hi: <http://lv2plug.in/ns/ext/host-info#> . @@ -55,7 +55,7 @@ The extensions supported by a host can be described like this: hi:sinceVersion "1.2.0" ] . </pre> -"""^^lv2:basicXHTML . +""" . ## Core Classes / Properties diff --git a/ext/instance-access.lv2/instance-access.ttl b/ext/instance-access.lv2/instance-access.ttl index 0646478..465a676 100644 --- a/ext/instance-access.lv2/instance-access.ttl +++ b/ext/instance-access.lv2/instance-access.ttl @@ -31,8 +31,8 @@ doap:license <http://usefulinc.com/doap/licenses/mit> ; doap:name "LV2 Instance Access" ; doap:release [ - doap:revision "1" ; - doap:created "2008-08-11" ; + doap:revision "1.1pre1" ; + doap:created "2010-10-29" ] ; doap:maintainer [ a foaf:Person ; diff --git a/ext/message.lv2/message.ttl b/ext/message.lv2/message.ttl index ae7d438..b47ae56 100644 --- a/ext/message.lv2/message.ttl +++ b/ext/message.lv2/message.ttl @@ -37,65 +37,65 @@ foaf:homepage <http://drobilla.net/> ; rdfs:seeAlso <http://drobilla.net/drobilla.rdf> ] ; - rdfs:comment """ -This extension defines a standard for LV2 "messages" which allow dynamic + lv2:documentation """ +<p>This extension defines a standard for LV2 "messages" which allow dynamic control and investigation of plugin instances, by both hosts and other -plugins. +plugins.</p> -This extension requires the host to support the <a +<p>This extension requires the host to support the <a href="http://lv2plug.in/ns/ext/uri-map">LV2 URI Map</a> extension, and the -<a href="http://lv2plug.in/ns/ext/atom">LV2 Atom</a> extension. +<a href="http://lv2plug.in/ns/ext/atom">LV2 Atom</a> extension.</p> """ . msg:MessageType a rdfs:Class ; rdfs:label "LV2 Message Type" ; - rdfs:comment """ -Base class for all types of LV2 Message. + lv2:documentation """ +<p>Base class for all types of LV2 Message.</p> -A type of message, which must be a resource (i.e. have a URI). This URI +<p>A type of message, which must be a resource (i.e. have a URI). This URI is used as the selector component of a Message and is used by receivers to -interpret the meaning of messages (e.g. which components are present). +interpret the meaning of messages (e.g. which components are present).</p> -A message in memory is simply an <a href="http://lv2plug.in/ns/ext/atom#Dict" +<p>A message in memory is simply an <a href="http://lv2plug.in/ns/ext/atom#Dict" >atom:Dict</a> with at least one rdf:type that is a rdfs:subClassOf msg:MessageType. The definitions of various message types define what -other key/value pairs can be expected in the message. +other key/value pairs can be expected in the message.</p> """ . msg:ControlPort a rdfs:Class ; rdfs:label "Control Port" ; rdfs:subClassOf lv2:Port ; - rdfs:comment """ -An input port used to control a plugin instance. A plugin has + lv2:documentation """ +<p>An input port used to control a plugin instance. A plugin has at most 1 msg:ControlPort. A ControlPort is always an lv2:InputPort. Hosts can send messages to the control port in order to investigate or manipulate -a plugin instance (possibly on behalf of a UI or another plugin instance). +a plugin instance (possibly on behalf of a UI or another plugin instance).</p> -This is an abstract port class, the actual format and semantics +<p>This is an abstract port class, the actual format and semantics of the port buffer (and messages) are defined by some other port type, i.e. a cmdControlPort MUST have another type which defines the format and semantics of the port buffer contents (likely candidates are <a href="http://lv2plug.in/ns/ext/atom#MessagePort">atom:MessagePort</a> -or <a href="http://lv2plug.in/ns/ext/event#EventPort">ev:EventPort</a>). +or <a href="http://lv2plug.in/ns/ext/event#EventPort">ev:EventPort</a>).</p> """ . msg:ResponsePort a rdfs:Class ; rdfs:label "Response Port" ; rdfs:subClassOf lv2:Port ; - rdfs:comment """ -An output port used to notify the host about changes to a plugin instance + lv2:documentation """ +<p>An output port used to notify the host about changes to a plugin instance or respond to messages send to its msg:ControlPort. A plugin has at most 1 StatusPort. A StatusPort is always an lv2:OutputPort. Any response to a command sent to the CommandPort of the plugin will appear in the StatusPort output. The plugin may also emit other messages (i.e. the contents of a -StatusPort are not necessarily responses to commands). +StatusPort are not necessarily responses to commands).</p> -This is an abstract port class, the actual format and semantics +<p>This is an abstract port class, the actual format and semantics of the port buffer (and messages) are defined by some other port type, i.e. a cmdControlPort MUST have another type which defines the format and semantics of the port buffer contents (likely candidates are <a href="http://lv2plug.in/ns/ext/atom#MessagePort">atom:MessagePort</a> -or <a href="http://lv2plug.in/ns/ext/event#EventPort">ev:EventPort</a>). +or <a href="http://lv2plug.in/ns/ext/event#EventPort">ev:EventPort</a>).</p> """ . diff --git a/ext/midi.lv2/midi.ttl b/ext/midi.lv2/midi.ttl index 12725ad..a8c7c6a 100644 --- a/ext/midi.lv2/midi.ttl +++ b/ext/midi.lv2/midi.ttl @@ -34,8 +34,8 @@ doap:name "LV2 MIDI Events" ; rdfs:comment "Defines an LV2 event type for standard raw MIDI" ; doap:release [ - doap:revision "1" ; - doap:created "2008-08-11" ; + doap:revision "1.1pre1" ; + doap:created "2010-10-29" ] ; doap:maintainer [ a foaf:Person ; @@ -51,11 +51,11 @@ midi:MidiEvent a rdfs:Class ; rdfs:label "LV2 MIDI event" ; rdfs:subClassOf lv2ev:Event ; - rdfs:comment """ -A single raw (sequence of bytes) MIDI event. + lv2:documentation """ +<p>A single raw (sequence of bytes) MIDI event.</p> -These events are equivalent to standard MIDI events, with the following -restrictions to ease the burden on plugin authors: +<p>These events are equivalent to standard MIDI events, with the following +restrictions to ease the burden on plugin authors:</p> <ul> <li>Running status is not allowed. Every event must have its own status byte.</li> @@ -83,5 +83,5 @@ restrictions to ease the burden on plugin authors: events to the buffer, and the MIDI reader (plugin or host) can assume that all events are valid.</li> </ul> -"""^^lv2:basicXHTML . +""" . diff --git a/ext/parameter.lv2/parameter.ttl b/ext/parameter.lv2/parameter.ttl index 5970844..d1517c9 100644 --- a/ext/parameter.lv2/parameter.ttl +++ b/ext/parameter.lv2/parameter.ttl @@ -43,22 +43,22 @@ param:Parameter a rdfs:Class ; a lv2:Resource ; rdfs:label "Parameter" ; - rdfs:comment """ -A parameter on an LV2 plugin. Parameters can be manipulated to alter the -behaviour or output of a plugin. Unlike lv2:ControlPort: + lv2:documentation """ +<p>A parameter on an LV2 plugin. Parameters can be manipulated to alter +the behaviour or output of a plugin. Unlike lv2:ControlPort:</p> <ul> <li>A parameter may have any data type</li> <li>Parameters can be dynamically added or removed</li> <li>Parameter values can be manipulated by the plugin</li> </ul> -Note that plugins are not required to support this potential functionality, +<p>Note that plugins are not required to support this potential functionality, parameters can be used to provide a basic LADSPA-like set of floating point -parameters in a more extensible manner. +parameters in a more extensible manner.</p> -Parameters are essentially controls that are not 1:1 associated with ports +<p>Parameters are essentially controls that are not 1:1 associated with ports (manipulation of parameters can be accomplished by e.g. sending messages -to a command port). +to a command port).</p> """ . @@ -66,11 +66,11 @@ param:supportsType a rdf:Property ; rdfs:domain param:Parameter ; rdfs:range atom:AtomType ; rdfs:label "supports type" ; - rdfs:comment """ + lv2:documentation """ Indicates that a Parameter has values of a particular type. A Parameter may support many types. Parameter values are always LV2 Atoms as defined -by the LV2 Atom Extension <http://lv2plug.in/ns/ext/atom#>. Any type -of LV2 Atom may be used as a parameter value. +by the <a href="http://lv2plug.in/ns/ext/atom">LV2 Atom</a> Extension +Any type of LV2 Atom may be used as a parameter value. """ . diff --git a/ext/persist.lv2/persist.ttl b/ext/persist.lv2/persist.ttl index 490e2c1..7ec0e0e 100644 --- a/ext/persist.lv2/persist.ttl +++ b/ext/persist.lv2/persist.ttl @@ -42,49 +42,49 @@ foaf:homepage <http://drobilla.net/> ; rdfs:seeAlso <http://drobilla.net/drobilla.rdf> ] ; - rdfs:comment """ -This extension provides a mechanism for plugins to save and restore state + lv2:documentation """ +<p>This extension provides a mechanism for plugins to save and restore state across instances, allowing hosts to save configuration/state/data with a -project or fully clone a plugin instance (including internal state). +project or fully clone a plugin instance (including internal state).</p> -Unlike ports, this extension allows plugins to save private state data. +<p>Unlike ports, this extension allows plugins to save private state data. The motivating ideal behind this extension is for the state of a plugin instance to be entirely described by port values (as with all LV2 plugins) and a key/value dictionary as defined by this extension. This mechanism is simple, -yet sufficiently powerful to describe the state of very advanced plugins. +yet sufficiently powerful to describe the state of very advanced plugins.</p> -The "state" described by this extension is conceptually a single key/value +<p>The "state" described by this extension is conceptually a single key/value dictionary. Keys are URIs, and values are typed-tagged blobs of any type. The plugin provides a save and restore method for saving and restoring state. To initiate a save or restore, the host calls these methods, passing a callback -to be used for saving or restoring a single key/value pair. In this way, the -actual mechanism of saving and restoring state is completely abstract from the -plugin's perspective. - -Because the state is a simple dictionary, hosts and plugins can work with state -easily (virtually all programming languages have an appropriate dictionary -type available). Additionally, this format is simple and terse to serialise -in many formats (e.g. any RDF syntax, JSON, XML, key/value databases such as -BDB, etc.). In particular, state can be elegantly described in a plugin's -Turtle description, which is useful for presets (among other things). +to be used for saving or restoring a single key/value pair. In this way, +the actual mechanism of saving and restoring state is completely abstract +from the plugin's perspective.</p> + +<p>Because the state is a simple dictionary, hosts and plugins can work +with state easily (virtually all programming languages have an appropriate +dictionary type available). Additionally, this format is simple and terse to +serialise in many formats (e.g. any RDF syntax, JSON, XML, key/value databases +such as BDB, etc.). In particular, state can be elegantly described in a +plugin's Turtle description, which is useful for presets (among other things). Note that these are all simply possibilities enabled by this simple data model. This extension defines only a few function prototypes and does not impose any requirement to use a particular syntax, data structure, library, or other implementation detail. Hosts are free to work with plugin state -in whatever way is most appropriate for that host. - -This extension makes it possible for plugins to save private data, but state is -not necessarily private, e.g. a plugin could have a public interface via ports -for manipulating internal state, which would be saved using this extension. -Plugins are strongly encouraged to represent all state change as modifications -of such key/value variables, to minimize implementation burden and enable -the many benefits of having a universal model for describing plugin state. -The use of URI keys prevents conflict and allows unrelated plugins to -meaningfully describe state changes. Future extensions will describe a -dynamic mechanism for manipulating plugin state, as well as define various -keys likely to be useful to a wide range of plugins. - -In pseudo code, a typical use case in a plugin is: +in whatever way is most appropriate for that host.</p> + +<p>This extension makes it possible for plugins to save private data, but +state is not necessarily private, e.g. a plugin could have a public interface +via ports for manipulating internal state, which would be saved using this +extension. Plugins are strongly encouraged to represent all state change as +modifications of such key/value variables, to minimize implementation burden +and enable the many benefits of having a universal model for describing +plugin state. The use of URI keys prevents conflict and allows unrelated +plugins to meaningfully describe state changes. Future extensions will +describe a dynamic mechanism for manipulating plugin state, as well as define +various keys likely to be useful to a wide range of plugins.</p> + +<p>In pseudo code, a typical use case in a plugin is:</p> <pre> static const char* const KEY_GREETING = "http://example.org/greeting"; @@ -108,7 +108,7 @@ void my_restore(LV2_Handle instance, size_t size; uint32_t type; - const char* greeting = retrieve(callback_data, KEY_GREETING, &size, &type); + const char* greeting = retrieve(callback_data, KEY_GREETING, &size, &type); if (greeting) plugin->state->greeting = greeting; @@ -118,7 +118,7 @@ void my_restore(LV2_Handle instance, } </pre> -Similarly, a typical use case in a host is: +<p>Similarly, a typical use case in a host is:</p> <pre> void store_callback(void* callback_data, const char* key, @@ -134,7 +134,7 @@ Map get_plugin_state(LV2_Handle instance) { LV2_Persist* persist = instance.extension_data("http://lv2plug.in/ns/ext/persist"); Map state_map; - persist.save(instance, store_callback, &state_map); + persist.save(instance, store_callback, &state_map); return state_map; } </pre> @@ -158,7 +158,7 @@ but its use is not required to support the LV2 Persist extension. persist:instanceState a rdf:Property ; rdfs:range persist:InstanceState ; - rdfs:comment """ + lv2:documentation """ Predicate to relate a plugin instance to an InstanceState. This may be used wherever the state of a particular plugin instance needs to be represented. Note that the domain of this property is unspecified, since LV2 does not diff --git a/ext/presets.lv2/presets.ttl b/ext/presets.lv2/presets.ttl index 804e187..21114e8 100644 --- a/ext/presets.lv2/presets.ttl +++ b/ext/presets.lv2/presets.ttl @@ -33,8 +33,8 @@ doap:license <http://usefulinc.com/doap/licenses/mit> ; doap:name "LV2 Presets" ; doap:release [ - doap:revision "2" ; - doap:created "2010-03-02" + doap:revision "2.1pre1" ; + doap:created "2010-10-29" ] ; doap:maintainer [ a foaf:Person ; diff --git a/ext/resize-port.lv2/resize-port.ttl b/ext/resize-port.lv2/resize-port.ttl index 7709c0a..9ddd3cb 100644 --- a/ext/resize-port.lv2/resize-port.ttl +++ b/ext/resize-port.lv2/resize-port.ttl @@ -35,18 +35,18 @@ a lv2:Specification ; a lv2:Feature ; doap:name "LV2 Resize Port Extension" ; - rdfs:comment """ -An extension that allows LV2 plugins to request a resize of an output port. + lv2:documentation """ +<p>An extension that allows LV2 plugins to request a resize of an output port.</p> -Any host which supports this extension must pass an LV2_Feature to +<p>Any host which supports this extension must pass an LV2_Feature to the plugin's instantiate method with URI http://lv2plug.in/ns/ext/resize-port and a pointer to a LV2_Resize_Port_Feature structure (see <a href="resize-port.h">resize-port.h</a> for details). This structure provides a resize_port function which plugins may use to resize output -port buffers as necessary. +port buffers as necessary.</p> -This extension also defines several predicates useful for describing the -amount of space required for a particular port buffer. +<p>This extension also defines several predicates useful for describing the +amount of space required for a particular port buffer.</p> """ . rsz:asLargeAs a rdf:Property ; diff --git a/ext/string-port.lv2/string-port.ttl b/ext/string-port.lv2/string-port.ttl index e6adfc2..8ee6373 100644 --- a/ext/string-port.lv2/string-port.ttl +++ b/ext/string-port.lv2/string-port.ttl @@ -35,7 +35,7 @@ a foaf:Person ; foaf:name "Krzysztof Foltman" ; ] ; - rdfs:comment """ + lv2:documentation """ Defines ports which contain string data. <h4>UI issues</h4> @@ -65,7 +65,7 @@ sp:StringTransfer a lv2:Feature ; sp:StringPort a lv2:Port ; rdfs:label "String port" ; - rdfs:comment """ + lv2:documentation """ Indicates that the port data points to a LV2_String_Data structure as defined in accompanying header file. diff --git a/ext/uri-map.lv2/uri-map.ttl b/ext/uri-map.lv2/uri-map.ttl index e6459c3..54db29d 100644 --- a/ext/uri-map.lv2/uri-map.ttl +++ b/ext/uri-map.lv2/uri-map.ttl @@ -31,8 +31,8 @@ doap:license <http://usefulinc.com/doap/licenses/mit> ; doap:name "LV2 URI Map" ; doap:release [ - doap:revision "1" ; - doap:created "2008-04-16" + doap:revision "1.1pre1" ; + doap:created "2010-10-29" ] ; doap:maintainer [ a foaf:Person ; diff --git a/ext/uri-unmap.lv2/uri-unmap.ttl b/ext/uri-unmap.lv2/uri-unmap.ttl index bf68446..6efab1f 100644 --- a/ext/uri-unmap.lv2/uri-unmap.ttl +++ b/ext/uri-unmap.lv2/uri-unmap.ttl @@ -30,17 +30,13 @@ <http://lv2plug.in/ns/ext/uri-unmap> a lv2:Specification , lv2:Feature ; doap:license <http://usefulinc.com/doap/licenses/mit> ; doap:name "LV2 URI Unmap" ; - doap:release [ - doap:revision "0" ; - doap:created "2010-10-19" - ] ; doap:maintainer [ a foaf:Person ; foaf:name "David Robillard" ; foaf:homepage <http://drobilla.net/> ; rdfs:seeAlso <http://drobilla.net/drobilla.xrdf> ] ; - rdfs:comment """ + lv2:documentation """ This extension is the opposite of the <a href="http://lv2plug.in/ns/ext/uri-map" >LV2 URI Map</a> extension. It allows the host to pass an id_to_uri function to the plugin which can be used for unmapping an integer (previously mapped using diff --git a/extensions/ui.lv2/ui.ttl b/extensions/ui.lv2/ui.ttl index 1c32272..36aee7f 100644 --- a/extensions/ui.lv2/ui.ttl +++ b/extensions/ui.lv2/ui.ttl @@ -33,8 +33,8 @@ doap:license <http://usefulinc.com/doap/licenses/mit> ; doap:name "LV2 UI" ; doap:release [ - doap:revision "2" ; - doap:created "2010-05-10" + doap:revision "2.1pre1" ; + doap:created "2010-10-29" ] ; doap:maintainer [ a foaf:Person ; @@ -46,10 +46,11 @@ foaf:homepage <http://drobilla.net/> ; rdfs:seeAlso <http://drobilla.net/drobilla.rdf> ] ; - rdfs:comment """ + lv2:documentation """ +<p> This extension defines an interface that can be used in LV2 plugins and hosts to create UIs for plugins. The UIs are similar to plugins and reside in shared object -files in an LV2 bundle. UIs are associated with a plugin in RDF using the triples +files in an LV2 bundle. UIs are associated with a plugin in RDF using the triples:</p> <pre> @prefix ui: <http://lv2plug.in/ns/extensions/ui#> . @@ -57,25 +58,23 @@ files in an LV2 bundle. UIs are associated with a plugin in RDF using the tripl <http://my.pluginui> a ui:GtkUI ; ui:binary <myui.so> . </pre> -where <http://my.plugin> is the URI of the plugin, +<p>where <http://my.plugin> is the URI of the plugin, <http://my.pluginui> is the URI of the plugin UI and <myui.so> -is the relative URI to the shared object file. +is the relative URI to the shared object file.</p> -While it is possible to have the plugin UI and the plugin in the same shared +<p>While it is possible to have the plugin UI and the plugin in the same shared object file it is probably a good idea to keep them separate so that hosts that don't want UIs don't have to load the UI code. A UI MUST specify its class in the RDF data (ui:GtkUI in the above example). The class defines what type the UI is, e.g. what graphics toolkit it uses. Any type of UI class can -be defined separately from this extension. - -(Note: the prefix above is used throughout this file for the same URI) +be defined separately from this extension.</p> -It is possible to have multiple UIs for the same plugin, or to have the UI +<p>It is possible to have multiple UIs for the same plugin, or to have the UI for a plugin in a different bundle from the actual plugin - this way people other than the plugin author can write plugin UIs independently without -editing the original plugin bundle. +editing the original plugin bundle.</p> -Note that the process that loads the shared object file containing the UI +<p>Note that the process that loads the shared object file containing the UI code and the process that loads the shared object file containing the actual plugin implementation are not necessarily the same process (and not even necessarily on the same machine). This means that plugin and UI code can @@ -84,39 +83,39 @@ the same objects in the UI and the actual plugin. The function callback interface defined in this header is the only method of communication between UIs and plugin instances (extensions may define more, though this is discouraged unless absolutely necessary since the significant benefits of -network transparency and serialisability are lost). +network transparency and serialisability are lost).</p> -Since the LV2 specification itself allows for extensions that may add new +<p>Since the LV2 specification itself allows for extensions that may add new functionality that could be useful to control with a UI, this extension allows for meta-extensions that can extend the interface between the UI and the host. These extensions mirror the extensions used for plugins - there are -required and optional "features" that you declare in the RDF data for the UI as +required and optional "features" that you declare in the RDF data for the UI:</p> <pre> <http://my.pluginui> lv2:requiredFeature <http://my.feature> . <http://my.pluginui> lv2:optionalFeature <http://my.feature> . </pre> -The rules for a UI with a required or optional feature are identical to those +<p>The rules for a UI with a required or optional feature are identical to those of lv2:Plugin instances: if a UI declares a feature as required, the host is NOT allowed to load it unless it supports that feature; and if it does support a feature, it MUST pass an appropriate LV2_Feature struct to the UI's instantiate() method. These features may be used to specify how to pass specific types of data between the UI and the plugin port buffers -(see LV2UI_Write_Function for details). +(see LV2UI_Write_Function for details).</p> -UIs written to this specification do not need to be threadsafe - the +<p>UIs written to this specification do not need to be threadsafe - the functions defined below may only be called in the same thread the UI -main loop is running in. +main loop is running in.</p> -Note that this UI extension is NOT a lv2:Feature. There is no way for a +<p>Note that this UI extension is NOT a lv2:Feature. There is no way for a plugin to know whether the host that loads it supports UIs or not, and the plugin must always work without the UI (although it may be rather useless unless it has been configured using the UI in a previous session). From the plugin perspective, control from a UI is the same as control -from anywhere else (e.g. the host, the user): via ports. +from anywhere else (e.g. the host, the user): via ports.</p> -A UI does not have to be a graphical widget, it could just as well be a +<p>A UI does not have to be a graphical widget, it could just as well be a server listening for OSC input or an interface to some sort of hardware -device, depending on the RDF class of the UI. +device, depending on the RDF class of the UI.</p> """ . @@ -133,17 +132,17 @@ and the host guarantees that the Gtk+ library has been initialised and the Glib main loop is running before an UI of this type is instantiated.""" . ui:makeSONameResident a lv2:Feature ; - rdfs:comment """ -This feature is ELF specific - it should only be used by UIs that + lv2:documentation """ +<p>This feature is ELF specific - it should only be used by UIs that use the ELF file format for the UI shared object files (e.g. on Linux). If it is required by an UI the UI should also list a number of SO names (shared object names) for libraries that the UI shared object depends on and that may not be unloaded during the lifetime of the host -process, using the predicate @c ui:residentSONames, like this: +process, using the predicate @c ui:residentSONames, like this:</p> <pre> <http://my.pluginui> ui:residentSONames "libgtkmm-2.4.so.1", "libfoo.so.0" </pre> -The host MUST then make sure that the shared libraries with the given ELF +<p>The host MUST then make sure that the shared libraries with the given ELF SO names are not unloaded when the plugin UI is, but stay loaded during the entire lifetime of the host process. On Linux this can be accomplished by calling dlopen() on the shared library file with that SO name and never @@ -154,8 +153,8 @@ act as if the UI required the @c ui:makeResident feature instead. Thus the host only needs to find the shared library files corresponding to the given SO names if it wants to save RAM by unloading the UI shared object file when it is no longer needed. The data pointer for the LV2_Feature for -this feature should always be set to NULL. -"""^^lv2:basicXHTML . +this feature should always be set to NULL.</p> +""" . ui:noUserResize a lv2:Feature ; rdfs:comment """ diff --git a/extensions/units.lv2/units.ttl b/extensions/units.lv2/units.ttl index 52e20f6..4ce3ada 100644 --- a/extensions/units.lv2/units.ttl +++ b/extensions/units.lv2/units.ttl @@ -32,8 +32,8 @@ doap:created "2007-02-06" ; doap:homepage <http://lv2plug.in/ns/extensions/units> ; doap:release [ - doap:revision "5" ; - doap:created "2009-11-10" + doap:revision "5.1pre1" ; + doap:created "2010-10-29" ] ; doap:maintainer [ a foaf:Person ; @@ -48,10 +48,11 @@ foaf:name "David Robillard" ] ; doap:name "LV2 Units extension" ; - rdfs:comment """ -This extension defines a number of units for use in audio processing. + lv2:documentation """ +<p>This extension defines a number of units for use in audio processing.</p> -For example, to say that the port use the gain unit defined as units:db (decibels): +<p>For example, to say that the port use the gain unit defined as units:db +(decibels):</p> <pre> @prefix : <http://lv2plug.in/ns/extensions/units#> . @@ -65,8 +66,8 @@ lv2:port [ ] </pre> -Using the same form, plugins may also specify one-off units inline, to give -better display hints to hosts: +<p>Using the same form, plugins may also specify one-off units inline, to give +better display hints to hosts:</p> <pre> lv2:port [ a lv2:ControlRateInputPort ; @@ -82,8 +83,8 @@ lv2:port [ ] ] </pre> -Units are defined by a number of properties: +<p>Units are defined by a number of properties:</p> <dl> <dt>units:name</dt> <dd>A display name for the unit (eg. decibels)</dd> @@ -97,7 +98,7 @@ unit class (eg. units:conversion [ units:to units:m ; units:factor 1000 ]). conversions are expressed as either factors (multiplicand for the conversion) or offsets (addend for the conversion).</dd> </dl> -""" ^^ lv2:basicXHTML . +""" . units:Unit a rdfs:Class ; rdfs:comment "A unit for LV2 port data" . @@ -7,7 +7,7 @@ import glob import re import datetime -out_base = os.path.join('build', 'default', 'doc') +out_base = os.path.join('build', 'default', 'ns') try: shutil.rmtree(out_base) except: @@ -17,6 +17,7 @@ os.makedirs(out_base) URIPREFIX = 'http://lv2plug.in/ns/' SPECGENDIR = './specgen' +STYLEURI = os.path.join('aux', 'style.css') release_dir = os.path.join('build', 'default', 'spec') try: @@ -39,14 +40,13 @@ def gendoc(specgen_dir, bundle_dir, ttl_filename, html_filename): subprocess.call([os.path.join(specgen_dir, 'lv2specgen.py'), os.path.join(bundle_dir, ttl_filename), os.path.join(specgen_dir, 'template.html'), - os.path.join(specgen_dir, 'style.css'), + STYLEURI, os.path.join(out_base, html_filename), - os.path.join('..', 'doc'), + os.path.join('..', '..'), '-i']) gendoc('./lv2specgen', 'core.lv2', 'lv2.ttl', 'lv2core/lv2core.html') -style = open('./lv2specgen/style.css', 'r') footer = open('./lv2specgen/footer.html', 'r') # Generate main (ontology) documentation and indices @@ -61,16 +61,13 @@ for dir in ['ext', 'extensions']: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> -<meta http-equiv="Content-Type" content="application/xhtml+xml;charset=utf-8"/> +<meta http-equiv="Content-Type" content="application/xhtml+xml;charset=utf-8" /> <title>LV2 Extensions</title> -<style type="text/css"> -""" - - index_html += style.read() - - index_html += """ -</style></head> -<body><h1>LV2 Extensions</h1> +<link rel="stylesheet" type="text/css" href="../../""" + STYLEURI + """\" /> +</head> +<body> +<div id="titleheader"><h1 id="title">LV2 Extensions</h1></div> +<div class="content"> <h2>""" + URIPREFIX + dir + "/</h2><ul>\n" extensions = [] @@ -107,8 +104,8 @@ SELECT ?rev FROM <%s.lv2/%s.ttl> WHERE { <%s> doap:release [ doap:revision ?rev else: rev = '0' - if rev != '0': - path = os.path.join(os.path.abspath(release_dir), 'lv2-%s-%s.0.tar.gz' % (b, rev)) + if rev != '0' and rev.find('pre') == -1: + path = os.path.join(os.path.abspath(release_dir), 'lv2-%s-%s.tar.gz' % (b, rev)) subprocess.call(['tar', '--exclude-vcs', '-czf', path, bundle[bundle.find('/') + 1:]], cwd=dir) @@ -118,9 +115,9 @@ SELECT ?rev FROM <%s.lv2/%s.ttl> WHERE { <%s> doap:release [ doap:revision ?rev subprocess.call([specgendir + 'lv2specgen.py', '%s.lv2/%s.ttl' % (b, b), specgendir + 'template.html', - specgendir + 'style.css', + STYLEURI, '%s.lv2/%s.html' % (b, b), - os.path.join('..', '..', 'doc'), + os.path.join('..', '..', '..'), '-i'], cwd=outdir); li = '<li>' @@ -140,12 +137,12 @@ SELECT ?rev FROM <%s.lv2/%s.ttl> WHERE { <%s> doap:release [ doap:revision ?rev for i in extensions: index_html += i + '\n' - index_html += '</ul>\n' + index_html += '</ul>\n</div>\n' - index_html += '<div class="footer">' + index_html += '<div id="footer">' index_html += '<span class="footer-text">Generated on ' index_html += datetime.datetime.utcnow().strftime('%F %H:%M UTC') - index_html += ' by LV2 gendoc.py</span>' + index_html += ' by gendoc.py</span> ' index_html += footer.read() + '</div>' index_html += '</body></html>\n' @@ -154,6 +151,13 @@ SELECT ?rev FROM <%s.lv2/%s.ttl> WHERE { <%s> doap:release [ doap:revision ?rev print >>index_file, index_html index_file.close() +# Copy stylesheet +try: + os.mkdir(os.path.join('build', 'default', 'aux')) +except: + pass +shutil.copy('lv2specgen/style.css', os.path.join('build', 'default', STYLEURI)) + # Generate code (headers) documentation print "** Generating header documentation" #shutil.copy('Doxyfile', os.path.join('upload', 'Doxyfile')) @@ -161,5 +165,4 @@ print ' * Calling doxygen in ' + os.getcwd() subprocess.call('doxygen', stdout=devnull) devnull.close() -style.close() footer.close() diff --git a/lv2specgen/lv2specgen.py b/lv2specgen/lv2specgen.py index 8fc1f93..914b774 100755 --- a/lv2specgen/lv2specgen.py +++ b/lv2specgen/lv2specgen.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # # lv2specgen, an LV2 extension specification page generator -# Copyright (c) 2009 David Robillard <d@drobilla.net> +# Copyright (c) 2009-2010 David Robillard <d@drobilla.net> # # Based on SpecGen: # <http://forge.morfeo-project.org/wiki_en/index.php/SpecGen> @@ -41,6 +41,7 @@ import sys import datetime import re import urllib +import xml.sax.saxutils try: import RDF @@ -85,6 +86,7 @@ lv2 = RDF.NS('http://lv2plug.in/ns/lv2core#') doap = RDF.NS('http://usefulinc.com/ns/doap#') foaf = RDF.NS('http://xmlns.com/foaf/0.1/') +doc_base = '.' def niceName(uri): regexp = re.compile( "^(.*[/#])([^/#]+)$" ) @@ -102,20 +104,39 @@ def return_name(m, urinode): "Trims the namespace out of a term to give a name to the term." return str(urinode.uri).replace(spec_ns_str, "") - -def get_rdfs(m, urinode): - "Returns label and comment given an RDF.Node with a URI in it" - comment = '' - label = '' - if (type(urinode)==str): +def getLabel(m, urinode): + if (type(urinode) == str): urinode = RDF.Uri(urinode) l = m.find_statements(RDF.Statement(urinode, rdfs.label, None)) if l.current(): - label = l.current().object.literal_value['string'] + return l.current().object.literal_value['string'] + else: + return '' + +def getComment(m, urinode): + if (type(urinode) == str): + urinode = RDF.Uri(urinode) + c = m.find_statements(RDF.Statement(urinode, lv2.documentation, None)) + if c.current(): + markup = c.current().object.literal_value['string'] + + # Replace urn:struct links with links to code documentation + matches = re.findall('href="urn:struct:([^"]*)"', markup) + if matches: + for match in matches: + struct_uri = os.path.join(doc_base, 'ns', 'doc', 'html', + 'struct' + match.replace('_', '__') + '.html') + markup = markup.replace('href="urn:struct:' + match + '"', + 'href="' + struct_uri + '"') + + return markup + c = m.find_statements(RDF.Statement(urinode, rdfs.comment, None)) if c.current(): - comment = c.current().object.literal_value['string'] - return label, comment + text = c.current().object.literal_value['string'] + return xml.sax.saxutils.escape(text) + + return '' def owlVersionInfo(m): @@ -242,12 +263,12 @@ def rdfsClassInfo(term,m): doc += '<dt>Restriction on property %s</dt>\n' % getTermLink(onProp.uri) doc += '<dd class="restriction">\n' if comment != None: - doc += "<p>%s</p>\n" % comment + doc += "<span>%s</span>\n" % comment.literal_value['string'] prop_str = '' for p in m.find_statements(RDF.Statement(r, None, None)): if p.predicate != owl.onProperty and p.predicate != rdfs.comment and not( - p.predicate == rdf.type and p.object == owl.Restriction): + p.predicate == rdf.type and p.object == owl.Restriction) and p.predicate != lv2.documentation: if p.object.is_resource(): prop_str += '\n<dt>%s</dt><dd>%s</dd>\n' % ( getTermLink(p.predicate.uri), getTermLink(p.object.uri)) @@ -279,7 +300,7 @@ def rdfsClassInfo(term,m): def isSpecial(pred): """Return True if the predicate is "special" and shouldn't be emitted generically""" - return pred == rdf.type or pred == rdfs.range or pred == rdfs.domain or pred == rdfs.label or pred == rdfs.comment or pred == rdfs.subClassOf + return pred in [rdf.type, rdfs.range, rdfs.domain, rdfs.label, rdfs.comment, rdfs.subClassOf, lv2.documentation] def blankNodeDesc(node,m): @@ -399,22 +420,21 @@ def docTerms(category, list, m): doc += """<div class="specterm" id="%s" about="%s">\n<h3>%s <a href="%s">%s</a></h3>\n""" % (t, term_uri, category, term_uri, curie) - label, comment = get_rdfs(m, term) + label = getLabel(m, term) + comment = getComment(m, term) + if label!='' or comment != '': doc += '<div class="description">' + if label!='': doc += "<div property=\"rdfs:label\" class=\"label\">%s</div>" % label + if comment!='': - comment = comment.replace('\n\n', '<br /><br />') - matches = re.findall('href="urn:struct:([^"]*)"', comment) - if matches: - for match in matches: - struct_uri = "../../doc/html/struct" + match.replace('_', '__') + '.html' - comment = comment.replace('href="urn:struct:' + match + '"', - 'href="' + struct_uri + '"') doc += "<div property=\"rdfs:comment\">%s</div>" % comment + if label!='' or comment != '': doc += "</div>" + terminfo = "" if category=='Property': terminfo += owlInfo(term,m) @@ -628,7 +648,7 @@ def specgen(specloc, docdir, template, instances=False, mode="spec"): global spec_ns global spec_pre global ns_list - + m = RDF.Model() p = RDF.Parser(name="guess") try: @@ -713,7 +733,7 @@ def specgen(specloc, docdir, template, instances=False, mode="spec"): template = template.replace('@MAIL@', 'devel@lists.lv2plug.in') revision = specRevision(m, spec_url) # (revision, date) - if revision: + if revision and revision[0] != '0': template = template.replace('@REVISION@', revision[0] + " (" + revision[1] + ")") else: template = template.replace('@REVISION@', '<span style="color: red; font-weight: bold">EXPERIMENTAL</span>') @@ -726,7 +746,7 @@ def specgen(specloc, docdir, template, instances=False, mode="spec"): release_name = "lv2-" + basename if basename == "lv2": release_name = "lv2core" - other_files += '<li><a href="http://lv2plug.in/spec/%s-%s.0.tar.gz">Release</a> (<a href="http://lv2plug.in/spec">all releases</a>)</li>\n' % (release_name, revision[0]) + other_files += '<li><a href="http://lv2plug.in/spec/%s-%s.tar.gz">Release</a> (<a href="http://lv2plug.in/spec">all releases</a>)</li>\n' % (release_name, revision[0]) if os.path.exists(os.path.abspath(header_path)): other_files += '<li><a href="' + docdir + '/html/%s">Header Documentation</a></li>\n' % ( basename + '_8h.html') @@ -737,16 +757,19 @@ def specgen(specloc, docdir, template, instances=False, mode="spec"): see_also_files = specProperties(m, spec_url, rdfs.seeAlso) for f in see_also_files: - other_files += '<li><a href="%s">%s</a></li>' % (f, f) + uri = str(f.uri) + if uri[0:5] == 'file:': + uri = uri[5:] + + other_files += '<li><a href="%s">%s</a></li>' % (uri, uri) template = template.replace('@FILES@', other_files); - comment = specProperty(m, spec_url, rdfs.comment) - if not comment: - comment = specProperty(m, spec_url, doap.shortdesc) - #template = template.replace('@COMMENT@', '<p>' + comment.strip().replace('\n\n', '</p><p>') + '</p>') - template = template.replace('@COMMENT@', comment.strip().replace('\n\n', '<br /><br />')) - #template = template.replace('@COMMENT@', comment) + comment = getComment(m, spec_url) + if comment != '': + template = template.replace('@COMMENT@', comment) + else: + template = template.replace('@COMMENT@', '') template = template.replace('@TIME@', datetime.datetime.utcnow().strftime('%F %H:%M UTC')) @@ -800,7 +823,7 @@ def usage(): TEMPLATE : HTML template path STYLE : CSS style path OUTPUT : HTML output path - DOCDIR : Doxygen documentation directory + BASE : Documentation output base URI Optional flags: -i : Document class/property instances (disabled by default) @@ -846,22 +869,17 @@ if __name__ == "__main__": template = template.replace('@FOOTER@', footer) # Style - styleloc = args[2] - style = '' - try: - f = open(styleloc, "r") - style = f.read() - except Exception, e: - print "Error reading from style \"" + styleloc + "\": " + str(e) - usage() - - template = template.replace('@STYLE@', style) + style_uri = args[2] # Destination dest = args[3] # Doxygen documentation directory - docdir = args[4] + doc_base = args[4] + + template = template.replace('@STYLE_URI@', os.path.join(doc_base, style_uri)) + + docdir = os.path.join(doc_base, 'ns', 'doc') # Flags instances = False diff --git a/lv2specgen/template.html b/lv2specgen/template.html index 3f4cff4..d4d76e0 100644 --- a/lv2specgen/template.html +++ b/lv2specgen/template.html @@ -12,32 +12,31 @@ <title>@NAME@</title> <meta http-equiv="content-type" content="text/xhtml+xml; charset=utf-8" /> <meta name="generator" content="lv2specgen" /> - <style type="text/css"> -@STYLE@ - </style> + <link href="@STYLE_URI@" rel="stylesheet" type="text/css" /> </head> <body> - <h1 id="title">@NAME@</h1> - <div class="meta"> - <table> - <tr><th class="metahead">URI</th><td><a href="@URI@">@URI@</a></td></tr> - <tr><th class="metahead">Revision</th><td>@REVISION@</td></tr> - <tr><th class="metahead">Namespaces</th><td>@PREFIXES@</td></tr> - @AUTHORS@ - </table> + <div id="titleheader"> + <h1 id="title">@NAME@</h1> + <div class="meta"> + <table> + <tr><th class="metahead">URI</th><td><a href="@URI@">@URI@</a></td></tr> + <tr><th class="metahead">Revision</th><td>@REVISION@</td></tr> + <tr><th class="metahead">Namespaces</th><td>@PREFIXES@</td></tr> + @AUTHORS@ + </table> + </div> </div> - <!-- META --> <div class="content"> - <p>This document describes <a href="@URI@">@NAME@</a>, - an <a href="http://lv2plug.in/">LV2</a> related specification. - Comments are welcome, please direct discussion to <a + <p>This document is generated from <a href="@FILENAME@">@FILENAME@</a>, which + describes <a href="@URI@">@NAME@</a> (an <a href="http://lv2plug.in/">LV2</a> + specification). Comments are welcome, please direct discussion to <a href="mailto:@MAIL@">@MAIL@</a>.</p> </div> - <h2 id="contents">Contents</h2> + <h2 class="sec" id="contents">Contents</h2> <div class="content"> <h3>This Document</h3> <ol id="toc"> @@ -55,13 +54,13 @@ <!-- DESCRIPTION --> - <h2 id="sec-description">1. Description</h2> + <h2 class="sec" id="sec-description">1. Description</h2> <div class="content">@COMMENT@</div> <!-- INDEX --> - <h2 id="sec-index">2. Index</h2> + <h2 class="sec" id="sec-index">2. Index</h2> <div class="content"> @INDEX@ </div> @@ -69,14 +68,14 @@ <!-- REFERENCE --> - <h2 id="sec-documentation">3. Documentation</h2> + <h2 class="sec" id="sec-documentation">3. Documentation</h2> <div class="content"> @REFERENCE@ </div> <!-- REFERENCES --> - <h2 id="sec-references">4. References</h2> + <h2 class="sec" id="sec-references">4. References</h2> <div class="content"> <dl> <dt class="label" id="ref-rfc2119">IETF RFC 2119</dt> @@ -92,7 +91,7 @@ <!-- FOOTER --> - <div class="footer"> + <div id="footer"> <span class="footer-text">Generated on @TIME@ from <a href="./@FILENAME@" class="footer-text">@FILENAME@</a> by <a href="http://drobilla.net/software/lv2specgen" class="footer-text">lv2specgen</a></span> @FOOTER@ </div> @@ -20,6 +20,8 @@ def set_options(opt): opt.tool_options('compiler_cxx') def configure(conf): + autowaf.set_recursive() + conf.sub_config('core.lv2'); autowaf.configure(conf) conf.check_tool('compiler_cc') conf.check_tool('compiler_cxx') @@ -65,6 +67,7 @@ def build_extension(bld, name, dir): bld.install_files('${LV2DIR}/' + name + '.lv2', header_files) def build(bld): + autowaf.set_recursive() ext = ''' atom contexts |