Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions scripts/build-graph.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -247,14 +247,16 @@ export function parseGlossary(repoRoot) {
continue;
}
const termMatch = line.match(
/^\*\*\[?([^\]*]+)\]?\s*(?:\([^)]*\))?\*\*:\s*(.*)/,
/^\*\*(?:\[([^\]]+)\]\(([^)]+)\)|([^*]+))\*\*:\s*(.*)/,
);
if (termMatch) {
terms.push({
term: termMatch[1].trim().replace(/\[|\]/g, ""),
definition: termMatch[2].trim(),
const term = {
term: (termMatch[1] ?? termMatch[3]).trim(),
definition: termMatch[4].trim(),
category: currentCategory,
});
};
if (termMatch[2]) term.href = termMatch[2].trim();
terms.push(term);
}
}
return terms;
Expand Down
33 changes: 22 additions & 11 deletions src/data/glossary.json
Original file line number Diff line number Diff line change
Expand Up @@ -142,57 +142,68 @@
{
"term": "ERC-3643",
"definition": "Ethereum standard for permissioned tokenized securities with built-in compliance framework",
"category": "Standards & Protocols"
"category": "Standards & Protocols",
"href": "https://eips.ethereum.org/EIPS/eip-3643"
},
{
"term": "CMTAT",
"definition": "CMTA's open standard for tokenizing financial instruments, using a rule-engine and allowlist model rather than an identity registry. Blockchain-agnostic, with reference implementations on EVM, Tezos, Solana, and a privacy-preserving Aztec/Noir variant",
"category": "Standards & Protocols"
"category": "Standards & Protocols",
"href": "https://cmta.ch/standards/cmta-token-cmtat"
},
{
"term": "ERC-7573",
"definition": "Standard for conditional cross-chain settlement coordination",
"category": "Standards & Protocols"
"category": "Standards & Protocols",
"href": "https://ercs.ethereum.org/ERCS/erc-7573"
},
{
"term": "EIP-6123",
"definition": "Ethereum standard for derivatives contracts with automated lifecycle management",
"category": "Standards & Protocols"
"category": "Standards & Protocols",
"href": "https://eips.ethereum.org/EIPS/eip-6123"
},
{
"term": "EIP-5564",
"definition": "Stealth address standard for unlinkable payments",
"category": "Standards & Protocols"
"category": "Standards & Protocols",
"href": "https://eips.ethereum.org/EIPS/eip-5564"
},
{
"term": "EIP-7805",
"definition": "Fork Choice Inclusion Lists (FOCIL) standard for censorship resistance through committee-enforced transaction inclusion",
"category": "Standards & Protocols"
"category": "Standards & Protocols",
"href": "https://eips.ethereum.org/EIPS/eip-7805"
},
{
"term": "EIP-7701",
"definition": "Native account abstraction standard enabling custom account validation logic, institutional key management, and ZK-based privacy systems",
"category": "Standards & Protocols"
"category": "Standards & Protocols",
"href": "https://eips.ethereum.org/EIPS/eip-7701"
},
{
"term": "ERC-7945",
"definition": "Standard for confidential token transfers using cryptographic commitments to hide balances and amounts",
"category": "Standards & Protocols"
"category": "Standards & Protocols",
"href": "https://ercs.ethereum.org/ERCS/erc-7945"
},
{
"term": "ERC-8065",
"definition": "ZK token wrapper standard enabling privacy for existing ERC-20 tokens through shielded wrapping",
"category": "Standards & Protocols"
"category": "Standards & Protocols",
"href": "https://ercs.ethereum.org/ERCS/erc-8065"
},
{
"term": "ISO 20022",
"definition": "International messaging standard for financial services communication",
"category": "Standards & Protocols"
"category": "Standards & Protocols",
"href": "https://www.iso20022.org/"
},
{
"term": "ICMA BDT",
"definition": "International Capital Market Association Bond Data Taxonomy for standardized bond information",
"category": "Standards & Protocols"
"category": "Standards & Protocols",
"href": "https://www.icmagroup.org/market-practice-and-regulatory-policy/repo-and-collateral-markets/legal-documentation/global-master-repurchase-agreement-gmra/"
},
{
"term": "FHE (Fully Homomorphic Encryption)",
Expand Down
11 changes: 11 additions & 0 deletions src/lib/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import type { Tokens } from 'marked';
import graphData from '../data/graph.json';
import type { GraphData } from './graph-types';
import { toContentSlug } from './slugify';
import { site } from './site';

// ─────────────────────────────────────────────────────────────────────────────
// CONTENT_DIRS — must agree with guide/scripts/build-graph.mjs#CONTENT_DIRS.
Expand Down Expand Up @@ -155,6 +156,14 @@ function isMdHref(href: string): boolean {
return href.endsWith('.md') || href.includes('.md#') || href.includes('.md?');
}

function resolveMapRootDocHref(href: string): string | null {
const match = href.match(
/^(README|CONTRIBUTING|CHANGELOG|GLOSSARY)\.md((?:[?#].*)?)$/,
);
if (!match) return null;
return `${site.mapRepo}/blob/master/${match[1]}.md${match[2]}`;
}

/**
* Map one ethsystems/map href to a Guide route, or return it unchanged.
*
Expand All @@ -165,6 +174,8 @@ function isMdHref(href: string): boolean {
*/
export function resolveHref(href: string): string {
if (isAbsoluteOrAnchor(href)) return href;
const rootDocHref = resolveMapRootDocHref(href);
if (rootDocHref) return rootDocHref;
if (isMdHref(href)) return resolveMdHref(href)?.route ?? resolveRouteHref(href) ?? href;
return resolveRouteHref(href) ?? href;
}
Expand Down
9 changes: 7 additions & 2 deletions src/pages/glossary.astro
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@
import BaseLayout from '../layouts/BaseLayout.astro';
import PageHeader from '../components/PageHeader.astro';
import glossaryData from '../data/glossary.json';
import { resolveHref } from '../lib/render';
import { inlineMd } from '../lib/inlineMarkdown';

interface Term {
term: string;
href?: string;
definition: string;
category: string;
}
Expand Down Expand Up @@ -114,8 +117,10 @@ const pageDescription = `${allTerms.length} terms used across the EthSystems gui
data-term={entry.term.toLowerCase()}
data-def={entry.definition.toLowerCase()}
>
<div class="g-term-name">{entry.term}</div>
<div class="g-term-def">{entry.definition}</div>
<div class="g-term-name">
{entry.href ? <a href={resolveHref(entry.href)}>{entry.term}</a> : entry.term}
</div>
<div class="g-term-def" set:html={inlineMd(entry.definition)} />
</div>
))}
</div>
Expand Down
40 changes: 40 additions & 0 deletions tests/build-graph.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ import {
extractSummary,
extractLinks,
classifyEdge,
parseGlossary,
buildGraph,
} from '../scripts/build-graph.mjs';
import { join } from 'path';
import { mkdtempSync, rmSync, writeFileSync } from 'fs';
import { tmpdir } from 'os';

// ---------------------------------------------------------------------------
// parseFrontmatter
Expand Down Expand Up @@ -225,6 +228,43 @@ describe('classifyEdge', () => {
});
});

// ---------------------------------------------------------------------------
// parseGlossary
// ---------------------------------------------------------------------------

describe('parseGlossary', () => {
it('preserves linked term hrefs and definition markdown', () => {
const repoRoot = mkdtempSync(join(tmpdir(), 'ethsystems-glossary-'));
try {
writeFileSync(
join(repoRoot, 'GLOSSARY.md'),
`### Standards

**[ERC-3643](https://eips.ethereum.org/EIPS/eip-3643)**: Permissioned token standard.
**vOPRF (Verifiable OPRF)**: See [RFC 9497](https://www.rfc-editor.org/rfc/rfc9497.html).
**Attestations**: See [Pattern](patterns/pattern-verifiable-attestation.md).
`,
);

const glossary = parseGlossary(repoRoot);

expect(glossary[0]).toEqual({
term: 'ERC-3643',
href: 'https://eips.ethereum.org/EIPS/eip-3643',
definition: 'Permissioned token standard.',
category: 'Standards',
});
expect(glossary[1].href).toBeUndefined();
expect(glossary[1].definition).toContain('[RFC 9497]');
expect(glossary[2].definition).toContain(
'[Pattern](patterns/pattern-verifiable-attestation.md)',
);
} finally {
rmSync(repoRoot, { recursive: true, force: true });
}
});
});

// ---------------------------------------------------------------------------
// buildGraph (integration test against real repo)
// ---------------------------------------------------------------------------
Expand Down
25 changes: 24 additions & 1 deletion tests/render-links.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, it, expect } from 'vitest';
import { renderMarkdown } from '../src/lib/render';
import { renderMarkdown, resolveHref } from '../src/lib/render';
import { inlineMd } from '../src/lib/inlineMarkdown';

function href(md: string): string {
Expand Down Expand Up @@ -32,9 +32,32 @@ describe('renderMarkdown link rewriting', () => {
);
expect(href('[map](/map/)')).toBe('/map/');
});

it('routes root map documents to their GitHub source', () => {
expect(resolveHref('CONTRIBUTING.md#crops-evaluation')).toBe(
'https://github.com/ethsystems/map/blob/master/CONTRIBUTING.md#crops-evaluation',
);
});

});

describe('inlineMd link rewriting', () => {
it('renders glossary definition links', () => {
expect(
inlineMd('See [RFC 9497](https://www.rfc-editor.org/rfc/rfc9497.html).'),
).toContain('href="https://www.rfc-editor.org/rfc/rfc9497.html"');

expect(
inlineMd('See [Pattern](patterns/pattern-verifiable-attestation.md).'),
).toContain('<a href="/patterns/pattern-verifiable-attestation/">Pattern</a>');

expect(
inlineMd('See [CROPS](CONTRIBUTING.md#crops-evaluation).'),
).toContain(
'href="https://github.com/ethsystems/map/blob/master/CONTRIBUTING.md#crops-evaluation"',
);
});

it('rewrites map hrefs in frontmatter strings', () => {
// Regression: pattern-page `post_quantum.mitigation` shipped verbatim.
expect(inlineMd('See [Post-Quantum Threats](../domains/post-quantum.md).')).toContain(
Expand Down
Loading