@dmthepm/commune 0.5.0 → 0.5.2
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.
package/lib/lib/graph.d.ts
CHANGED
|
@@ -163,6 +163,14 @@ export declare function loadContentEntries(options?: GraphOptions): Promise<Cont
|
|
|
163
163
|
* matters when two pieces of content claim the same name, and is a content bug
|
|
164
164
|
* either way.
|
|
165
165
|
*/
|
|
166
|
+
/**
|
|
167
|
+
* The key a wikilink is looked up by. Case-folded, and typographic quotes
|
|
168
|
+
* folded to their ASCII forms: a title in frontmatter is written with a
|
|
169
|
+
* straight apostrophe, but by the time the remark plugin sees the link text
|
|
170
|
+
* smartypants has curled it, so `[[Andy's Notes]]` arrived as `Andy’s Notes`
|
|
171
|
+
* and rendered as plain text.
|
|
172
|
+
*/
|
|
173
|
+
export declare function linkKey(name: string): string;
|
|
166
174
|
export declare function buildLinkLookup(entries: ContentEntry[]): Map<string, LinkTarget>;
|
|
167
175
|
/**
|
|
168
176
|
* Build the url resolution table: canonical `urlPath` → target.
|
package/lib/lib/graph.js
CHANGED
|
@@ -243,6 +243,20 @@ export async function loadContentEntries(options = {}) {
|
|
|
243
243
|
* matters when two pieces of content claim the same name, and is a content bug
|
|
244
244
|
* either way.
|
|
245
245
|
*/
|
|
246
|
+
/**
|
|
247
|
+
* The key a wikilink is looked up by. Case-folded, and typographic quotes
|
|
248
|
+
* folded to their ASCII forms: a title in frontmatter is written with a
|
|
249
|
+
* straight apostrophe, but by the time the remark plugin sees the link text
|
|
250
|
+
* smartypants has curled it, so `[[Andy's Notes]]` arrived as `Andy’s Notes`
|
|
251
|
+
* and rendered as plain text.
|
|
252
|
+
*/
|
|
253
|
+
export function linkKey(name) {
|
|
254
|
+
return name
|
|
255
|
+
.trim()
|
|
256
|
+
.replace(/[\u2018\u2019\u02BC]/g, "'")
|
|
257
|
+
.replace(/[\u201C\u201D]/g, '"')
|
|
258
|
+
.toLowerCase();
|
|
259
|
+
}
|
|
246
260
|
export function buildLinkLookup(entries) {
|
|
247
261
|
const lookup = new Map();
|
|
248
262
|
for (const entry of entries) {
|
|
@@ -252,9 +266,9 @@ export function buildLinkLookup(entries) {
|
|
|
252
266
|
urlPath: entry.urlPath,
|
|
253
267
|
};
|
|
254
268
|
for (const alias of entry.aliases) {
|
|
255
|
-
lookup.set(alias
|
|
269
|
+
lookup.set(linkKey(alias), target);
|
|
256
270
|
}
|
|
257
|
-
lookup.set(entry.title
|
|
271
|
+
lookup.set(linkKey(entry.title), target);
|
|
258
272
|
}
|
|
259
273
|
return lookup;
|
|
260
274
|
}
|
package/lib/remark-wikilinks.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* graph core in `src/lib/graph.ts` — not here.
|
|
11
11
|
*/
|
|
12
12
|
import { visit } from 'unist-util-visit';
|
|
13
|
-
import { getLinkLookup } from "./lib/graph.js";
|
|
13
|
+
import { getLinkLookup, linkKey } from "./lib/graph.js";
|
|
14
14
|
/**
|
|
15
15
|
* Remark plugin function.
|
|
16
16
|
*
|
|
@@ -49,8 +49,7 @@ export default function remarkWikiLinks({ root } = {}) {
|
|
|
49
49
|
}
|
|
50
50
|
// Resolve WikiLink to URL path
|
|
51
51
|
const trimmedLinkText = linkText.trim();
|
|
52
|
-
const
|
|
53
|
-
const resolved = lookup.get(lookupKey);
|
|
52
|
+
const resolved = lookup.get(linkKey(trimmedLinkText));
|
|
54
53
|
if (resolved) {
|
|
55
54
|
// Create a proper link node with correct URL for collection
|
|
56
55
|
// Add data-collection attribute to identify research links for styling
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dmthepm/commune",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.5.
|
|
4
|
+
"version": "0.5.2",
|
|
5
5
|
"description": "An Astro wiki engine with WikiLinks, sliding panes, backlinks and static search, plus a commune CLI that queries the content graph and checks links",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"keywords": [
|
|
@@ -34,15 +34,16 @@
|
|
|
34
34
|
if (note?.isStarred) {
|
|
35
35
|
// Check if star isn't already there
|
|
36
36
|
if (!link.querySelector('.star-indicator-inline') && !link.nextElementSibling?.classList?.contains('star-indicator-inline')) {
|
|
37
|
-
//
|
|
37
|
+
// The star must not land on a line of its own, but the link itself
|
|
38
|
+
// has to wrap like any other run of text: a whole-link nowrap
|
|
39
|
+
// pushed long titles onto their own line on phones. A no-break
|
|
40
|
+
// space glues the star to the link's last word and nothing else.
|
|
38
41
|
const wrapper = document.createElement('span');
|
|
39
|
-
wrapper.style.whiteSpace = 'nowrap';
|
|
40
|
-
wrapper.style.display = 'inline';
|
|
41
42
|
|
|
42
43
|
// Create star as a separate clickable element (not part of the link)
|
|
43
44
|
const star = document.createElement('span');
|
|
44
45
|
star.className = 'star-indicator-inline';
|
|
45
|
-
star.textContent = '
|
|
46
|
+
star.textContent = '\u00A0⭐';
|
|
46
47
|
star.setAttribute('aria-label', 'Top 5% most linked - click to learn more');
|
|
47
48
|
star.setAttribute('role', 'button');
|
|
48
49
|
star.setAttribute('tabindex', '0');
|
|
@@ -67,7 +68,7 @@
|
|
|
67
68
|
}
|
|
68
69
|
});
|
|
69
70
|
|
|
70
|
-
//
|
|
71
|
+
// Keep the link and its star as one span
|
|
71
72
|
link.parentNode.insertBefore(wrapper, link);
|
|
72
73
|
wrapper.appendChild(link);
|
|
73
74
|
wrapper.appendChild(star);
|