eyeling 1.24.10 → 1.24.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12077,8 +12077,10 @@ class PrefixEnv {
12077
12077
  }
12078
12078
 
12079
12079
  expandQName(q) {
12080
- if (q.includes(':')) {
12081
- const [p, local] = q.split(':', 2);
12080
+ const sep = typeof q === 'string' ? q.indexOf(':') : -1;
12081
+ if (sep >= 0) {
12082
+ const p = q.slice(0, sep);
12083
+ const local = q.slice(sep + 1);
12082
12084
  const base = this.map[p] || '';
12083
12085
  if (base) return base + local;
12084
12086
  return q;
package/eyeling.js CHANGED
@@ -12077,8 +12077,10 @@ class PrefixEnv {
12077
12077
  }
12078
12078
 
12079
12079
  expandQName(q) {
12080
- if (q.includes(':')) {
12081
- const [p, local] = q.split(':', 2);
12080
+ const sep = typeof q === 'string' ? q.indexOf(':') : -1;
12081
+ if (sep >= 0) {
12082
+ const p = q.slice(0, sep);
12083
+ const local = q.slice(sep + 1);
12082
12084
  const base = this.map[p] || '';
12083
12085
  if (base) return base + local;
12084
12086
  return q;
package/lib/prelude.js CHANGED
@@ -398,8 +398,10 @@ class PrefixEnv {
398
398
  }
399
399
 
400
400
  expandQName(q) {
401
- if (q.includes(':')) {
402
- const [p, local] = q.split(':', 2);
401
+ const sep = typeof q === 'string' ? q.indexOf(':') : -1;
402
+ if (sep >= 0) {
403
+ const p = q.slice(0, sep);
404
+ const local = q.slice(sep + 1);
403
405
  const base = this.map[p] || '';
404
406
  if (base) return base + local;
405
407
  return q;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyeling",
3
- "version": "1.24.10",
3
+ "version": "1.24.12",
4
4
  "description": "A minimal Notation3 (N3) reasoner in JavaScript.",
5
5
  "main": "./index.js",
6
6
  "keywords": [
package/test/api.test.js CHANGED
@@ -1370,6 +1370,32 @@ res:CITY_Chañaral rdfs:label "Chañaral".
1370
1370
  },
1371
1371
  },
1372
1372
 
1373
+ {
1374
+ name: '52c parse: prefixed local names preserve colons after the prefix separator',
1375
+ opt: ['-n'],
1376
+ input: `@prefix : <http://example.org/> .
1377
+
1378
+ :foo: a :Bar .
1379
+
1380
+ {
1381
+ <http://example.org/foo:> a <http://example.org/Bar> .
1382
+ }
1383
+ =>
1384
+ {
1385
+ :result :has :success-literal-24 .
1386
+ }.
1387
+
1388
+ {
1389
+ :result :has :success-literal-24 .
1390
+ }
1391
+ =>
1392
+ {
1393
+ :test :is true .
1394
+ }.
1395
+ `,
1396
+ expect: [/:result\s+:has\s+:success-literal-24\s*\./, /:test\s+:is\s+true\s*\./],
1397
+ },
1398
+
1373
1399
  {
1374
1400
  name: '53 --stream: prints prefixes used in input (not just derived output) before streaming triples',
1375
1401
  opt: ['--stream', '-n'],
@@ -646,11 +646,21 @@ async function main() {
646
646
  };
647
647
  })
648
648
  : [];
649
+ const renderedPanel = document.getElementById('output-rendered');
650
+ const renderedTab = document.getElementById('output-rendered-tab');
651
+ const sourceTab = document.getElementById('output-source-tab');
652
+ const sourceWrapper = document.getElementById('output-source');
649
653
  return {
650
654
  status: statusEl ? String(statusEl.textContent || '') : '',
651
655
  output: outputCm && typeof outputCm.getValue === 'function'
652
656
  ? String(outputCm.getValue() || '')
653
657
  : (outputTa ? String(outputTa.value || '') : ''),
658
+ renderedText: renderedPanel ? String(renderedPanel.textContent || '') : '',
659
+ renderedHtml: renderedPanel ? String(renderedPanel.innerHTML || '') : '',
660
+ renderedHidden: renderedPanel ? !!renderedPanel.hidden : true,
661
+ sourceHidden: sourceWrapper ? sourceWrapper.classList.contains('markdown-source-hidden') : true,
662
+ renderedTabSelected: renderedTab ? renderedTab.getAttribute('aria-selected') === 'true' : false,
663
+ sourceTabSelected: sourceTab ? sourceTab.getAttribute('aria-selected') === 'true' : false,
654
664
  highlighted,
655
665
  };
656
666
  })()`)) || { status: '', output: '', highlighted: [] }
@@ -681,6 +691,24 @@ async function main() {
681
691
  })()`);
682
692
  }
683
693
 
694
+ async function clickOutputSourceTab() {
695
+ await evalInPage(`(() => {
696
+ const btn = document.getElementById('output-source-tab');
697
+ if (!btn) throw new Error('output-source-tab not found');
698
+ btn.click();
699
+ return true;
700
+ })()`);
701
+ }
702
+
703
+ async function clickOutputRenderedTab() {
704
+ await evalInPage(`(() => {
705
+ const btn = document.getElementById('output-rendered-tab');
706
+ if (!btn) throw new Error('output-rendered-tab not found');
707
+ btn.click();
708
+ return true;
709
+ })()`);
710
+ }
711
+
684
712
  async function loadUrlIntoEditor(url) {
685
713
  const payload = JSON.stringify(String(url));
686
714
  await evalInPage(`(() => {
@@ -720,7 +748,7 @@ ${JSON.stringify(last, null, 2)}`);
720
748
  const fuseProgram = fs.readFileSync(path.join(ROOT, 'examples', 'fuse.n3'), 'utf8');
721
749
  const outputStringProgram = `@prefix : <#> .
722
750
  @prefix log: <http://www.w3.org/2000/10/swap/log#> .
723
- :report log:outputString "Hello from output string\nLine 2\n" .
751
+ :report log:outputString "## Hello from output string\n\nLine 2 with **bold** and [Eyeling](https://example.org/eyeling)\n" .
724
752
  `;
725
753
 
726
754
  // 1) Baseline smoke test: the default program runs to completion.
@@ -778,13 +806,31 @@ ${JSON.stringify(last, null, 2)}`);
778
806
  .startsWith('Done') && /Hello from output string/.test(String(st.output || '')),
779
807
  20000,
780
808
  );
781
- assert.match(rendered.output, /^Hello from output string\nLine 2\n?$/m, 'Expected rendered outputString text');
809
+ assert.match(rendered.output, /^## Hello from output string\n\nLine 2 with \*\*bold\*\*/m, 'Expected markdown source output');
782
810
  assert.doesNotMatch(
783
811
  rendered.output,
784
812
  /:report\s+log:outputString\s+"|# Derived triples/i,
785
813
  'Expected clean rendered output without raw triples',
786
814
  );
787
- ok('playground renders log:outputString cleanly in Output');
815
+ assert.equal(rendered.renderedHidden, false, 'Expected rendered Markdown tab to be visible by default');
816
+ assert.equal(rendered.sourceHidden, true, 'Expected Markdown source tab to be hidden by default');
817
+ assert.equal(rendered.renderedTabSelected, true, 'Expected Rendered tab to be selected by default');
818
+ assert.match(rendered.renderedText, /Hello from output string/, 'Expected rendered Markdown text');
819
+ assert.match(rendered.renderedHtml, /<h2>Hello from output string<\/h2>/i, 'Expected Markdown heading rendering');
820
+ assert.match(rendered.renderedHtml, /<strong>bold<\/strong>/i, 'Expected Markdown bold rendering');
821
+ assert.match(rendered.renderedHtml, /href="https:\/\/example\.org\/eyeling"/i, 'Expected Markdown link rendering');
822
+
823
+ await clickOutputSourceTab();
824
+ const sourceView = await getPlaygroundState();
825
+ assert.equal(sourceView.sourceTabSelected, true, 'Expected Markdown source tab to be selectable');
826
+ assert.equal(sourceView.renderedHidden, true, 'Expected rendered Markdown panel to hide after selecting source');
827
+ assert.equal(sourceView.sourceHidden, false, 'Expected source editor to show after selecting source');
828
+ assert.match(sourceView.output, /^## Hello from output string/m, 'Expected source tab to show markdown source');
829
+
830
+ await clickOutputRenderedTab();
831
+ const renderedAgain = await getPlaygroundState();
832
+ assert.equal(renderedAgain.renderedTabSelected, true, 'Expected Rendered tab to be selectable again');
833
+ ok('playground renders log:outputString Markdown with Rendered/Markdown source tabs');
788
834
 
789
835
  // 5) URL-loaded repository examples should auto-load matching examples/builtin/<stem>.js.
790
836
  await loadUrlIntoEditor('https://raw.githubusercontent.com/eyereasoner/eyeling/refs/heads/main/examples/sudoku.n3');