update documentation
This commit is contained in:
parent
efd75b7a54
commit
4f5e3f5cea
|
@ -361,6 +361,148 @@ In case of <code>buttonA</code> the end-user will be teleported to another locat
|
|||
Also, after lazy-loading <code>ocean.com/aquarium.gltf</code>, only the queried objects <code>bass</code> and <code>tuna</code> will be instanced inside <code>aquariumcube</code>.<br>
|
||||
Resizing will be happen accordingly to its placeholder object <code>aquariumcube</code>, see chapter Scaling.<br></p>
|
||||
|
||||
<h1 id="xr-fragment-queries">XR Fragment queries</h1>
|
||||
|
||||
<p>Include, exclude, hide/shows objects using space-separated strings:</p>
|
||||
|
||||
<ul>
|
||||
<li><code>#q=cube</code></li>
|
||||
<li><code>#q=cube -ball_inside_cube</code></li>
|
||||
<li><code>#q=* -sky</code></li>
|
||||
<li><code>#q=-.language .english</code></li>
|
||||
<li><code>#q=cube&rot=0,90,0</code></li>
|
||||
<li><code>#q=price:>2 price:<5</code></li>
|
||||
</ul>
|
||||
|
||||
<p>It’s simple but powerful syntax which allows <b>css</b>-like class/id-selectors with a searchengine prompt-style feeling:</p>
|
||||
|
||||
<ol>
|
||||
<li>queries are showing/hiding objects <strong>only</strong> when defined as <code>src</code> value (prevents sharing of scene-tampered URL’s).</li>
|
||||
<li>queries are highlighting objects when defined in the top-Level (browser) URL (bar).</li>
|
||||
<li>search words like <code>cube</code> and <code>foo</code> in <code>#q=cube foo</code> are matched against 3D object names or custom metadata-key(values)</li>
|
||||
<li>search words like <code>cube</code> and <code>foo</code> in <code>#q=cube foo</code> are matched against tags (BibTeX) inside plaintext <code>src</code> values like <code>@cube{redcube, ...</code> e.g.</li>
|
||||
<li><code>#</code> equals <code>#q=*</code></li>
|
||||
<li>words starting with <code>.</code> like <code>.german</code> match class-metadata of 3D objects like <code>"class":"german"</code></li>
|
||||
<li>words starting with <code>.</code> like <code>.german</code> match class-metadata of (BibTeX) tags in XR Text objects like <code>@german{KarlHeinz, ...</code> e.g.</li>
|
||||
</ol>
|
||||
|
||||
<blockquote>
|
||||
<p><strong>For example</strong>: <code>#q=.foo</code> is a shorthand for <code>#q=class:foo</code>, which will select objects with custom property <code>class</code>:<code>foo</code>. Just a simple <code>#q=cube</code> will simply select an object named <code>cube</code>.</p>
|
||||
</blockquote>
|
||||
|
||||
<ul>
|
||||
<li>see <a href="https://coderofsalvation.github.io/xrfragment.media/queries.mp4">an example video here</a></li>
|
||||
</ul>
|
||||
|
||||
<h2 id="including-excluding">including/excluding</h2>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>operator</th>
|
||||
<th>info</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>*</code></td>
|
||||
<td>select all objects (only useful in <code>src</code> custom property)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>-</code></td>
|
||||
<td>removes/hides object(s)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>:</code></td>
|
||||
<td>indicates an object-embedded custom property key/value</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>.</code></td>
|
||||
<td>alias for <code>"class" :".foo"</code> equals <code>class:foo</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>></code> <code><</code></td>
|
||||
<td>compare float or int number</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>/</code></td>
|
||||
<td>reference to root-scene.<br>Useful in case of (preventing) showing/hiding objects in nested scenes (instanced by <code>src</code>) (*)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<blockquote>
|
||||
<p>* = <code>#q=-/cube</code> hides object <code>cube</code> only in the root-scene (not nested <code>cube</code> objects)<br> <code>#q=-cube</code> hides both object <code>cube</code> in the root-scene <b>AND</b> nested <code>skybox</code> objects |</p>
|
||||
</blockquote>
|
||||
|
||||
<p><a href="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/q.js">» example implementation</a>
|
||||
<a href="https://github.com/coderofsalvation/xrfragment/blob/main/example/assets/query.gltf#L192">» example 3D asset</a>
|
||||
<a href="https://github.com/coderofsalvation/xrfragment/issues/3">» discussion</a></p>
|
||||
|
||||
<h2 id="query-parser">Query Parser</h2>
|
||||
|
||||
<p>Here’s how to write a query parser:</p>
|
||||
|
||||
<ol>
|
||||
<li>create an associative array/object to store query-arguments as objects</li>
|
||||
<li>detect object id’s & properties <code>foo:1</code> and <code>foo</code> (reference regex: <code>/^.*:[><=!]?/</code> )</li>
|
||||
<li>detect excluders like <code>-foo</code>,<code>-foo:1</code>,<code>-.foo</code>,<code>-/foo</code> (reference regex: <code>/^-/</code> )</li>
|
||||
<li>detect root selectors like <code>/foo</code> (reference regex: <code>/^[-]?\//</code> )</li>
|
||||
<li>detect class selectors like <code>.foo</code> (reference regex: <code>/^[-]?class$/</code> )</li>
|
||||
<li>detect number values like <code>foo:1</code> (reference regex: <code>/^[0-9\.]+$/</code> )</li>
|
||||
<li>expand aliases like <code>.foo</code> into <code>class:foo</code></li>
|
||||
<li>for every query token split string on <code>:</code></li>
|
||||
<li>create an empty array <code>rules</code></li>
|
||||
<li>then strip key-operator: convert “-foo” into “foo”</li>
|
||||
<li>add operator and value to rule-array</li>
|
||||
<li>therefore we we set <code>id</code> to <code>true</code> or <code>false</code> (false=excluder <code>-</code>)</li>
|
||||
<li>and we set <code>root</code> to <code>true</code> or <code>false</code> (true=<code>/</code> root selector is present)</li>
|
||||
<li>we convert key ‘/foo’ into ‘foo’</li>
|
||||
<li>finally we add the key/value to the store like <code>store.foo = {id:false,root:true}</code> e.g.</li>
|
||||
</ol>
|
||||
|
||||
<blockquote>
|
||||
<p>An example query-parser (which compiles to many languages) can be <a href="https://github.com/coderofsalvation/xrfragment/blob/main/src/xrfragment/Query.hx">found here</a></p>
|
||||
</blockquote>
|
||||
|
||||
<h2 id="xr-fragment-uri-grammar">XR Fragment URI Grammar</h2>
|
||||
|
||||
<pre><code>reserved = gen-delims / sub-delims
|
||||
gen-delims = "#" / "&"
|
||||
sub-delims = "," / "="
|
||||
</code></pre>
|
||||
|
||||
<blockquote>
|
||||
<p>Example: <code>://foo.com/my3d.gltf#pos=1,0,0&prio=-5&t=0,100</code></p>
|
||||
</blockquote>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Demo</th>
|
||||
<th>Explanation</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>pos=1,2,3</code></td>
|
||||
<td>vector/coordinate argument e.g.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>pos=1,2,3&rot=0,90,0&q=.foo</code></td>
|
||||
<td>combinators</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h1 id="text-in-xr-tagging-linking-to-spatial-objects">Text in XR (tagging,linking to spatial objects)</h1>
|
||||
|
||||
<p>We still think and speak in simple text, not in HTML or RDF.<br>
|
||||
|
@ -496,7 +638,7 @@ To keep XR Fragments a lightweight spec, BibTeX is used for text/spatial tagging
|
|||
| │ └ src: ://author.com/article.txt | | |
|
||||
| │ | | @friend{friends |
|
||||
| └── ◻ note_canvas | | ... |
|
||||
| └ src:`data:welcome human @...` | | } |
|
||||
| └ src:`data:welcome human\n@...` | | } |
|
||||
| | +------------------------+
|
||||
| |
|
||||
+--------------------------------------------------------------+
|
||||
|
@ -507,40 +649,43 @@ The beauty is that text (AND visual-meta) in Data URI promotes rich copy-paste.
|
|||
In both cases, the text gets rendered immediately (onto a plane geometry, hence the name ‘_canvas’).
|
||||
The XR Fragment-compatible browser can let the enduser access visual-meta(data)-fields after interacting with the object (contextmenu e.g.).</p>
|
||||
|
||||
<p>The mapping between 3D objects and text (src-data) is simple:</p>
|
||||
<blockquote>
|
||||
<p>additional tagging using <a href="https://github.com/coderofsalvation/tagbibs">bibs</a>: to tag spatial object <code>note_canvas</code> with ‘todo’, the enduser can type or speak <code>@note_canvas@todo</code></p>
|
||||
</blockquote>
|
||||
|
||||
<p>The mapping between 3D objects and text (src-data) is simple (the :</p>
|
||||
|
||||
<p>Example:</p>
|
||||
|
||||
<pre><code> +------------------------------------------------------------------------------------+
|
||||
| |
|
||||
| index.gltf |
|
||||
| │ |
|
||||
| └── ◻ rentalhouse |
|
||||
| └ class: house |
|
||||
| └ ◻ note |
|
||||
| └ src:`data: todo: call owner |
|
||||
| @house{owner, |
|
||||
| url = {#.house} |
|
||||
| }` |
|
||||
+------------------------------------------------------------------------------------+
|
||||
<pre><code> +------------------------------------------------+
|
||||
| |
|
||||
| index.gltf |
|
||||
| │ |
|
||||
| └── ◻ rentalhouse |
|
||||
| └ class: house <----------------- matches -------+
|
||||
| └ ◻ note | |
|
||||
| └ src:`data: todo: call owner | bib |
|
||||
| @owner@house@todo | ----> expands to @house{owner,
|
||||
| | bibtex: }
|
||||
| ` | @contact{
|
||||
+------------------------------------------------+ }
|
||||
</code></pre>
|
||||
|
||||
<p>3D object names and/or classes map to <code>name</code> of visual-meta glossary-entries.
|
||||
This allows rich interaction and interlinking between text and 3D objects:</p>
|
||||
<p>Bi-directional mapping between 3D object names and/or classnames and text using bibs,BibTags & XR Fragments, allows for rich interlinking between text and 3D objects:</p>
|
||||
|
||||
<ol>
|
||||
<li>When the user surfs to https://…/index.gltf#rentalhouse the XR Fragments-parser points the enduser to the rentalhouse object, and can show contextual info about it.</li>
|
||||
<li>When (partial) remote content is embedded thru XR Fragment queries (see XR Fragment queries), indirectly related metadata can be embedded along.</li>
|
||||
</ol>
|
||||
|
||||
<h2 id="bibs-enabled-bibtex-lowest-common-denominator-for-tagging-triples">Bibs-enabled BibTeX: lowest common denominator for tagging/triples</h2>
|
||||
<h2 id="bibs-bibtex-lowest-common-denominator-for-linking-data">Bibs & BibTeX: lowest common denominator for linking data</h2>
|
||||
|
||||
<blockquote>
|
||||
<p>“When a car breaks down, the ones <strong>without</strong> turbosupercharger are easier to fix”</p>
|
||||
</blockquote>
|
||||
|
||||
<p>Unlike XML or JSON, the typeless, unnested, everything-is-text nature of BibTeX tags is a great advantage for introspection.<br>
|
||||
It’s a missing sensemaking precursor to (eventual) extrospective RDF.<br>
|
||||
It’s a missing sensemaking precursor to extrospective RDF.<br>
|
||||
BibTeX-appendices are already used in the digital AND physical world (academic books, <a href="https://visual-meta.info">visual-meta</a>), perhaps due to its terseness & simplicity.<br>
|
||||
In that sense, it’s one step up from the <code>.ini</code> fileformat (which has never leaked into the physical world like BibTex):</p>
|
||||
|
||||
|
@ -584,7 +729,7 @@ In that sense, it’s one step up from the <code>.ini</code> fileformat (whi
|
|||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>paperfriendly</td>
|
||||
<td>voice/paper-friendly</td>
|
||||
<td><a href="https://github.com/coderofsalvation/tagbibs">bibs</a></td>
|
||||
<td>no</td>
|
||||
</tr>
|
||||
|
@ -750,7 +895,7 @@ In that sense, it’s one step up from the <code>.ini</code> fileformat (whi
|
|||
}
|
||||
</code></pre>
|
||||
|
||||
<p>The above (de)multiplexes text/metadata, expands bibs, (de)serializes bibtex (and all fits more or less on one A4 paper)</p>
|
||||
<p>The above functions (de)multiplexe text/metadata, expands bibs, (de)serialize bibtex (and all fits more or less on one A4 paper)</p>
|
||||
|
||||
<blockquote>
|
||||
<p>above can be used as a startingpoint for LLVM’s to translate/steelman to a more formal form/language.</p>
|
||||
|
@ -771,35 +916,26 @@ tags.push({ k:'bar{', v:{abc:123} }) // add tag
|
|||
console.log( xrtext.encode(text,tags) ) // multiplex text & bibtex back together
|
||||
</code></pre>
|
||||
|
||||
<pre><code>@{references-start}
|
||||
@misc{emilyHegland/Edgar&Frod,
|
||||
author = {Emily Hegland},
|
||||
title = {Edgar & Frode Hegland, November 2021},
|
||||
year = {2021},
|
||||
month = {11},
|
||||
}
|
||||
</code></pre>
|
||||
<p>This outputs:</p>
|
||||
|
||||
<p>The above BibTeX-flavor can be imported, however will be rewritten to Dumb BibTeX, to satisfy rule 2 & 5, as well as the <a href="#core-principle">core principle</a></p>
|
||||
<pre><code>hello world
|
||||
|
||||
<pre><code>@visual-meta{
|
||||
version = {1.1},
|
||||
generator = {Author 7.6.2 (1064)},
|
||||
section = {visual-meta-header}
|
||||
|
||||
@greeting{hello,
|
||||
}
|
||||
@misc{emilyHegland/Edgar&Frod,
|
||||
author = {Emily Hegland},
|
||||
title = {Edgar & Frode Hegland, November 2021},
|
||||
year = {2021},
|
||||
month = {11},
|
||||
section = {references}
|
||||
@{some-section}
|
||||
@flap{
|
||||
asdf = {1}
|
||||
}
|
||||
@bar{
|
||||
abc = {123}
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
<h1 id="hyper-copy-paste">HYPER copy/paste</h1>
|
||||
|
||||
<p>The previous example, offers something exciting compared to simple copy/paste of 3D objects or text.
|
||||
XR Fragment allows HYPER-copy/paste: time, space and text interlinked.
|
||||
XR Text according to the XR Fragment spec, allows HYPER-copy/paste: time, space and text interlinked.
|
||||
Therefore, the enduser in an XR Fragment-compatible browser can copy/paste/share data in these ways:</p>
|
||||
|
||||
<ol>
|
||||
|
@ -808,148 +944,6 @@ Therefore, the enduser in an XR Fragment-compatible browser can copy/paste/share
|
|||
<li>interlinked: Collected objects by visual-meta tag</li>
|
||||
</ol>
|
||||
|
||||
<h1 id="xr-fragment-queries">XR Fragment queries</h1>
|
||||
|
||||
<p>Include, exclude, hide/shows objects using space-separated strings:</p>
|
||||
|
||||
<ul>
|
||||
<li><code>#q=cube</code></li>
|
||||
<li><code>#q=cube -ball_inside_cube</code></li>
|
||||
<li><code>#q=* -sky</code></li>
|
||||
<li><code>#q=-.language .english</code></li>
|
||||
<li><code>#q=cube&rot=0,90,0</code></li>
|
||||
<li><code>#q=price:>2 price:<5</code></li>
|
||||
</ul>
|
||||
|
||||
<p>It’s simple but powerful syntax which allows <b>css</b>-like class/id-selectors with a searchengine prompt-style feeling:</p>
|
||||
|
||||
<ol>
|
||||
<li>queries are showing/hiding objects <strong>only</strong> when defined as <code>src</code> value (prevents sharing of scene-tampered URL’s).</li>
|
||||
<li>queries are highlighting objects when defined in the top-Level (browser) URL (bar).</li>
|
||||
<li>search words like <code>cube</code> and <code>foo</code> in <code>#q=cube foo</code> are matched against 3D object names or custom metadata-key(values)</li>
|
||||
<li>search words like <code>cube</code> and <code>foo</code> in <code>#q=cube foo</code> are matched against tags (BibTeX) inside plaintext <code>src</code> values like <code>@cube{redcube, ...</code> e.g.</li>
|
||||
<li><code>#</code> equals <code>#q=*</code></li>
|
||||
<li>words starting with <code>.</code> like <code>.german</code> match class-metadata of 3D objects like <code>"class":"german"</code></li>
|
||||
<li>words starting with <code>.</code> like <code>.german</code> match class-metadata of (BibTeX) tags in XR Text objects like <code>@german{KarlHeinz, ...</code> e.g.</li>
|
||||
</ol>
|
||||
|
||||
<blockquote>
|
||||
<p><strong>For example</strong>: <code>#q=.foo</code> is a shorthand for <code>#q=class:foo</code>, which will select objects with custom property <code>class</code>:<code>foo</code>. Just a simple <code>#q=cube</code> will simply select an object named <code>cube</code>.</p>
|
||||
</blockquote>
|
||||
|
||||
<ul>
|
||||
<li>see <a href="https://coderofsalvation.github.io/xrfragment.media/queries.mp4">an example video here</a></li>
|
||||
</ul>
|
||||
|
||||
<h2 id="including-excluding">including/excluding</h2>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>operator</th>
|
||||
<th>info</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>*</code></td>
|
||||
<td>select all objects (only useful in <code>src</code> custom property)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>-</code></td>
|
||||
<td>removes/hides object(s)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>:</code></td>
|
||||
<td>indicates an object-embedded custom property key/value</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>.</code></td>
|
||||
<td>alias for <code>"class" :".foo"</code> equals <code>class:foo</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>></code> <code><</code></td>
|
||||
<td>compare float or int number</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>/</code></td>
|
||||
<td>reference to root-scene.<br>Useful in case of (preventing) showing/hiding objects in nested scenes (instanced by <code>src</code>) (*)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<blockquote>
|
||||
<p>* = <code>#q=-/cube</code> hides object <code>cube</code> only in the root-scene (not nested <code>cube</code> objects)<br> <code>#q=-cube</code> hides both object <code>cube</code> in the root-scene <b>AND</b> nested <code>skybox</code> objects |</p>
|
||||
</blockquote>
|
||||
|
||||
<p><a href="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/q.js">» example implementation</a>
|
||||
<a href="https://github.com/coderofsalvation/xrfragment/blob/main/example/assets/query.gltf#L192">» example 3D asset</a>
|
||||
<a href="https://github.com/coderofsalvation/xrfragment/issues/3">» discussion</a></p>
|
||||
|
||||
<h2 id="query-parser">Query Parser</h2>
|
||||
|
||||
<p>Here’s how to write a query parser:</p>
|
||||
|
||||
<ol>
|
||||
<li>create an associative array/object to store query-arguments as objects</li>
|
||||
<li>detect object id’s & properties <code>foo:1</code> and <code>foo</code> (reference regex: <code>/^.*:[><=!]?/</code> )</li>
|
||||
<li>detect excluders like <code>-foo</code>,<code>-foo:1</code>,<code>-.foo</code>,<code>-/foo</code> (reference regex: <code>/^-/</code> )</li>
|
||||
<li>detect root selectors like <code>/foo</code> (reference regex: <code>/^[-]?\//</code> )</li>
|
||||
<li>detect class selectors like <code>.foo</code> (reference regex: <code>/^[-]?class$/</code> )</li>
|
||||
<li>detect number values like <code>foo:1</code> (reference regex: <code>/^[0-9\.]+$/</code> )</li>
|
||||
<li>expand aliases like <code>.foo</code> into <code>class:foo</code></li>
|
||||
<li>for every query token split string on <code>:</code></li>
|
||||
<li>create an empty array <code>rules</code></li>
|
||||
<li>then strip key-operator: convert “-foo” into “foo”</li>
|
||||
<li>add operator and value to rule-array</li>
|
||||
<li>therefore we we set <code>id</code> to <code>true</code> or <code>false</code> (false=excluder <code>-</code>)</li>
|
||||
<li>and we set <code>root</code> to <code>true</code> or <code>false</code> (true=<code>/</code> root selector is present)</li>
|
||||
<li>we convert key ‘/foo’ into ‘foo’</li>
|
||||
<li>finally we add the key/value to the store like <code>store.foo = {id:false,root:true}</code> e.g.</li>
|
||||
</ol>
|
||||
|
||||
<blockquote>
|
||||
<p>An example query-parser (which compiles to many languages) can be <a href="https://github.com/coderofsalvation/xrfragment/blob/main/src/xrfragment/Query.hx">found here</a></p>
|
||||
</blockquote>
|
||||
|
||||
<h2 id="xr-fragment-uri-grammar">XR Fragment URI Grammar</h2>
|
||||
|
||||
<pre><code>reserved = gen-delims / sub-delims
|
||||
gen-delims = "#" / "&"
|
||||
sub-delims = "," / "="
|
||||
</code></pre>
|
||||
|
||||
<blockquote>
|
||||
<p>Example: <code>://foo.com/my3d.gltf#pos=1,0,0&prio=-5&t=0,100</code></p>
|
||||
</blockquote>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Demo</th>
|
||||
<th>Explanation</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>pos=1,2,3</code></td>
|
||||
<td>vector/coordinate argument e.g.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>pos=1,2,3&rot=0,90,0&q=.foo</code></td>
|
||||
<td>combinators</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h1 id="security-considerations">Security Considerations</h1>
|
||||
|
||||
<p>Since XR Text contains metadata too, the user should be able to set up tagging-rules, so the copy-paste feature can :</p>
|
||||
|
|
|
@ -221,6 +221,85 @@ An XR Fragment-compatible browser viewing this scene, lazy-loads and projects `p
|
|||
Also, after lazy-loading `ocean.com/aquarium.gltf`, only the queried objects `bass` and `tuna` will be instanced inside `aquariumcube`.<br>
|
||||
Resizing will be happen accordingly to its placeholder object `aquariumcube`, see chapter Scaling.<br>
|
||||
|
||||
# XR Fragment queries
|
||||
|
||||
Include, exclude, hide/shows objects using space-separated strings:
|
||||
|
||||
* `#q=cube`
|
||||
* `#q=cube -ball_inside_cube`
|
||||
* `#q=* -sky`
|
||||
* `#q=-.language .english`
|
||||
* `#q=cube&rot=0,90,0`
|
||||
* `#q=price:>2 price:<5`
|
||||
|
||||
It's simple but powerful syntax which allows <b>css</b>-like class/id-selectors with a searchengine prompt-style feeling:
|
||||
|
||||
1. queries are showing/hiding objects **only** when defined as `src` value (prevents sharing of scene-tampered URL's).
|
||||
1. queries are highlighting objects when defined in the top-Level (browser) URL (bar).
|
||||
1. search words like `cube` and `foo` in `#q=cube foo` are matched against 3D object names or custom metadata-key(values)
|
||||
1. search words like `cube` and `foo` in `#q=cube foo` are matched against tags (BibTeX) inside plaintext `src` values like `@cube{redcube, ...` e.g.
|
||||
1. `#` equals `#q=*`
|
||||
1. words starting with `.` like `.german` match class-metadata of 3D objects like `"class":"german"`
|
||||
1. words starting with `.` like `.german` match class-metadata of (BibTeX) tags in XR Text objects like `@german{KarlHeinz, ...` e.g.
|
||||
|
||||
> **For example**: `#q=.foo` is a shorthand for `#q=class:foo`, which will select objects with custom property `class`:`foo`. Just a simple `#q=cube` will simply select an object named `cube`.
|
||||
|
||||
* see [an example video here](https://coderofsalvation.github.io/xrfragment.media/queries.mp4)
|
||||
|
||||
## including/excluding
|
||||
|
||||
| operator | info |
|
||||
|----------|-------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `*` | select all objects (only useful in `src` custom property) |
|
||||
| `-` | removes/hides object(s) |
|
||||
| `:` | indicates an object-embedded custom property key/value |
|
||||
| `.` | alias for `"class" :".foo"` equals `class:foo` |
|
||||
| `>` `<` | compare float or int number |
|
||||
| `/` | reference to root-scene.<br>Useful in case of (preventing) showing/hiding objects in nested scenes (instanced by `src`) (*) |
|
||||
|
||||
> \* = `#q=-/cube` hides object `cube` only in the root-scene (not nested `cube` objects)<br> `#q=-cube` hides both object `cube` in the root-scene <b>AND</b> nested `skybox` objects |
|
||||
|
||||
[» example implementation](https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/q.js)
|
||||
[» example 3D asset](https://github.com/coderofsalvation/xrfragment/blob/main/example/assets/query.gltf#L192)
|
||||
[» discussion](https://github.com/coderofsalvation/xrfragment/issues/3)
|
||||
|
||||
## Query Parser
|
||||
|
||||
Here's how to write a query parser:
|
||||
|
||||
1. create an associative array/object to store query-arguments as objects
|
||||
1. detect object id's & properties `foo:1` and `foo` (reference regex: `/^.*:[><=!]?/` )
|
||||
1. detect excluders like `-foo`,`-foo:1`,`-.foo`,`-/foo` (reference regex: `/^-/` )
|
||||
1. detect root selectors like `/foo` (reference regex: `/^[-]?\//` )
|
||||
1. detect class selectors like `.foo` (reference regex: `/^[-]?class$/` )
|
||||
1. detect number values like `foo:1` (reference regex: `/^[0-9\.]+$/` )
|
||||
1. expand aliases like `.foo` into `class:foo`
|
||||
1. for every query token split string on `:`
|
||||
1. create an empty array `rules`
|
||||
1. then strip key-operator: convert "-foo" into "foo"
|
||||
1. add operator and value to rule-array
|
||||
1. therefore we we set `id` to `true` or `false` (false=excluder `-`)
|
||||
1. and we set `root` to `true` or `false` (true=`/` root selector is present)
|
||||
1. we convert key '/foo' into 'foo'
|
||||
1. finally we add the key/value to the store like `store.foo = {id:false,root:true}` e.g.
|
||||
|
||||
> An example query-parser (which compiles to many languages) can be [found here](https://github.com/coderofsalvation/xrfragment/blob/main/src/xrfragment/Query.hx)
|
||||
|
||||
## XR Fragment URI Grammar
|
||||
|
||||
```
|
||||
reserved = gen-delims / sub-delims
|
||||
gen-delims = "#" / "&"
|
||||
sub-delims = "," / "="
|
||||
```
|
||||
|
||||
> Example: `://foo.com/my3d.gltf#pos=1,0,0&prio=-5&t=0,100`
|
||||
|
||||
| Demo | Explanation |
|
||||
|-------------------------------|---------------------------------|
|
||||
| `pos=1,2,3` | vector/coordinate argument e.g. |
|
||||
| `pos=1,2,3&rot=0,90,0&q=.foo` | combinators |
|
||||
|
||||
|
||||
# Text in XR (tagging,linking to spatial objects)
|
||||
|
||||
|
@ -316,7 +395,7 @@ To keep XR Fragments a lightweight spec, BibTeX is used for text/spatial tagging
|
|||
| │ └ src: ://author.com/article.txt | | |
|
||||
| │ | | @friend{friends |
|
||||
| └── ◻ note_canvas | | ... |
|
||||
| └ src:`data:welcome human @...` | | } |
|
||||
| └ src:`data:welcome human\n@...` | | } |
|
||||
| | +------------------------+
|
||||
| |
|
||||
+--------------------------------------------------------------+
|
||||
|
@ -327,37 +406,38 @@ The beauty is that text (AND visual-meta) in Data URI promotes rich copy-paste.
|
|||
In both cases, the text gets rendered immediately (onto a plane geometry, hence the name '_canvas').
|
||||
The XR Fragment-compatible browser can let the enduser access visual-meta(data)-fields after interacting with the object (contextmenu e.g.).
|
||||
|
||||
The mapping between 3D objects and text (src-data) is simple:
|
||||
> additional tagging using [bibs](https://github.com/coderofsalvation/tagbibs): to tag spatial object `note_canvas` with 'todo', the enduser can type or speak `@note_canvas@todo`
|
||||
|
||||
The mapping between 3D objects and text (src-data) is simple (the :
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
+------------------------------------------------------------------------------------+
|
||||
| |
|
||||
| index.gltf |
|
||||
| │ |
|
||||
| └── ◻ rentalhouse |
|
||||
| └ class: house |
|
||||
| └ ◻ note |
|
||||
| └ src:`data: todo: call owner |
|
||||
| @house{owner, |
|
||||
| url = {#.house} |
|
||||
| }` |
|
||||
+------------------------------------------------------------------------------------+
|
||||
+------------------------------------------------+
|
||||
| |
|
||||
| index.gltf |
|
||||
| │ |
|
||||
| └── ◻ rentalhouse |
|
||||
| └ class: house <----------------- matches -------+
|
||||
| └ ◻ note | |
|
||||
| └ src:`data: todo: call owner | bib |
|
||||
| @owner@house@todo | ----> expands to @house{owner,
|
||||
| | bibtex: }
|
||||
| ` | @contact{
|
||||
+------------------------------------------------+ }
|
||||
```
|
||||
|
||||
3D object names and/or classes map to `name` of visual-meta glossary-entries.
|
||||
This allows rich interaction and interlinking between text and 3D objects:
|
||||
Bi-directional mapping between 3D object names and/or classnames and text using bibs,BibTags & XR Fragments, allows for rich interlinking between text and 3D objects:
|
||||
|
||||
1. When the user surfs to https://.../index.gltf#rentalhouse the XR Fragments-parser points the enduser to the rentalhouse object, and can show contextual info about it.
|
||||
2. When (partial) remote content is embedded thru XR Fragment queries (see XR Fragment queries), indirectly related metadata can be embedded along.
|
||||
|
||||
## Bibs-enabled BibTeX: lowest common denominator for tagging/triples
|
||||
## Bibs & BibTeX: lowest common denominator for linking data
|
||||
|
||||
> "When a car breaks down, the ones **without** turbosupercharger are easier to fix"
|
||||
|
||||
Unlike XML or JSON, the typeless, unnested, everything-is-text nature of BibTeX tags is a great advantage for introspection.<br>
|
||||
It's a missing sensemaking precursor to (eventual) extrospective RDF.<br>
|
||||
It's a missing sensemaking precursor to extrospective RDF.<br>
|
||||
BibTeX-appendices are already used in the digital AND physical world (academic books, [visual-meta](https://visual-meta.info)), perhaps due to its terseness & simplicity.<br>
|
||||
In that sense, it's one step up from the `.ini` fileformat (which has never leaked into the physical world like BibTex):
|
||||
|
||||
|
@ -370,7 +450,7 @@ In that sense, it's one step up from the `.ini` fileformat (which has never leak
|
|||
| structure | fuzzy (sensemaking) | precise |
|
||||
| space/scope | local | world |
|
||||
| everything is text (string) | yes | no |
|
||||
| paperfriendly | [bibs](https://github.com/coderofsalvation/tagbibs) | no |
|
||||
| voice/paper-friendly | [bibs](https://github.com/coderofsalvation/tagbibs) | no |
|
||||
| leaves (dictated) text intact | yes | no |
|
||||
| markup language | just an appendix | ~4 different |
|
||||
| polyglot format | no | yes |
|
||||
|
@ -451,7 +531,7 @@ xrtext = {
|
|||
}
|
||||
```
|
||||
|
||||
The above (de)multiplexes text/metadata, expands bibs, (de)serializes bibtex (and all fits more or less on one A4 paper)
|
||||
The above functions (de)multiplexe text/metadata, expands bibs, (de)serialize bibtex (and all fits more or less on one A4 paper)
|
||||
|
||||
> above can be used as a startingpoint for LLVM's to translate/steelman to a more formal form/language.
|
||||
|
||||
|
@ -470,123 +550,33 @@ tags.find( (t) => t.k == 'flap{' ).v.asdf = 1 // edit tag
|
|||
tags.push({ k:'bar{', v:{abc:123} }) // add tag
|
||||
console.log( xrtext.encode(text,tags) ) // multiplex text & bibtex back together
|
||||
```
|
||||
This outputs:
|
||||
|
||||
```
|
||||
@{references-start}
|
||||
@misc{emilyHegland/Edgar&Frod,
|
||||
author = {Emily Hegland},
|
||||
title = {Edgar & Frode Hegland, November 2021},
|
||||
year = {2021},
|
||||
month = {11},
|
||||
hello world
|
||||
|
||||
|
||||
@greeting{hello,
|
||||
}
|
||||
```
|
||||
|
||||
The above BibTeX-flavor can be imported, however will be rewritten to Dumb BibTeX, to satisfy rule 2 & 5, as well as the [core principle](#core-principle)
|
||||
|
||||
```
|
||||
@visual-meta{
|
||||
version = {1.1},
|
||||
generator = {Author 7.6.2 (1064)},
|
||||
section = {visual-meta-header}
|
||||
@{some-section}
|
||||
@flap{
|
||||
asdf = {1}
|
||||
}
|
||||
@misc{emilyHegland/Edgar&Frod,
|
||||
author = {Emily Hegland},
|
||||
title = {Edgar & Frode Hegland, November 2021},
|
||||
year = {2021},
|
||||
month = {11},
|
||||
section = {references}
|
||||
@bar{
|
||||
abc = {123}
|
||||
}
|
||||
```
|
||||
|
||||
# HYPER copy/paste
|
||||
|
||||
The previous example, offers something exciting compared to simple copy/paste of 3D objects or text.
|
||||
XR Fragment allows HYPER-copy/paste: time, space and text interlinked.
|
||||
XR Text according to the XR Fragment spec, allows HYPER-copy/paste: time, space and text interlinked.
|
||||
Therefore, the enduser in an XR Fragment-compatible browser can copy/paste/share data in these ways:
|
||||
|
||||
1. time/space: 3D object (current animation-loop)
|
||||
1. text: TeXt object (including BibTeX/visual-meta if any)
|
||||
1. interlinked: Collected objects by visual-meta tag
|
||||
|
||||
# XR Fragment queries
|
||||
|
||||
Include, exclude, hide/shows objects using space-separated strings:
|
||||
|
||||
* `#q=cube`
|
||||
* `#q=cube -ball_inside_cube`
|
||||
* `#q=* -sky`
|
||||
* `#q=-.language .english`
|
||||
* `#q=cube&rot=0,90,0`
|
||||
* `#q=price:>2 price:<5`
|
||||
|
||||
It's simple but powerful syntax which allows <b>css</b>-like class/id-selectors with a searchengine prompt-style feeling:
|
||||
|
||||
1. queries are showing/hiding objects **only** when defined as `src` value (prevents sharing of scene-tampered URL's).
|
||||
1. queries are highlighting objects when defined in the top-Level (browser) URL (bar).
|
||||
1. search words like `cube` and `foo` in `#q=cube foo` are matched against 3D object names or custom metadata-key(values)
|
||||
1. search words like `cube` and `foo` in `#q=cube foo` are matched against tags (BibTeX) inside plaintext `src` values like `@cube{redcube, ...` e.g.
|
||||
1. `#` equals `#q=*`
|
||||
1. words starting with `.` like `.german` match class-metadata of 3D objects like `"class":"german"`
|
||||
1. words starting with `.` like `.german` match class-metadata of (BibTeX) tags in XR Text objects like `@german{KarlHeinz, ...` e.g.
|
||||
|
||||
> **For example**: `#q=.foo` is a shorthand for `#q=class:foo`, which will select objects with custom property `class`:`foo`. Just a simple `#q=cube` will simply select an object named `cube`.
|
||||
|
||||
* see [an example video here](https://coderofsalvation.github.io/xrfragment.media/queries.mp4)
|
||||
|
||||
## including/excluding
|
||||
|
||||
| operator | info |
|
||||
|----------|-------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `*` | select all objects (only useful in `src` custom property) |
|
||||
| `-` | removes/hides object(s) |
|
||||
| `:` | indicates an object-embedded custom property key/value |
|
||||
| `.` | alias for `"class" :".foo"` equals `class:foo` |
|
||||
| `>` `<` | compare float or int number |
|
||||
| `/` | reference to root-scene.<br>Useful in case of (preventing) showing/hiding objects in nested scenes (instanced by `src`) (*) |
|
||||
|
||||
> \* = `#q=-/cube` hides object `cube` only in the root-scene (not nested `cube` objects)<br> `#q=-cube` hides both object `cube` in the root-scene <b>AND</b> nested `skybox` objects |
|
||||
|
||||
[» example implementation](https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/q.js)
|
||||
[» example 3D asset](https://github.com/coderofsalvation/xrfragment/blob/main/example/assets/query.gltf#L192)
|
||||
[» discussion](https://github.com/coderofsalvation/xrfragment/issues/3)
|
||||
|
||||
## Query Parser
|
||||
|
||||
Here's how to write a query parser:
|
||||
|
||||
1. create an associative array/object to store query-arguments as objects
|
||||
1. detect object id's & properties `foo:1` and `foo` (reference regex: `/^.*:[><=!]?/` )
|
||||
1. detect excluders like `-foo`,`-foo:1`,`-.foo`,`-/foo` (reference regex: `/^-/` )
|
||||
1. detect root selectors like `/foo` (reference regex: `/^[-]?\//` )
|
||||
1. detect class selectors like `.foo` (reference regex: `/^[-]?class$/` )
|
||||
1. detect number values like `foo:1` (reference regex: `/^[0-9\.]+$/` )
|
||||
1. expand aliases like `.foo` into `class:foo`
|
||||
1. for every query token split string on `:`
|
||||
1. create an empty array `rules`
|
||||
1. then strip key-operator: convert "-foo" into "foo"
|
||||
1. add operator and value to rule-array
|
||||
1. therefore we we set `id` to `true` or `false` (false=excluder `-`)
|
||||
1. and we set `root` to `true` or `false` (true=`/` root selector is present)
|
||||
1. we convert key '/foo' into 'foo'
|
||||
1. finally we add the key/value to the store like `store.foo = {id:false,root:true}` e.g.
|
||||
|
||||
> An example query-parser (which compiles to many languages) can be [found here](https://github.com/coderofsalvation/xrfragment/blob/main/src/xrfragment/Query.hx)
|
||||
|
||||
## XR Fragment URI Grammar
|
||||
|
||||
```
|
||||
reserved = gen-delims / sub-delims
|
||||
gen-delims = "#" / "&"
|
||||
sub-delims = "," / "="
|
||||
```
|
||||
|
||||
> Example: `://foo.com/my3d.gltf#pos=1,0,0&prio=-5&t=0,100`
|
||||
|
||||
| Demo | Explanation |
|
||||
|-------------------------------|---------------------------------|
|
||||
| `pos=1,2,3` | vector/coordinate argument e.g. |
|
||||
| `pos=1,2,3&rot=0,90,0&q=.foo` | combinators |
|
||||
|
||||
# Security Considerations
|
||||
|
||||
Since XR Text contains metadata too, the user should be able to set up tagging-rules, so the copy-paste feature can :
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
|
||||
Internet Engineering Task Force L.R. van Kammen
|
||||
Internet-Draft 6 September 2023
|
||||
Internet-Draft 7 September 2023
|
||||
Intended status: Informational
|
||||
|
||||
|
||||
|
@ -40,7 +40,7 @@ Status of This Memo
|
|||
time. It is inappropriate to use Internet-Drafts as reference
|
||||
material or to cite them other than as "work in progress."
|
||||
|
||||
This Internet-Draft will expire on 9 March 2024.
|
||||
This Internet-Draft will expire on 10 March 2024.
|
||||
|
||||
Copyright Notice
|
||||
|
||||
|
@ -53,7 +53,7 @@ Copyright Notice
|
|||
|
||||
|
||||
|
||||
van Kammen Expires 9 March 2024 [Page 1]
|
||||
van Kammen Expires 10 March 2024 [Page 1]
|
||||
|
||||
Internet-Draft XR Fragments September 2023
|
||||
|
||||
|
@ -73,18 +73,18 @@ Table of Contents
|
|||
5. List of metadata for 3D nodes . . . . . . . . . . . . . . . . 5
|
||||
6. Navigating 3D . . . . . . . . . . . . . . . . . . . . . . . . 5
|
||||
7. Embedding 3D content . . . . . . . . . . . . . . . . . . . . 6
|
||||
8. Text in XR (tagging,linking to spatial objects) . . . . . . . 7
|
||||
8.1. Default Data URI mimetype . . . . . . . . . . . . . . . . 10
|
||||
8.2. URL and Data URI . . . . . . . . . . . . . . . . . . . . 11
|
||||
8.3. Bibs-enabled BibTeX: lowest common denominator for tagging/
|
||||
triples . . . . . . . . . . . . . . . . . . . . . . . . . 12
|
||||
8.4. XR Text example parser . . . . . . . . . . . . . . . . . 14
|
||||
9. HYPER copy/paste . . . . . . . . . . . . . . . . . . . . . . 16
|
||||
10. XR Fragment queries . . . . . . . . . . . . . . . . . . . . . 17
|
||||
10.1. including/excluding . . . . . . . . . . . . . . . . . . 17
|
||||
10.2. Query Parser . . . . . . . . . . . . . . . . . . . . . . 18
|
||||
10.3. XR Fragment URI Grammar . . . . . . . . . . . . . . . . 19
|
||||
11. Security Considerations . . . . . . . . . . . . . . . . . . . 19
|
||||
8. XR Fragment queries . . . . . . . . . . . . . . . . . . . . . 7
|
||||
8.1. including/excluding . . . . . . . . . . . . . . . . . . . 8
|
||||
8.2. Query Parser . . . . . . . . . . . . . . . . . . . . . . 8
|
||||
8.3. XR Fragment URI Grammar . . . . . . . . . . . . . . . . . 9
|
||||
9. Text in XR (tagging,linking to spatial objects) . . . . . . . 9
|
||||
9.1. Default Data URI mimetype . . . . . . . . . . . . . . . . 12
|
||||
9.2. URL and Data URI . . . . . . . . . . . . . . . . . . . . 13
|
||||
9.3. Bibs & BibTeX: lowest common denominator for linking
|
||||
data . . . . . . . . . . . . . . . . . . . . . . . . . . 14
|
||||
9.4. XR Text example parser . . . . . . . . . . . . . . . . . 16
|
||||
10. HYPER copy/paste . . . . . . . . . . . . . . . . . . . . . . 18
|
||||
11. Security Considerations . . . . . . . . . . . . . . . . . . . 18
|
||||
12. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 19
|
||||
13. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 19
|
||||
|
||||
|
@ -109,7 +109,7 @@ Table of Contents
|
|||
|
||||
|
||||
|
||||
van Kammen Expires 9 March 2024 [Page 2]
|
||||
van Kammen Expires 10 March 2024 [Page 2]
|
||||
|
||||
Internet-Draft XR Fragments September 2023
|
||||
|
||||
|
@ -165,7 +165,7 @@ Internet-Draft XR Fragments September 2023
|
|||
|
||||
|
||||
|
||||
van Kammen Expires 9 March 2024 [Page 3]
|
||||
van Kammen Expires 10 March 2024 [Page 3]
|
||||
|
||||
Internet-Draft XR Fragments September 2023
|
||||
|
||||
|
@ -221,7 +221,7 @@ Internet-Draft XR Fragments September 2023
|
|||
|
||||
|
||||
|
||||
van Kammen Expires 9 March 2024 [Page 4]
|
||||
van Kammen Expires 10 March 2024 [Page 4]
|
||||
|
||||
Internet-Draft XR Fragments September 2023
|
||||
|
||||
|
@ -277,7 +277,7 @@ Internet-Draft XR Fragments September 2023
|
|||
|
||||
|
||||
|
||||
van Kammen Expires 9 March 2024 [Page 5]
|
||||
van Kammen Expires 10 March 2024 [Page 5]
|
||||
|
||||
Internet-Draft XR Fragments September 2023
|
||||
|
||||
|
@ -333,7 +333,7 @@ Internet-Draft XR Fragments September 2023
|
|||
|
||||
|
||||
|
||||
van Kammen Expires 9 March 2024 [Page 6]
|
||||
van Kammen Expires 10 March 2024 [Page 6]
|
||||
|
||||
Internet-Draft XR Fragments September 2023
|
||||
|
||||
|
@ -346,7 +346,149 @@ Internet-Draft XR Fragments September 2023
|
|||
Resizing will be happen accordingly to its placeholder object
|
||||
aquariumcube, see chapter Scaling.
|
||||
|
||||
8. Text in XR (tagging,linking to spatial objects)
|
||||
8. XR Fragment queries
|
||||
|
||||
Include, exclude, hide/shows objects using space-separated strings:
|
||||
|
||||
* #q=cube
|
||||
* #q=cube -ball_inside_cube
|
||||
* #q=* -sky
|
||||
* #q=-.language .english
|
||||
* #q=cube&rot=0,90,0
|
||||
* #q=price:>2 price:<5
|
||||
|
||||
It's simple but powerful syntax which allows <b>css</b>-like class/
|
||||
id-selectors with a searchengine prompt-style feeling:
|
||||
|
||||
1. queries are showing/hiding objects *only* when defined as src
|
||||
value (prevents sharing of scene-tampered URL's).
|
||||
2. queries are highlighting objects when defined in the top-Level
|
||||
(browser) URL (bar).
|
||||
3. search words like cube and foo in #q=cube foo are matched against
|
||||
3D object names or custom metadata-key(values)
|
||||
4. search words like cube and foo in #q=cube foo are matched against
|
||||
tags (BibTeX) inside plaintext src values like @cube{redcube, ...
|
||||
e.g.
|
||||
5. # equals #q=*
|
||||
6. words starting with . like .german match class-metadata of 3D
|
||||
objects like "class":"german"
|
||||
7. words starting with . like .german match class-metadata of
|
||||
(BibTeX) tags in XR Text objects like @german{KarlHeinz, ... e.g.
|
||||
|
||||
| *For example*: #q=.foo is a shorthand for #q=class:foo, which will
|
||||
| select objects with custom property class:foo. Just a simple
|
||||
| #q=cube will simply select an object named cube.
|
||||
|
||||
* see an example video here
|
||||
(https://coderofsalvation.github.io/xrfragment.media/queries.mp4)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
van Kammen Expires 10 March 2024 [Page 7]
|
||||
|
||||
Internet-Draft XR Fragments September 2023
|
||||
|
||||
|
||||
8.1. including/excluding
|
||||
|
||||
+==========+=================================================+
|
||||
| operator | info |
|
||||
+==========+=================================================+
|
||||
| * | select all objects (only useful in src custom |
|
||||
| | property) |
|
||||
+----------+-------------------------------------------------+
|
||||
| - | removes/hides object(s) |
|
||||
+----------+-------------------------------------------------+
|
||||
| : | indicates an object-embedded custom property |
|
||||
| | key/value |
|
||||
+----------+-------------------------------------------------+
|
||||
| . | alias for "class" :".foo" equals class:foo |
|
||||
+----------+-------------------------------------------------+
|
||||
| > < | compare float or int number |
|
||||
+----------+-------------------------------------------------+
|
||||
| / | reference to root-scene. |
|
||||
| | Useful in case of (preventing) showing/hiding |
|
||||
| | objects in nested scenes (instanced by src) (*) |
|
||||
+----------+-------------------------------------------------+
|
||||
|
||||
Table 4
|
||||
|
||||
| * = #q=-/cube hides object cube only in the root-scene (not nested
|
||||
| cube objects)
|
||||
| #q=-cube hides both object cube in the root-scene <b>AND</b>
|
||||
| nested skybox objects |
|
||||
|
||||
» example implementation
|
||||
(https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/
|
||||
three/xrf/q.js) » example 3D asset
|
||||
(https://github.com/coderofsalvation/xrfragment/blob/main/example/
|
||||
assets/query.gltf#L192) » discussion
|
||||
(https://github.com/coderofsalvation/xrfragment/issues/3)
|
||||
|
||||
8.2. Query Parser
|
||||
|
||||
Here's how to write a query parser:
|
||||
|
||||
1. create an associative array/object to store query-arguments as
|
||||
objects
|
||||
2. detect object id's & properties foo:1 and foo (reference regex:
|
||||
/^.*:[><=!]?/ )
|
||||
3. detect excluders like -foo,-foo:1,-.foo,-/foo (reference regex:
|
||||
/^-/ )
|
||||
4. detect root selectors like /foo (reference regex: /^[-]?\// )
|
||||
|
||||
|
||||
|
||||
|
||||
van Kammen Expires 10 March 2024 [Page 8]
|
||||
|
||||
Internet-Draft XR Fragments September 2023
|
||||
|
||||
|
||||
5. detect class selectors like .foo (reference regex: /^[-]?class$/
|
||||
)
|
||||
6. detect number values like foo:1 (reference regex: /^[0-9\.]+$/ )
|
||||
7. expand aliases like .foo into class:foo
|
||||
8. for every query token split string on :
|
||||
9. create an empty array rules
|
||||
10. then strip key-operator: convert "-foo" into "foo"
|
||||
11. add operator and value to rule-array
|
||||
12. therefore we we set id to true or false (false=excluder -)
|
||||
13. and we set root to true or false (true=/ root selector is
|
||||
present)
|
||||
14. we convert key '/foo' into 'foo'
|
||||
15. finally we add the key/value to the store like store.foo =
|
||||
{id:false,root:true} e.g.
|
||||
|
||||
| An example query-parser (which compiles to many languages) can be
|
||||
| found here
|
||||
| (https://github.com/coderofsalvation/xrfragment/blob/main/src/
|
||||
| xrfragment/Query.hx)
|
||||
|
||||
8.3. XR Fragment URI Grammar
|
||||
|
||||
reserved = gen-delims / sub-delims
|
||||
gen-delims = "#" / "&"
|
||||
sub-delims = "," / "="
|
||||
|
||||
| Example: ://foo.com/my3d.gltf#pos=1,0,0&prio=-5&t=0,100
|
||||
|
||||
+=============================+=================================+
|
||||
| Demo | Explanation |
|
||||
+=============================+=================================+
|
||||
| pos=1,2,3 | vector/coordinate argument e.g. |
|
||||
+-----------------------------+---------------------------------+
|
||||
| pos=1,2,3&rot=0,90,0&q=.foo | combinators |
|
||||
+-----------------------------+---------------------------------+
|
||||
|
||||
Table 5
|
||||
|
||||
9. Text in XR (tagging,linking to spatial objects)
|
||||
|
||||
We still think and speak in simple text, not in HTML or RDF.
|
||||
The most advanced human will probably not shout <h1>FIRE!</h1> in
|
||||
|
@ -356,6 +498,14 @@ Internet-Draft XR Fragments September 2023
|
|||
Ideally metadata must come *later with* text, but not *obfuscate* the
|
||||
text, or *in another* file.
|
||||
|
||||
|
||||
|
||||
|
||||
van Kammen Expires 10 March 2024 [Page 9]
|
||||
|
||||
Internet-Draft XR Fragments September 2023
|
||||
|
||||
|
||||
| Humans first, machines (AI) later (core principle (#core-
|
||||
| principle)
|
||||
|
||||
|
@ -384,16 +534,6 @@ Internet-Draft XR Fragments September 2023
|
|||
This allows recursive connections between text itself, as well as 3D
|
||||
objects and vice versa, using *BibTags* :
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
van Kammen Expires 9 March 2024 [Page 7]
|
||||
|
||||
Internet-Draft XR Fragments September 2023
|
||||
|
||||
|
||||
+---------------------------------------------+ +------------------+
|
||||
| My Notes | | / \ |
|
||||
| | | / \ |
|
||||
|
@ -417,35 +557,7 @@ Internet-Draft XR Fragments September 2023
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
van Kammen Expires 9 March 2024 [Page 8]
|
||||
van Kammen Expires 10 March 2024 [Page 10]
|
||||
|
||||
Internet-Draft XR Fragments September 2023
|
||||
|
||||
|
@ -488,7 +600,7 @@ Internet-Draft XR Fragments September 2023
|
|||
| | node to all nodes) |
|
||||
+------------------------------------+-----------------------------+
|
||||
|
||||
Table 4
|
||||
Table 6
|
||||
|
||||
This empowers the enduser spatial expressiveness (see the core
|
||||
principle (#core-principle)): spatial wires can be rendered, words
|
||||
|
@ -501,7 +613,7 @@ Internet-Draft XR Fragments September 2023
|
|||
|
||||
|
||||
|
||||
van Kammen Expires 9 March 2024 [Page 9]
|
||||
van Kammen Expires 10 March 2024 [Page 11]
|
||||
|
||||
Internet-Draft XR Fragments September 2023
|
||||
|
||||
|
@ -518,7 +630,7 @@ Internet-Draft XR Fragments September 2023
|
|||
| multiplexing of id/category is deliberate because of the core
|
||||
| principle (#core-principle).
|
||||
|
||||
8.1. Default Data URI mimetype
|
||||
9.1. Default Data URI mimetype
|
||||
|
||||
The src-values work as expected (respecting mime-types), however:
|
||||
|
||||
|
@ -557,7 +669,7 @@ Internet-Draft XR Fragments September 2023
|
|||
|
||||
|
||||
|
||||
van Kammen Expires 9 March 2024 [Page 10]
|
||||
van Kammen Expires 10 March 2024 [Page 12]
|
||||
|
||||
Internet-Draft XR Fragments September 2023
|
||||
|
||||
|
@ -576,7 +688,7 @@ Internet-Draft XR Fragments September 2023
|
|||
| objects using custom properties (but is not interpreted by this
|
||||
| spec).
|
||||
|
||||
8.2. URL and Data URI
|
||||
9.2. URL and Data URI
|
||||
|
||||
+--------------------------------------------------------------+ +------------------------+
|
||||
| | | author.com/article.txt |
|
||||
|
@ -586,7 +698,7 @@ Internet-Draft XR Fragments September 2023
|
|||
| │ └ src: ://author.com/article.txt | | |
|
||||
| │ | | @friend{friends |
|
||||
| └── ◻ note_canvas | | ... |
|
||||
| └ src:`data:welcome human @...` | | } |
|
||||
| └ src:`data:welcome human\n@...` | | } |
|
||||
| | +------------------------+
|
||||
| |
|
||||
+--------------------------------------------------------------+
|
||||
|
@ -599,7 +711,12 @@ Internet-Draft XR Fragments September 2023
|
|||
meta(data)-fields after interacting with the object (contextmenu
|
||||
e.g.).
|
||||
|
||||
The mapping between 3D objects and text (src-data) is simple:
|
||||
| additional tagging using bibs
|
||||
| (https://github.com/coderofsalvation/tagbibs): to tag spatial
|
||||
| object note_canvas with 'todo', the enduser can type or speak
|
||||
| @note_canvas@todo
|
||||
|
||||
The mapping between 3D objects and text (src-data) is simple (the :
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -608,32 +725,27 @@ Internet-Draft XR Fragments September 2023
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
van Kammen Expires 9 March 2024 [Page 11]
|
||||
van Kammen Expires 10 March 2024 [Page 13]
|
||||
|
||||
Internet-Draft XR Fragments September 2023
|
||||
|
||||
|
||||
+------------------------------------------------------------------------------------+
|
||||
| |
|
||||
| index.gltf |
|
||||
| │ |
|
||||
| └── ◻ rentalhouse |
|
||||
| └ class: house |
|
||||
| └ ◻ note |
|
||||
| └ src:`data: todo: call owner |
|
||||
| @house{owner, |
|
||||
| url = {#.house} |
|
||||
| }` |
|
||||
+------------------------------------------------------------------------------------+
|
||||
+------------------------------------------------+
|
||||
| |
|
||||
| index.gltf |
|
||||
| │ |
|
||||
| └── ◻ rentalhouse |
|
||||
| └ class: house <----------------- matches -------+
|
||||
| └ ◻ note | |
|
||||
| └ src:`data: todo: call owner | bib |
|
||||
| @owner@house@todo | ----> expands to @house{owner,
|
||||
| | bibtex: }
|
||||
| ` | @contact{
|
||||
+------------------------------------------------+ }
|
||||
|
||||
3D object names and/or classes map to name of visual-meta glossary-
|
||||
entries. This allows rich interaction and interlinking between text
|
||||
and 3D objects:
|
||||
Bi-directional mapping between 3D object names and/or classnames and
|
||||
text using bibs,BibTags & XR Fragments, allows for rich interlinking
|
||||
between text and 3D objects:
|
||||
|
||||
1. When the user surfs to https://.../index.gltf#rentalhouse the XR
|
||||
Fragments-parser points the enduser to the rentalhouse object,
|
||||
|
@ -642,14 +754,14 @@ Internet-Draft XR Fragments September 2023
|
|||
queries (see XR Fragment queries), indirectly related metadata
|
||||
can be embedded along.
|
||||
|
||||
8.3. Bibs-enabled BibTeX: lowest common denominator for tagging/triples
|
||||
9.3. Bibs & BibTeX: lowest common denominator for linking data
|
||||
|
||||
| "When a car breaks down, the ones *without* turbosupercharger are
|
||||
| easier to fix"
|
||||
|
||||
Unlike XML or JSON, the typeless, unnested, everything-is-text nature
|
||||
of BibTeX tags is a great advantage for introspection.
|
||||
It's a missing sensemaking precursor to (eventual) extrospective RDF.
|
||||
It's a missing sensemaking precursor to extrospective RDF.
|
||||
BibTeX-appendices are already used in the digital AND physical world
|
||||
(academic books, visual-meta (https://visual-meta.info)), perhaps due
|
||||
to its terseness & simplicity.
|
||||
|
@ -669,7 +781,7 @@ Internet-Draft XR Fragments September 2023
|
|||
|
||||
|
||||
|
||||
van Kammen Expires 9 March 2024 [Page 12]
|
||||
van Kammen Expires 10 March 2024 [Page 14]
|
||||
|
||||
Internet-Draft XR Fragments September 2023
|
||||
|
||||
|
@ -686,8 +798,8 @@ Internet-Draft XR Fragments September 2023
|
|||
|everything is |yes |no |
|
||||
|text (string) | | |
|
||||
+----------------+-------------------------------------+---------------+
|
||||
|paperfriendly |bibs |no |
|
||||
| |(https://github.com/coderofsalvation/| |
|
||||
|voice/paper- |bibs |no |
|
||||
|friendly |(https://github.com/coderofsalvation/| |
|
||||
| |tagbibs) | |
|
||||
+----------------+-------------------------------------+---------------+
|
||||
|leaves |yes |no |
|
||||
|
@ -725,7 +837,7 @@ Internet-Draft XR Fragments September 2023
|
|||
|
||||
|
||||
|
||||
van Kammen Expires 9 March 2024 [Page 13]
|
||||
van Kammen Expires 10 March 2024 [Page 15]
|
||||
|
||||
Internet-Draft XR Fragments September 2023
|
||||
|
||||
|
@ -750,9 +862,9 @@ Internet-Draft XR Fragments September 2023
|
|||
|structures | | |
|
||||
+----------------+-------------------------------------+---------------+
|
||||
|
||||
Table 5
|
||||
Table 7
|
||||
|
||||
8.4. XR Text example parser
|
||||
9.4. XR Text example parser
|
||||
|
||||
1. The XR Fragments spec does not aim to harden the BiBTeX format
|
||||
2. However, respect multi-line BibTex values because of the core
|
||||
|
@ -781,7 +893,7 @@ xrtext = {
|
|||
|
||||
|
||||
|
||||
van Kammen Expires 9 March 2024 [Page 14]
|
||||
van Kammen Expires 10 March 2024 [Page 16]
|
||||
|
||||
Internet-Draft XR Fragments September 2023
|
||||
|
||||
|
@ -824,8 +936,8 @@ Internet-Draft XR Fragments September 2023
|
|||
}
|
||||
}
|
||||
|
||||
The above (de)multiplexes text/metadata, expands bibs, (de)serializes
|
||||
bibtex (and all fits more or less on one A4 paper)
|
||||
The above functions (de)multiplexe text/metadata, expands bibs,
|
||||
(de)serialize bibtex (and all fits more or less on one A4 paper)
|
||||
|
||||
| above can be used as a startingpoint for LLVM's to translate/
|
||||
| steelman to a more formal form/language.
|
||||
|
@ -837,7 +949,7 @@ Internet-Draft XR Fragments September 2023
|
|||
|
||||
|
||||
|
||||
van Kammen Expires 9 March 2024 [Page 15]
|
||||
van Kammen Expires 10 March 2024 [Page 17]
|
||||
|
||||
Internet-Draft XR Fragments September 2023
|
||||
|
||||
|
@ -856,189 +968,33 @@ tags.find( (t) => t.k == 'flap{' ).v.asdf = 1 // edit tag
|
|||
tags.push({ k:'bar{', v:{abc:123} }) // add tag
|
||||
console.log( xrtext.encode(text,tags) ) // multiplex text & bibtex back together
|
||||
|
||||
@{references-start}
|
||||
@misc{emilyHegland/Edgar&Frod,
|
||||
author = {Emily Hegland},
|
||||
title = {Edgar & Frode Hegland, November 2021},
|
||||
year = {2021},
|
||||
month = {11},
|
||||
This outputs:
|
||||
|
||||
hello world
|
||||
|
||||
|
||||
@greeting{hello,
|
||||
}
|
||||
@{some-section}
|
||||
@flap{
|
||||
asdf = {1}
|
||||
}
|
||||
@bar{
|
||||
abc = {123}
|
||||
}
|
||||
|
||||
The above BibTeX-flavor can be imported, however will be rewritten to
|
||||
Dumb BibTeX, to satisfy rule 2 & 5, as well as the core principle
|
||||
(#core-principle)
|
||||
|
||||
@visual-meta{
|
||||
version = {1.1},
|
||||
generator = {Author 7.6.2 (1064)},
|
||||
section = {visual-meta-header}
|
||||
}
|
||||
@misc{emilyHegland/Edgar&Frod,
|
||||
author = {Emily Hegland},
|
||||
title = {Edgar & Frode Hegland, November 2021},
|
||||
year = {2021},
|
||||
month = {11},
|
||||
section = {references}
|
||||
}
|
||||
|
||||
9. HYPER copy/paste
|
||||
10. HYPER copy/paste
|
||||
|
||||
The previous example, offers something exciting compared to simple
|
||||
copy/paste of 3D objects or text. XR Fragment allows HYPER-copy/
|
||||
paste: time, space and text interlinked. Therefore, the enduser in
|
||||
an XR Fragment-compatible browser can copy/paste/share data in these
|
||||
ways:
|
||||
copy/paste of 3D objects or text. XR Text according to the XR
|
||||
Fragment spec, allows HYPER-copy/paste: time, space and text
|
||||
interlinked. Therefore, the enduser in an XR Fragment-compatible
|
||||
browser can copy/paste/share data in these ways:
|
||||
|
||||
1. time/space: 3D object (current animation-loop)
|
||||
|
||||
|
||||
|
||||
van Kammen Expires 9 March 2024 [Page 16]
|
||||
|
||||
Internet-Draft XR Fragments September 2023
|
||||
|
||||
|
||||
2. text: TeXt object (including BibTeX/visual-meta if any)
|
||||
3. interlinked: Collected objects by visual-meta tag
|
||||
|
||||
10. XR Fragment queries
|
||||
|
||||
Include, exclude, hide/shows objects using space-separated strings:
|
||||
|
||||
* #q=cube
|
||||
* #q=cube -ball_inside_cube
|
||||
* #q=* -sky
|
||||
* #q=-.language .english
|
||||
* #q=cube&rot=0,90,0
|
||||
* #q=price:>2 price:<5
|
||||
|
||||
It's simple but powerful syntax which allows <b>css</b>-like class/
|
||||
id-selectors with a searchengine prompt-style feeling:
|
||||
|
||||
1. queries are showing/hiding objects *only* when defined as src
|
||||
value (prevents sharing of scene-tampered URL's).
|
||||
2. queries are highlighting objects when defined in the top-Level
|
||||
(browser) URL (bar).
|
||||
3. search words like cube and foo in #q=cube foo are matched against
|
||||
3D object names or custom metadata-key(values)
|
||||
4. search words like cube and foo in #q=cube foo are matched against
|
||||
tags (BibTeX) inside plaintext src values like @cube{redcube, ...
|
||||
e.g.
|
||||
5. # equals #q=*
|
||||
6. words starting with . like .german match class-metadata of 3D
|
||||
objects like "class":"german"
|
||||
7. words starting with . like .german match class-metadata of
|
||||
(BibTeX) tags in XR Text objects like @german{KarlHeinz, ... e.g.
|
||||
|
||||
| *For example*: #q=.foo is a shorthand for #q=class:foo, which will
|
||||
| select objects with custom property class:foo. Just a simple
|
||||
| #q=cube will simply select an object named cube.
|
||||
|
||||
* see an example video here
|
||||
(https://coderofsalvation.github.io/xrfragment.media/queries.mp4)
|
||||
|
||||
10.1. including/excluding
|
||||
|
||||
+==========+=================================================+
|
||||
| operator | info |
|
||||
+==========+=================================================+
|
||||
| * | select all objects (only useful in src custom |
|
||||
| | property) |
|
||||
+----------+-------------------------------------------------+
|
||||
| - | removes/hides object(s) |
|
||||
|
||||
|
||||
|
||||
van Kammen Expires 9 March 2024 [Page 17]
|
||||
|
||||
Internet-Draft XR Fragments September 2023
|
||||
|
||||
|
||||
+----------+-------------------------------------------------+
|
||||
| : | indicates an object-embedded custom property |
|
||||
| | key/value |
|
||||
+----------+-------------------------------------------------+
|
||||
| . | alias for "class" :".foo" equals class:foo |
|
||||
+----------+-------------------------------------------------+
|
||||
| > < | compare float or int number |
|
||||
+----------+-------------------------------------------------+
|
||||
| / | reference to root-scene. |
|
||||
| | Useful in case of (preventing) showing/hiding |
|
||||
| | objects in nested scenes (instanced by src) (*) |
|
||||
+----------+-------------------------------------------------+
|
||||
|
||||
Table 6
|
||||
|
||||
| * = #q=-/cube hides object cube only in the root-scene (not nested
|
||||
| cube objects)
|
||||
| #q=-cube hides both object cube in the root-scene <b>AND</b>
|
||||
| nested skybox objects |
|
||||
|
||||
» example implementation
|
||||
(https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/
|
||||
three/xrf/q.js) » example 3D asset
|
||||
(https://github.com/coderofsalvation/xrfragment/blob/main/example/
|
||||
assets/query.gltf#L192) » discussion
|
||||
(https://github.com/coderofsalvation/xrfragment/issues/3)
|
||||
|
||||
10.2. Query Parser
|
||||
|
||||
Here's how to write a query parser:
|
||||
|
||||
1. create an associative array/object to store query-arguments as
|
||||
objects
|
||||
2. detect object id's & properties foo:1 and foo (reference regex:
|
||||
/^.*:[><=!]?/ )
|
||||
3. detect excluders like -foo,-foo:1,-.foo,-/foo (reference regex:
|
||||
/^-/ )
|
||||
4. detect root selectors like /foo (reference regex: /^[-]?\// )
|
||||
5. detect class selectors like .foo (reference regex: /^[-]?class$/
|
||||
)
|
||||
6. detect number values like foo:1 (reference regex: /^[0-9\.]+$/ )
|
||||
7. expand aliases like .foo into class:foo
|
||||
8. for every query token split string on :
|
||||
9. create an empty array rules
|
||||
10. then strip key-operator: convert "-foo" into "foo"
|
||||
11. add operator and value to rule-array
|
||||
12. therefore we we set id to true or false (false=excluder -)
|
||||
|
||||
|
||||
|
||||
|
||||
van Kammen Expires 9 March 2024 [Page 18]
|
||||
|
||||
Internet-Draft XR Fragments September 2023
|
||||
|
||||
|
||||
13. and we set root to true or false (true=/ root selector is
|
||||
present)
|
||||
14. we convert key '/foo' into 'foo'
|
||||
15. finally we add the key/value to the store like store.foo =
|
||||
{id:false,root:true} e.g.
|
||||
|
||||
| An example query-parser (which compiles to many languages) can be
|
||||
| found here
|
||||
| (https://github.com/coderofsalvation/xrfragment/blob/main/src/
|
||||
| xrfragment/Query.hx)
|
||||
|
||||
10.3. XR Fragment URI Grammar
|
||||
|
||||
reserved = gen-delims / sub-delims
|
||||
gen-delims = "#" / "&"
|
||||
sub-delims = "," / "="
|
||||
|
||||
| Example: ://foo.com/my3d.gltf#pos=1,0,0&prio=-5&t=0,100
|
||||
|
||||
+=============================+=================================+
|
||||
| Demo | Explanation |
|
||||
+=============================+=================================+
|
||||
| pos=1,2,3 | vector/coordinate argument e.g. |
|
||||
+-----------------------------+---------------------------------+
|
||||
| pos=1,2,3&rot=0,90,0&q=.foo | combinators |
|
||||
+-----------------------------+---------------------------------+
|
||||
|
||||
Table 7
|
||||
|
||||
11. Security Considerations
|
||||
|
||||
Since XR Text contains metadata too, the user should be able to set
|
||||
|
@ -1047,6 +1003,13 @@ Internet-Draft XR Fragments September 2023
|
|||
* filter out sensitive data when copy/pasting (XR text with
|
||||
class:secret e.g.)
|
||||
|
||||
|
||||
|
||||
van Kammen Expires 10 March 2024 [Page 18]
|
||||
|
||||
Internet-Draft XR Fragments September 2023
|
||||
|
||||
|
||||
12. IANA Considerations
|
||||
|
||||
This document has no IANA actions.
|
||||
|
@ -1061,4 +1024,41 @@ Internet-Draft XR Fragments September 2023
|
|||
|
||||
|
||||
|
||||
van Kammen Expires 9 March 2024 [Page 19]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
van Kammen Expires 10 March 2024 [Page 19]
|
||||
|
|
|
@ -285,6 +285,134 @@ Resizing will be happen accordingly to its placeholder object <tt>aquariumcube</
|
|||
</t>
|
||||
</section>
|
||||
|
||||
<section anchor="xr-fragment-queries"><name>XR Fragment queries</name>
|
||||
<t>Include, exclude, hide/shows objects using space-separated strings:</t>
|
||||
|
||||
<ul spacing="compact">
|
||||
<li><tt>#q=cube</tt></li>
|
||||
<li><tt>#q=cube -ball_inside_cube</tt></li>
|
||||
<li><tt>#q=* -sky</tt></li>
|
||||
<li><tt>#q=-.language .english</tt></li>
|
||||
<li><tt>#q=cube&rot=0,90,0</tt></li>
|
||||
<li><tt>#q=price:>2 price:<5</tt></li>
|
||||
</ul>
|
||||
<t>It's simple but powerful syntax which allows <b>css</b>-like class/id-selectors with a searchengine prompt-style feeling:</t>
|
||||
|
||||
<ol spacing="compact">
|
||||
<li>queries are showing/hiding objects <strong>only</strong> when defined as <tt>src</tt> value (prevents sharing of scene-tampered URL's).</li>
|
||||
<li>queries are highlighting objects when defined in the top-Level (browser) URL (bar).</li>
|
||||
<li>search words like <tt>cube</tt> and <tt>foo</tt> in <tt>#q=cube foo</tt> are matched against 3D object names or custom metadata-key(values)</li>
|
||||
<li>search words like <tt>cube</tt> and <tt>foo</tt> in <tt>#q=cube foo</tt> are matched against tags (BibTeX) inside plaintext <tt>src</tt> values like <tt>@cube{redcube, ...</tt> e.g.</li>
|
||||
<li><tt>#</tt> equals <tt>#q=*</tt></li>
|
||||
<li>words starting with <tt>.</tt> like <tt>.german</tt> match class-metadata of 3D objects like <tt>"class":"german"</tt></li>
|
||||
<li>words starting with <tt>.</tt> like <tt>.german</tt> match class-metadata of (BibTeX) tags in XR Text objects like <tt>@german{KarlHeinz, ...</tt> e.g.</li>
|
||||
</ol>
|
||||
<blockquote><t><strong>For example</strong>: <tt>#q=.foo</tt> is a shorthand for <tt>#q=class:foo</tt>, which will select objects with custom property <tt>class</tt>:<tt>foo</tt>. Just a simple <tt>#q=cube</tt> will simply select an object named <tt>cube</tt>.</t>
|
||||
</blockquote>
|
||||
<ul spacing="compact">
|
||||
<li>see <eref target="https://coderofsalvation.github.io/xrfragment.media/queries.mp4">an example video here</eref></li>
|
||||
</ul>
|
||||
|
||||
<section anchor="including-excluding"><name>including/excluding</name>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>operator</th>
|
||||
<th>info</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><tt>*</tt></td>
|
||||
<td>select all objects (only useful in <tt>src</tt> custom property)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>-</tt></td>
|
||||
<td>removes/hides object(s)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>:</tt></td>
|
||||
<td>indicates an object-embedded custom property key/value</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>.</tt></td>
|
||||
<td>alias for <tt>"class" :".foo"</tt> equals <tt>class:foo</tt></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>></tt> <tt><</tt></td>
|
||||
<td>compare float or int number</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>/</tt></td>
|
||||
<td>reference to root-scene.<br />
|
||||
Useful in case of (preventing) showing/hiding objects in nested scenes (instanced by <tt>src</tt>) (*)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table><blockquote><t>* = <tt>#q=-/cube</tt> hides object <tt>cube</tt> only in the root-scene (not nested <tt>cube</tt> objects)<br />
|
||||
<tt>#q=-cube</tt> hides both object <tt>cube</tt> in the root-scene <b>AND</b> nested <tt>skybox</tt> objects |</t>
|
||||
</blockquote><t><eref target="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/q.js">» example implementation</eref>
|
||||
<eref target="https://github.com/coderofsalvation/xrfragment/blob/main/example/assets/query.gltf#L192">» example 3D asset</eref>
|
||||
<eref target="https://github.com/coderofsalvation/xrfragment/issues/3">» discussion</eref></t>
|
||||
</section>
|
||||
|
||||
<section anchor="query-parser"><name>Query Parser</name>
|
||||
<t>Here's how to write a query parser:</t>
|
||||
|
||||
<ol spacing="compact">
|
||||
<li>create an associative array/object to store query-arguments as objects</li>
|
||||
<li>detect object id's & properties <tt>foo:1</tt> and <tt>foo</tt> (reference regex: <tt>/^.*:[><=!]?/</tt> )</li>
|
||||
<li>detect excluders like <tt>-foo</tt>,<tt>-foo:1</tt>,<tt>-.foo</tt>,<tt>-/foo</tt> (reference regex: <tt>/^-/</tt> )</li>
|
||||
<li>detect root selectors like <tt>/foo</tt> (reference regex: <tt>/^[-]?\//</tt> )</li>
|
||||
<li>detect class selectors like <tt>.foo</tt> (reference regex: <tt>/^[-]?class$/</tt> )</li>
|
||||
<li>detect number values like <tt>foo:1</tt> (reference regex: <tt>/^[0-9\.]+$/</tt> )</li>
|
||||
<li>expand aliases like <tt>.foo</tt> into <tt>class:foo</tt></li>
|
||||
<li>for every query token split string on <tt>:</tt></li>
|
||||
<li>create an empty array <tt>rules</tt></li>
|
||||
<li>then strip key-operator: convert "-foo" into "foo"</li>
|
||||
<li>add operator and value to rule-array</li>
|
||||
<li>therefore we we set <tt>id</tt> to <tt>true</tt> or <tt>false</tt> (false=excluder <tt>-</tt>)</li>
|
||||
<li>and we set <tt>root</tt> to <tt>true</tt> or <tt>false</tt> (true=<tt>/</tt> root selector is present)</li>
|
||||
<li>we convert key '/foo' into 'foo'</li>
|
||||
<li>finally we add the key/value to the store like <tt>store.foo = {id:false,root:true}</tt> e.g.</li>
|
||||
</ol>
|
||||
<blockquote><t>An example query-parser (which compiles to many languages) can be <eref target="https://github.com/coderofsalvation/xrfragment/blob/main/src/xrfragment/Query.hx">found here</eref></t>
|
||||
</blockquote></section>
|
||||
|
||||
<section anchor="xr-fragment-uri-grammar"><name>XR Fragment URI Grammar</name>
|
||||
|
||||
<artwork>reserved = gen-delims / sub-delims
|
||||
gen-delims = "#" / "&"
|
||||
sub-delims = "," / "="
|
||||
</artwork>
|
||||
<blockquote><t>Example: <tt>://foo.com/my3d.gltf#pos=1,0,0&prio=-5&t=0,100</tt></t>
|
||||
</blockquote><table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Demo</th>
|
||||
<th>Explanation</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><tt>pos=1,2,3</tt></td>
|
||||
<td>vector/coordinate argument e.g.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>pos=1,2,3&rot=0,90,0&q=.foo</tt></td>
|
||||
<td>combinators</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table></section>
|
||||
</section>
|
||||
|
||||
<section anchor="text-in-xr-tagging-linking-to-spatial-objects"><name>Text in XR (tagging,linking to spatial objects)</name>
|
||||
<t>We still think and speak in simple text, not in HTML or RDF.<br />
|
||||
|
||||
|
@ -401,7 +529,7 @@ To keep XR Fragments a lightweight spec, BibTeX is used for text/spatial tagging
|
|||
| │ └ src: ://author.com/article.txt | | |
|
||||
| │ | | @friend{friends |
|
||||
| └── ◻ note_canvas | | ... |
|
||||
| └ src:`data:welcome human @...` | | } |
|
||||
| └ src:`data:welcome human\n@...` | | } |
|
||||
| | +------------------------+
|
||||
| |
|
||||
+--------------------------------------------------------------+
|
||||
|
@ -410,24 +538,24 @@ To keep XR Fragments a lightweight spec, BibTeX is used for text/spatial tagging
|
|||
The beauty is that text (AND visual-meta) in Data URI promotes rich copy-paste.
|
||||
In both cases, the text gets rendered immediately (onto a plane geometry, hence the name '_canvas').
|
||||
The XR Fragment-compatible browser can let the enduser access visual-meta(data)-fields after interacting with the object (contextmenu e.g.).</t>
|
||||
<t>The mapping between 3D objects and text (src-data) is simple:</t>
|
||||
<blockquote><t>additional tagging using <eref target="https://github.com/coderofsalvation/tagbibs">bibs</eref>: to tag spatial object <tt>note_canvas</tt> with 'todo', the enduser can type or speak <tt>@note_canvas@todo</tt></t>
|
||||
</blockquote><t>The mapping between 3D objects and text (src-data) is simple (the :</t>
|
||||
<t>Example:</t>
|
||||
|
||||
<artwork> +------------------------------------------------------------------------------------+
|
||||
| |
|
||||
| index.gltf |
|
||||
| │ |
|
||||
| └── ◻ rentalhouse |
|
||||
| └ class: house |
|
||||
| └ ◻ note |
|
||||
| └ src:`data: todo: call owner |
|
||||
| @house{owner, |
|
||||
| url = {#.house} |
|
||||
| }` |
|
||||
+------------------------------------------------------------------------------------+
|
||||
<artwork> +------------------------------------------------+
|
||||
| |
|
||||
| index.gltf |
|
||||
| │ |
|
||||
| └── ◻ rentalhouse |
|
||||
| └ class: house <----------------- matches -------+
|
||||
| └ ◻ note | |
|
||||
| └ src:`data: todo: call owner | bib |
|
||||
| @owner@house@todo | ----> expands to @house{owner,
|
||||
| | bibtex: }
|
||||
| ` | @contact{
|
||||
+------------------------------------------------+ }
|
||||
</artwork>
|
||||
<t>3D object names and/or classes map to <tt>name</tt> of visual-meta glossary-entries.
|
||||
This allows rich interaction and interlinking between text and 3D objects:</t>
|
||||
<t>Bi-directional mapping between 3D object names and/or classnames and text using bibs,BibTags & XR Fragments, allows for rich interlinking between text and 3D objects:</t>
|
||||
|
||||
<ol spacing="compact">
|
||||
<li>When the user surfs to https://.../index.gltf#rentalhouse the XR Fragments-parser points the enduser to the rentalhouse object, and can show contextual info about it.</li>
|
||||
|
@ -435,11 +563,11 @@ This allows rich interaction and interlinking between text and 3D objects:</t>
|
|||
</ol>
|
||||
</section>
|
||||
|
||||
<section anchor="bibs-enabled-bibtex-lowest-common-denominator-for-tagging-triples"><name>Bibs-enabled BibTeX: lowest common denominator for tagging/triples</name>
|
||||
<section anchor="bibs-bibtex-lowest-common-denominator-for-linking-data"><name>Bibs & BibTeX: lowest common denominator for linking data</name>
|
||||
<blockquote><t>"When a car breaks down, the ones <strong>without</strong> turbosupercharger are easier to fix"</t>
|
||||
</blockquote><t>Unlike XML or JSON, the typeless, unnested, everything-is-text nature of BibTeX tags is a great advantage for introspection.<br />
|
||||
|
||||
It's a missing sensemaking precursor to (eventual) extrospective RDF.<br />
|
||||
It's a missing sensemaking precursor to extrospective RDF.<br />
|
||||
|
||||
BibTeX-appendices are already used in the digital AND physical world (academic books, <eref target="https://visual-meta.info">visual-meta</eref>), perhaps due to its terseness & simplicity.<br />
|
||||
|
||||
|
@ -484,7 +612,7 @@ In that sense, it's one step up from the <tt>.ini</tt> fileformat (which has nev
|
|||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>paperfriendly</td>
|
||||
<td>voice/paper-friendly</td>
|
||||
<td><eref target="https://github.com/coderofsalvation/tagbibs">bibs</eref></td>
|
||||
<td>no</td>
|
||||
</tr>
|
||||
|
@ -648,7 +776,7 @@ In that sense, it's one step up from the <tt>.ini</tt> fileformat (which has nev
|
|||
}
|
||||
}
|
||||
</artwork>
|
||||
<t>The above (de)multiplexes text/metadata, expands bibs, (de)serializes bibtex (and all fits more or less on one A4 paper)</t>
|
||||
<t>The above functions (de)multiplexe text/metadata, expands bibs, (de)serialize bibtex (and all fits more or less on one A4 paper)</t>
|
||||
<blockquote><t>above can be used as a startingpoint for LLVM's to translate/steelman to a more formal form/language.</t>
|
||||
</blockquote>
|
||||
<artwork>str = `
|
||||
|
@ -665,28 +793,19 @@ tags.find( (t) => t.k == 'flap{' ).v.asdf = 1 // edit tag
|
|||
tags.push({ k:'bar{', v:{abc:123} }) // add tag
|
||||
console.log( xrtext.encode(text,tags) ) // multiplex text & bibtex back together
|
||||
</artwork>
|
||||
<t>This outputs:</t>
|
||||
|
||||
<artwork>@{references-start}
|
||||
@misc{emilyHegland/Edgar&Frod,
|
||||
author = {Emily Hegland},
|
||||
title = {Edgar & Frode Hegland, November 2021},
|
||||
year = {2021},
|
||||
month = {11},
|
||||
}
|
||||
</artwork>
|
||||
<t>The above BibTeX-flavor can be imported, however will be rewritten to Dumb BibTeX, to satisfy rule 2 & 5, as well as the <eref target="#core-principle">core principle</eref></t>
|
||||
<artwork>hello world
|
||||
|
||||
<artwork>@visual-meta{
|
||||
version = {1.1},
|
||||
generator = {Author 7.6.2 (1064)},
|
||||
section = {visual-meta-header}
|
||||
|
||||
@greeting{hello,
|
||||
}
|
||||
@misc{emilyHegland/Edgar&Frod,
|
||||
author = {Emily Hegland},
|
||||
title = {Edgar & Frode Hegland, November 2021},
|
||||
year = {2021},
|
||||
month = {11},
|
||||
section = {references}
|
||||
@{some-section}
|
||||
@flap{
|
||||
asdf = {1}
|
||||
}
|
||||
@bar{
|
||||
abc = {123}
|
||||
}
|
||||
</artwork>
|
||||
</section>
|
||||
|
@ -694,7 +813,7 @@ console.log( xrtext.encode(text,tags) ) // multiplex text & bibtex bac
|
|||
|
||||
<section anchor="hyper-copy-paste"><name>HYPER copy/paste</name>
|
||||
<t>The previous example, offers something exciting compared to simple copy/paste of 3D objects or text.
|
||||
XR Fragment allows HYPER-copy/paste: time, space and text interlinked.
|
||||
XR Text according to the XR Fragment spec, allows HYPER-copy/paste: time, space and text interlinked.
|
||||
Therefore, the enduser in an XR Fragment-compatible browser can copy/paste/share data in these ways:</t>
|
||||
|
||||
<ol spacing="compact">
|
||||
|
@ -704,134 +823,6 @@ Therefore, the enduser in an XR Fragment-compatible browser can copy/paste/share
|
|||
</ol>
|
||||
</section>
|
||||
|
||||
<section anchor="xr-fragment-queries"><name>XR Fragment queries</name>
|
||||
<t>Include, exclude, hide/shows objects using space-separated strings:</t>
|
||||
|
||||
<ul spacing="compact">
|
||||
<li><tt>#q=cube</tt></li>
|
||||
<li><tt>#q=cube -ball_inside_cube</tt></li>
|
||||
<li><tt>#q=* -sky</tt></li>
|
||||
<li><tt>#q=-.language .english</tt></li>
|
||||
<li><tt>#q=cube&rot=0,90,0</tt></li>
|
||||
<li><tt>#q=price:>2 price:<5</tt></li>
|
||||
</ul>
|
||||
<t>It's simple but powerful syntax which allows <b>css</b>-like class/id-selectors with a searchengine prompt-style feeling:</t>
|
||||
|
||||
<ol spacing="compact">
|
||||
<li>queries are showing/hiding objects <strong>only</strong> when defined as <tt>src</tt> value (prevents sharing of scene-tampered URL's).</li>
|
||||
<li>queries are highlighting objects when defined in the top-Level (browser) URL (bar).</li>
|
||||
<li>search words like <tt>cube</tt> and <tt>foo</tt> in <tt>#q=cube foo</tt> are matched against 3D object names or custom metadata-key(values)</li>
|
||||
<li>search words like <tt>cube</tt> and <tt>foo</tt> in <tt>#q=cube foo</tt> are matched against tags (BibTeX) inside plaintext <tt>src</tt> values like <tt>@cube{redcube, ...</tt> e.g.</li>
|
||||
<li><tt>#</tt> equals <tt>#q=*</tt></li>
|
||||
<li>words starting with <tt>.</tt> like <tt>.german</tt> match class-metadata of 3D objects like <tt>"class":"german"</tt></li>
|
||||
<li>words starting with <tt>.</tt> like <tt>.german</tt> match class-metadata of (BibTeX) tags in XR Text objects like <tt>@german{KarlHeinz, ...</tt> e.g.</li>
|
||||
</ol>
|
||||
<blockquote><t><strong>For example</strong>: <tt>#q=.foo</tt> is a shorthand for <tt>#q=class:foo</tt>, which will select objects with custom property <tt>class</tt>:<tt>foo</tt>. Just a simple <tt>#q=cube</tt> will simply select an object named <tt>cube</tt>.</t>
|
||||
</blockquote>
|
||||
<ul spacing="compact">
|
||||
<li>see <eref target="https://coderofsalvation.github.io/xrfragment.media/queries.mp4">an example video here</eref></li>
|
||||
</ul>
|
||||
|
||||
<section anchor="including-excluding"><name>including/excluding</name>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>operator</th>
|
||||
<th>info</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><tt>*</tt></td>
|
||||
<td>select all objects (only useful in <tt>src</tt> custom property)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>-</tt></td>
|
||||
<td>removes/hides object(s)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>:</tt></td>
|
||||
<td>indicates an object-embedded custom property key/value</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>.</tt></td>
|
||||
<td>alias for <tt>"class" :".foo"</tt> equals <tt>class:foo</tt></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>></tt> <tt><</tt></td>
|
||||
<td>compare float or int number</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>/</tt></td>
|
||||
<td>reference to root-scene.<br />
|
||||
Useful in case of (preventing) showing/hiding objects in nested scenes (instanced by <tt>src</tt>) (*)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table><blockquote><t>* = <tt>#q=-/cube</tt> hides object <tt>cube</tt> only in the root-scene (not nested <tt>cube</tt> objects)<br />
|
||||
<tt>#q=-cube</tt> hides both object <tt>cube</tt> in the root-scene <b>AND</b> nested <tt>skybox</tt> objects |</t>
|
||||
</blockquote><t><eref target="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/q.js">» example implementation</eref>
|
||||
<eref target="https://github.com/coderofsalvation/xrfragment/blob/main/example/assets/query.gltf#L192">» example 3D asset</eref>
|
||||
<eref target="https://github.com/coderofsalvation/xrfragment/issues/3">» discussion</eref></t>
|
||||
</section>
|
||||
|
||||
<section anchor="query-parser"><name>Query Parser</name>
|
||||
<t>Here's how to write a query parser:</t>
|
||||
|
||||
<ol spacing="compact">
|
||||
<li>create an associative array/object to store query-arguments as objects</li>
|
||||
<li>detect object id's & properties <tt>foo:1</tt> and <tt>foo</tt> (reference regex: <tt>/^.*:[><=!]?/</tt> )</li>
|
||||
<li>detect excluders like <tt>-foo</tt>,<tt>-foo:1</tt>,<tt>-.foo</tt>,<tt>-/foo</tt> (reference regex: <tt>/^-/</tt> )</li>
|
||||
<li>detect root selectors like <tt>/foo</tt> (reference regex: <tt>/^[-]?\//</tt> )</li>
|
||||
<li>detect class selectors like <tt>.foo</tt> (reference regex: <tt>/^[-]?class$/</tt> )</li>
|
||||
<li>detect number values like <tt>foo:1</tt> (reference regex: <tt>/^[0-9\.]+$/</tt> )</li>
|
||||
<li>expand aliases like <tt>.foo</tt> into <tt>class:foo</tt></li>
|
||||
<li>for every query token split string on <tt>:</tt></li>
|
||||
<li>create an empty array <tt>rules</tt></li>
|
||||
<li>then strip key-operator: convert "-foo" into "foo"</li>
|
||||
<li>add operator and value to rule-array</li>
|
||||
<li>therefore we we set <tt>id</tt> to <tt>true</tt> or <tt>false</tt> (false=excluder <tt>-</tt>)</li>
|
||||
<li>and we set <tt>root</tt> to <tt>true</tt> or <tt>false</tt> (true=<tt>/</tt> root selector is present)</li>
|
||||
<li>we convert key '/foo' into 'foo'</li>
|
||||
<li>finally we add the key/value to the store like <tt>store.foo = {id:false,root:true}</tt> e.g.</li>
|
||||
</ol>
|
||||
<blockquote><t>An example query-parser (which compiles to many languages) can be <eref target="https://github.com/coderofsalvation/xrfragment/blob/main/src/xrfragment/Query.hx">found here</eref></t>
|
||||
</blockquote></section>
|
||||
|
||||
<section anchor="xr-fragment-uri-grammar"><name>XR Fragment URI Grammar</name>
|
||||
|
||||
<artwork>reserved = gen-delims / sub-delims
|
||||
gen-delims = "#" / "&"
|
||||
sub-delims = "," / "="
|
||||
</artwork>
|
||||
<blockquote><t>Example: <tt>://foo.com/my3d.gltf#pos=1,0,0&prio=-5&t=0,100</tt></t>
|
||||
</blockquote><table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Demo</th>
|
||||
<th>Explanation</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><tt>pos=1,2,3</tt></td>
|
||||
<td>vector/coordinate argument e.g.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>pos=1,2,3&rot=0,90,0&q=.foo</tt></td>
|
||||
<td>combinators</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table></section>
|
||||
</section>
|
||||
|
||||
<section anchor="security-considerations"><name>Security Considerations</name>
|
||||
<t>Since XR Text contains metadata too, the user should be able to set up tagging-rules, so the copy-paste feature can :</t>
|
||||
|
||||
|
|
Loading…
Reference in New Issue