feat(#59): implement wiki-link parser

- Created wiki-link-parser.ts utility for parsing [[links]] syntax
- Supports multiple formats: [[Page Name]], [[Page|display]], [[slug]]
- Returns parsed links with target, display text, and position info
- Handles edge cases: nested brackets, escaped brackets, code blocks
- Code block awareness: skips links in inline code, fenced blocks, and indented code
- Comprehensive test suite with 43 passing tests (100% coverage)
- Updated README.md with parser documentation

Implements KNOW-007 (Issue #59) - Wiki-style linking foundation
This commit is contained in:
Jason Woltje
2026-01-29 17:42:49 -06:00
parent 95833fb4ea
commit 1e5fcd19a4
10 changed files with 2068 additions and 0 deletions
+134
View File
@@ -1,5 +1,139 @@
# Knowledge Module Utilities
## Wiki-Link Parser
### Overview
The `wiki-link-parser.ts` utility provides parsing of wiki-style `[[links]]` from markdown content. This is the foundation for the Knowledge Module's linking system.
### Features
- **Multiple Link Formats**: Supports title, slug, and display text variations
- **Position Tracking**: Returns exact positions for link replacement or highlighting
- **Code Block Awareness**: Skips links in code blocks (inline and fenced)
- **Escape Support**: Respects escaped brackets `\[[not a link]]`
- **Edge Case Handling**: Properly handles nested brackets, empty links, and malformed syntax
### Usage
```typescript
import { parseWikiLinks } from './utils/wiki-link-parser';
const content = 'See [[Main Page]] and [[Getting Started|start here]].';
const links = parseWikiLinks(content);
// Result:
// [
// {
// raw: '[[Main Page]]',
// target: 'Main Page',
// displayText: 'Main Page',
// start: 4,
// end: 17
// },
// {
// raw: '[[Getting Started|start here]]',
// target: 'Getting Started',
// displayText: 'start here',
// start: 22,
// end: 52
// }
// ]
```
### Supported Link Formats
#### Basic Link (by title)
```markdown
[[Page Name]]
```
Links to a page by its title. Display text will be "Page Name".
#### Link with Display Text
```markdown
[[Page Name|custom display]]
```
Links to "Page Name" but displays "custom display".
#### Link by Slug
```markdown
[[page-slug-name]]
```
Links to a page by its URL slug (kebab-case).
### Edge Cases
#### Nested Brackets
```markdown
[[Page [with] brackets]] ✓ Parsed correctly
```
Single brackets inside link text are allowed.
#### Code Blocks (Not Parsed)
```markdown
Use `[[WikiLink]]` syntax for linking.
\`\`\`typescript
const link = "[[not parsed]]";
\`\`\`
```
Links inside inline code or fenced code blocks are ignored.
#### Escaped Brackets
```markdown
\[[not a link]] but [[real link]] works
```
Escaped brackets are not parsed as links.
#### Empty or Invalid Links
```markdown
[[]] ✗ Empty link (ignored)
[[ ]] ✗ Whitespace only (ignored)
[[ Target ]] ✓ Trimmed to "Target"
```
### Return Type
```typescript
interface WikiLink {
raw: string; // Full matched text: "[[Page Name]]"
target: string; // Target page: "Page Name"
displayText: string; // Display text: "Page Name" or custom
start: number; // Start position in content
end: number; // End position in content
}
```
### Testing
Comprehensive test suite (100% coverage) includes:
- Basic parsing (single, multiple, consecutive links)
- Display text variations
- Edge cases (brackets, escapes, empty links)
- Code block exclusion (inline, fenced, indented)
- Position tracking
- Unicode support
- Malformed input handling
Run tests:
```bash
pnpm test --filter=@mosaic/api -- wiki-link-parser.spec.ts
```
### Integration
This parser is designed to work with the Knowledge Module's linking system:
1. **On Entry Save**: Parse `[[links]]` from content
2. **Create Link Records**: Store references in database
3. **Backlink Tracking**: Maintain bidirectional link relationships
4. **Link Rendering**: Replace `[[links]]` with HTML anchors
See related issues:
- #59 - Wiki-link parser (this implementation)
- Future: Link resolution and storage
- Future: Backlink display and navigation
## Markdown Rendering
### Overview