mentionwell 1.4.2 → 1.4.3

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/README.md CHANGED
@@ -1,6 +1,12 @@
1
1
  # mentionwell
2
2
 
3
- Destination-side reader + styles for [Mentionwell](https://github.com/isaachorowitz/Witz-Blog-Bot-1)-generated blog posts. The recommended setup reads published articles from the hosted Mentionwell API with a per-site `MENTIONWELL_API_KEY`; no Supabase credentials or GitHub delivery are needed on the destination domain. The package also ships ready-to-use CSS for tables, callouts, pull quotes, FAQ accordions, citations, YouTube embeds, and a sticky table-of-contents sidebar.
3
+ Destination-side reader + styles for [Mentionwell](https://mentionwell.com)-generated blog posts. The recommended setup reads published articles from the hosted Mentionwell API with a per-site `MENTIONWELL_API_KEY`; no Supabase credentials or GitHub delivery are needed on the destination domain. The package also ships ready-to-use CSS for tables, callouts, pull quotes, FAQ accordions, citations, YouTube embeds, and a sticky table-of-contents sidebar.
4
+
5
+ ## Companion packages
6
+
7
+ - [`mentionwell-cli`](https://www.npmjs.com/package/mentionwell-cli) — wires Mentionwell into your repo (`npx mentionwell-cli init`).
8
+ - [`mentionwell-mcp-docs`](https://www.npmjs.com/package/mentionwell-mcp-docs) — Mentionwell docs as an MCP server.
9
+ - [`mentionwell-mcp-account`](https://www.npmjs.com/package/mentionwell-mcp-account) — manage your Mentionwell account from any AI assistant.
4
10
 
5
11
  ## Install
6
12
 
@@ -11,7 +17,7 @@ npm install mentionwell
11
17
  ## Use
12
18
 
13
19
  ```ts
14
- // lib/blogoto-blog.ts
20
+ // lib/mentionwell-blog.ts
15
21
  import {
16
22
  getBlogPostViaApi,
17
23
  getBlogPostsViaApi,
@@ -38,7 +44,7 @@ import {
38
44
  stripTocFromArticle,
39
45
  stripPlatformChrome
40
46
  } from 'mentionwell/html-utils'
41
- import { fetchBlogPost } from '@/lib/blogoto-blog'
47
+ import { fetchBlogPost } from '@/lib/mentionwell-blog'
42
48
 
43
49
  export default async function ArticlePage({ params }) {
44
50
  const { slug } = await params
@@ -142,6 +148,34 @@ Removes the platform-rendered TL;DR, TOC, FAQ, CTA, author, header, and hero blo
142
148
 
143
149
  Pull the inline `<nav class="wb-toc">` out so you can mount it in a sidebar layout.
144
150
 
151
+ ### `getDirAttr(language)`
152
+
153
+ Returns `"rtl"` for `he-*` / `ar-*` BCP-47 codes and `"ltr"` for everything
154
+ else (including `undefined`). Apply it to `.wb-article-host` together with
155
+ `lang` — see the "RTL languages" section below.
156
+
157
+ ## RTL languages
158
+
159
+ The reader supports right-to-left languages out of the box. The article
160
+ container emits a `dir` attribute based on the post's `language` field
161
+ (`he-*` and `ar-*` resolve to `rtl`). All layout uses CSS logical
162
+ properties, so no extra stylesheet is required.
163
+
164
+ ```tsx
165
+ import { getDirAttr } from 'mentionwell/api'
166
+
167
+ <div
168
+ className="wb-article-host"
169
+ dir={getDirAttr(post.language)}
170
+ lang={post.language}
171
+ dangerouslySetInnerHTML={{ __html: bodyHtml }}
172
+ />
173
+ ```
174
+
175
+ If you self-host fonts, add Hebrew (Heebo/Assistant/Rubik) or Arabic
176
+ (Noto Naskh Arabic/Cairo/Tajawal) webfonts to your destination site. The
177
+ reader's CSS variables fall back to system fonts gracefully.
178
+
145
179
  ## License
146
180
 
147
181
  MIT
@@ -1,17 +1,17 @@
1
1
  /**
2
- * API-mode reader for Blogoto.
2
+ * API-mode reader for Mentionwell.
3
3
  *
4
- * Talks to a hosted Blogoto instance over HTTPS instead of going directly to
4
+ * Talks to a hosted Mentionwell instance over HTTPS instead of going directly to
5
5
  * Supabase. This is the recommended mode when you don't want destination
6
6
  * sites to know about your Supabase URL/anon key.
7
7
  *
8
- * Endpoints (provided by Blogoto `app/api/public/[siteSlug]/...`):
8
+ * Endpoints (provided by Mentionwell `app/api/public/[siteSlug]/...`):
9
9
  * GET /api/public/{siteSlug}/posts?limit=100 → list
10
10
  * GET /api/public/{siteSlug}/posts/{slug} → detail
11
11
  *
12
12
  * Auth: `Authorization: Bearer <apiKey>` where apiKey is the per-site key
13
- * surfaced in the Blogoto dashboard's integration page (deterministically
14
- * derived from siteId + READER_API_SECRET, prefix `bgo_read_`).
13
+ * surfaced in the Mentionwell dashboard's integration page (deterministically
14
+ * derived from siteId + READER_API_SECRET, prefix `mw_read_`).
15
15
  */
16
16
  export interface ReaderAuthor {
17
17
  id: string;
@@ -65,11 +65,35 @@ export interface ReaderPost {
65
65
  jsonLd: string;
66
66
  };
67
67
  canonicalUrl?: string;
68
+ /**
69
+ * BCP-47 language tag for the post (e.g. `"en-US"`, `"he-IL"`, `"ar-SA"`).
70
+ * Drives both the `lang` attribute and direction (`dir`) of the article
71
+ * host element. Use {@link getDirAttr} to derive the `dir` value.
72
+ */
73
+ language?: string;
68
74
  }
69
- export interface BlogotoApiConfig {
75
+ /**
76
+ * Returns the writing direction for a given BCP-47 language tag.
77
+ *
78
+ * Hebrew (`he*`) and Arabic (`ar*`) resolve to `"rtl"`; everything else
79
+ * (including unknown / missing values) returns `"ltr"`. Apply this to the
80
+ * `.wb-article-host` element so the bundled stylesheet — which is built
81
+ * entirely on CSS logical properties — flips the layout automatically:
82
+ *
83
+ * ```tsx
84
+ * <div
85
+ * className="wb-article-host"
86
+ * dir={getDirAttr(post.language)}
87
+ * lang={post.language}
88
+ * dangerouslySetInnerHTML={{ __html: html }}
89
+ * />
90
+ * ```
91
+ */
92
+ export declare function getDirAttr(language: string | undefined): "rtl" | "ltr";
93
+ export interface MentionwellApiConfig {
70
94
  /** Base URL of the Mentionwell instance, e.g. https://app.mentionwell.com */
71
95
  apiUrl: string;
72
- /** Per-site API key (Bearer token), prefix `bgo_read_`. */
96
+ /** Per-site API key (Bearer token), prefix `mw_read_`. */
73
97
  apiKey: string;
74
98
  /** Slug of this destination site as registered in Mentionwell. */
75
99
  siteSlug: string;
@@ -86,14 +110,14 @@ export interface BlogotoApiConfig {
86
110
  * which silently hid every page past the first. Sites with >100 posts
87
111
  * need server-side `?page=` support; bump this package once that lands.
88
112
  */
89
- export declare function getBlogPostsViaApi(config: BlogotoApiConfig, page?: number, perPage?: number): Promise<{
113
+ export declare function getBlogPostsViaApi(config: MentionwellApiConfig, page?: number, perPage?: number): Promise<{
90
114
  posts: ReaderPost[];
91
115
  total: number;
92
116
  totalPages: number;
93
117
  }>;
94
- export declare function getBlogPostViaApi(config: BlogotoApiConfig, slug: string): Promise<ReaderPost | null>;
95
- export declare function getAllBlogSlugsViaApi(config: BlogotoApiConfig): Promise<string[]>;
96
- export declare function getBlogPostSummariesViaApi(config: BlogotoApiConfig): Promise<Array<{
118
+ export declare function getBlogPostViaApi(config: MentionwellApiConfig, slug: string): Promise<ReaderPost | null>;
119
+ export declare function getAllBlogSlugsViaApi(config: MentionwellApiConfig): Promise<string[]>;
120
+ export declare function getBlogPostSummariesViaApi(config: MentionwellApiConfig): Promise<Array<{
97
121
  slug: string;
98
122
  updatedAt?: string;
99
123
  publishedAt?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"api-reader.d.ts","sourceRoot":"","sources":["../src/api-reader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAClD,YAAY,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,IAAI,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC3B,GAAG,CAAC,EAAE,cAAc,EAAE,CAAC;IACvB,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,sFAAsF;IACtF,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAmGD;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,gBAAgB,EACxB,IAAI,SAAI,EACR,OAAO,SAAK,GACX,OAAO,CAAC;IAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAmBrE;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAa5B;AAED,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAOvF;AAED,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAW5E"}
1
+ {"version":3,"file":"api-reader.d.ts","sourceRoot":"","sources":["../src/api-reader.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,43 @@
1
1
  /**
2
- * API-mode reader for Blogoto.
2
+ * API-mode reader for Mentionwell.
3
3
  *
4
- * Talks to a hosted Blogoto instance over HTTPS instead of going directly to
4
+ * Talks to a hosted Mentionwell instance over HTTPS instead of going directly to
5
5
  * Supabase. This is the recommended mode when you don't want destination
6
6
  * sites to know about your Supabase URL/anon key.
7
7
  *
8
- * Endpoints (provided by Blogoto `app/api/public/[siteSlug]/...`):
8
+ * Endpoints (provided by Mentionwell `app/api/public/[siteSlug]/...`):
9
9
  * GET /api/public/{siteSlug}/posts?limit=100 → list
10
10
  * GET /api/public/{siteSlug}/posts/{slug} → detail
11
11
  *
12
12
  * Auth: `Authorization: Bearer <apiKey>` where apiKey is the per-site key
13
- * surfaced in the Blogoto dashboard's integration page (deterministically
14
- * derived from siteId + READER_API_SECRET, prefix `bgo_read_`).
13
+ * surfaced in the Mentionwell dashboard's integration page (deterministically
14
+ * derived from siteId + READER_API_SECRET, prefix `mw_read_`).
15
15
  */
16
+ /**
17
+ * Returns the writing direction for a given BCP-47 language tag.
18
+ *
19
+ * Hebrew (`he*`) and Arabic (`ar*`) resolve to `"rtl"`; everything else
20
+ * (including unknown / missing values) returns `"ltr"`. Apply this to the
21
+ * `.wb-article-host` element so the bundled stylesheet — which is built
22
+ * entirely on CSS logical properties — flips the layout automatically:
23
+ *
24
+ * ```tsx
25
+ * <div
26
+ * className="wb-article-host"
27
+ * dir={getDirAttr(post.language)}
28
+ * lang={post.language}
29
+ * dangerouslySetInnerHTML={{ __html: html }}
30
+ * />
31
+ * ```
32
+ */
33
+ export function getDirAttr(language) {
34
+ if (!language)
35
+ return "ltr";
36
+ const code = language.toLowerCase();
37
+ if (code.startsWith("he") || code.startsWith("ar"))
38
+ return "rtl";
39
+ return "ltr";
40
+ }
16
41
  function trimUrl(url) {
17
42
  return url.replace(/\/+$/, "");
18
43
  }
@@ -28,7 +53,13 @@ function toReader(post) {
28
53
  excerpt: post.excerpt ?? "",
29
54
  html: post.html ?? "",
30
55
  markdown: post.markdown,
31
- featuredImage: post.featuredImage ?? undefined,
56
+ // Treat the legacy "/placeholder.jpg" sentinel as missing — destination
57
+ // sites resolve relative URLs against their own domain, so it 404s on
58
+ // every client that doesn't host that exact file. Returning undefined
59
+ // lets templates skip the hero figure cleanly.
60
+ featuredImage: post.featuredImage && post.featuredImage !== "/placeholder.jpg"
61
+ ? post.featuredImage
62
+ : undefined,
32
63
  readingTime: post.readingTime,
33
64
  tags: post.tags ?? [],
34
65
  category: post.category ?? null,
@@ -40,7 +71,8 @@ function toReader(post) {
40
71
  toc: post.toc ?? undefined,
41
72
  faqs: post.faqs ?? undefined,
42
73
  schema: post.jsonLd ? { jsonLd: post.jsonLd } : undefined,
43
- canonicalUrl: post.canonicalUrl ?? undefined
74
+ canonicalUrl: post.canonicalUrl ?? undefined,
75
+ language: post.language ?? undefined
44
76
  };
45
77
  }
46
78
  async function callApi(config, path, init) {
@@ -64,7 +96,7 @@ async function callApi(config, path, init) {
64
96
  catch {
65
97
  // body wasn't JSON; keep status text
66
98
  }
67
- throw new Error(`Blogoto API ${path} failed: ${message}`);
99
+ throw new Error(`Mentionwell API ${path} failed: ${message}`);
68
100
  }
69
101
  return (await response.json());
70
102
  }
@@ -1 +1 @@
1
- {"version":3,"file":"api-reader.js","sourceRoot":"","sources":["../src/api-reader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api-reader.js","sourceRoot":"","sources":["../src/api-reader.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  /**
2
- * Helpers for rendering Blogoto-generated article HTML on a destination site.
2
+ * Helpers for rendering Mentionwell-generated article HTML on a destination site.
3
3
  *
4
- * Blogoto's `buildArticleHtml` produces a self-contained article with a
4
+ * Mentionwell's `buildArticleHtml` produces a self-contained article with a
5
5
  * `<header class="wb-header">` (title + dek + tags) and a
6
6
  * `<figure class="wb-hero">` (cover image). Most destination templates also
7
7
  * render their own hero/title/cover, so injecting `post.html` raw double-
@@ -17,6 +17,15 @@
17
17
  */
18
18
  export declare function stripDuplicateChrome(html: string): string;
19
19
  export declare function stripLegacyCtaLeaks(html: string): string;
20
+ /**
21
+ * Older Mentionwell renders emitted callouts without a leading
22
+ * `<span class="wb-callout-emoji">…</span>` element. Most destination CSS
23
+ * templates lay the callout out as a 2-column grid (icon + body), so missing
24
+ * the icon span pushes the body into the narrow icon column and collapses
25
+ * the text to one word per line. Inject the missing emoji at read time so
26
+ * existing posts render correctly without re-publishing every article.
27
+ */
28
+ export declare function repairLegacyCallouts(html: string): string;
20
29
  export declare function extractTocHtml(html: string): string | null;
21
30
  export declare function stripTocFromArticle(html: string): string;
22
31
  export declare function stripPlatformChrome(html: string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"html-utils.d.ts","sourceRoot":"","sources":["../src/html-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKzD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKxD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG1D;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOxD;AAED,MAAM,WAAW,yBAAyB;IACxC;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,gFAAgF;IAChF,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,8DAA8D;AAC9D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,yBAA8B,GAAG,MAAM,CAKhG"}
1
+ {"version":3,"file":"html-utils.d.ts","sourceRoot":"","sources":["../src/html-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKzD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKxD;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAezD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG1D;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOxD;AAED,MAAM,WAAW,yBAAyB;IACxC;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,gFAAgF;IAChF,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,8DAA8D;AAC9D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,yBAA8B,GAAG,MAAM,CAKhG"}
@@ -1,7 +1,7 @@
1
1
  /**
2
- * Helpers for rendering Blogoto-generated article HTML on a destination site.
2
+ * Helpers for rendering Mentionwell-generated article HTML on a destination site.
3
3
  *
4
- * Blogoto's `buildArticleHtml` produces a self-contained article with a
4
+ * Mentionwell's `buildArticleHtml` produces a self-contained article with a
5
5
  * `<header class="wb-header">` (title + dek + tags) and a
6
6
  * `<figure class="wb-hero">` (cover image). Most destination templates also
7
7
  * render their own hero/title/cover, so injecting `post.html` raw double-
@@ -27,6 +27,27 @@ export function stripLegacyCtaLeaks(html) {
27
27
  .replace(/<strong>\s*\[CTA\]\s*<\/strong>/g, "")
28
28
  .replace(/\[CTA\]/g, "");
29
29
  }
30
+ /**
31
+ * Older Mentionwell renders emitted callouts without a leading
32
+ * `<span class="wb-callout-emoji">…</span>` element. Most destination CSS
33
+ * templates lay the callout out as a 2-column grid (icon + body), so missing
34
+ * the icon span pushes the body into the narrow icon column and collapses
35
+ * the text to one word per line. Inject the missing emoji at read time so
36
+ * existing posts render correctly without re-publishing every article.
37
+ */
38
+ export function repairLegacyCallouts(html) {
39
+ const emojiByVariant = {
40
+ tip: "💡",
41
+ warning: "⚠️",
42
+ stat: "📊"
43
+ };
44
+ return html.replace(/<aside\b([^>]*\bclass="[^"]*\bwb-callout\b[^"]*"[^>]*)>(\s*)(?!<span[^>]*\bwb-callout-emoji\b)/gi, (match, attrs, gap) => {
45
+ const variantMatch = attrs.match(/wb-callout-(tip|warning|stat)\b/i);
46
+ const variant = variantMatch ? variantMatch[1].toLowerCase() : "tip";
47
+ const emoji = emojiByVariant[variant] ?? "💡";
48
+ return `<aside${attrs}>${gap}<span class="wb-callout-emoji" aria-hidden="true">${emoji}</span>`;
49
+ });
50
+ }
30
51
  export function extractTocHtml(html) {
31
52
  const match = html.match(/<nav class="wb-toc"[\s\S]*?<\/nav>/);
32
53
  return match ? match[0] : null;
@@ -44,7 +65,7 @@ export function stripPlatformChrome(html) {
44
65
  }
45
66
  /** Convenience: apply all the safe transforms in one call. */
46
67
  export function prepareArticleHtml(html, options = {}) {
47
- let next = stripLegacyCtaLeaks(stripDuplicateChrome(html));
68
+ let next = repairLegacyCallouts(stripLegacyCtaLeaks(stripDuplicateChrome(html)));
48
69
  if (options.stripPlatformChrome)
49
70
  next = stripPlatformChrome(next);
50
71
  if (options.stripToc)
@@ -1 +1 @@
1
- {"version":3,"file":"html-utils.js","sourceRoot":"","sources":["../src/html-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,OAAO,IAAI;SACR,OAAO,CAAC,8CAA8C,EAAE,EAAE,CAAC;SAC3D,OAAO,CAAC,4CAA4C,EAAE,EAAE,CAAC;SACzD,OAAO,CAAC,gDAAgD,EAAE,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,IAAI;SACR,OAAO,CAAC,yDAAyD,EAAE,EAAE,CAAC;SACtE,OAAO,CAAC,kCAAkC,EAAE,EAAE,CAAC;SAC/C,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;IAC/D,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,IAAI,CAAC,OAAO,CAAC,oCAAoC,EAAE,EAAE,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,oBAAoB,CAAC,IAAI,CAAC;SAC9B,OAAO,CAAC,qEAAqE,EAAE,EAAE,CAAC;SAClF,OAAO,CAAC,wEAAwE,EAAE,EAAE,CAAC;SACrF,OAAO,CAAC,mFAAmF,EAAE,EAAE,CAAC;SAChG,OAAO,CAAC,uEAAuE,EAAE,EAAE,CAAC;SACpF,OAAO,CAAC,gEAAgE,EAAE,EAAE,CAAC,CAAC;AACnF,CAAC;AAaD,8DAA8D;AAC9D,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,UAAqC,EAAE;IACtF,IAAI,IAAI,GAAG,mBAAmB,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3D,IAAI,OAAO,CAAC,mBAAmB;QAAE,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAClE,IAAI,OAAO,CAAC,QAAQ;QAAE,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACvD,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"html-utils.js","sourceRoot":"","sources":["../src/html-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,OAAO,IAAI;SACR,OAAO,CAAC,8CAA8C,EAAE,EAAE,CAAC;SAC3D,OAAO,CAAC,4CAA4C,EAAE,EAAE,CAAC;SACzD,OAAO,CAAC,gDAAgD,EAAE,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,IAAI;SACR,OAAO,CAAC,yDAAyD,EAAE,EAAE,CAAC;SACtE,OAAO,CAAC,kCAAkC,EAAE,EAAE,CAAC;SAC/C,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,cAAc,GAA2B;QAC7C,GAAG,EAAE,IAAI;QACT,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,IAAI;KACX,CAAC;IACF,OAAO,IAAI,CAAC,OAAO,CACjB,kGAAkG,EAClG,CAAC,KAAK,EAAE,KAAa,EAAE,GAAW,EAAE,EAAE;QACpC,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACrE,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QACrE,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;QAC9C,OAAO,SAAS,KAAK,IAAI,GAAG,qDAAqD,KAAK,SAAS,CAAC;IAClG,CAAC,CACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;IAC/D,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,IAAI,CAAC,OAAO,CAAC,oCAAoC,EAAE,EAAE,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,oBAAoB,CAAC,IAAI,CAAC;SAC9B,OAAO,CAAC,qEAAqE,EAAE,EAAE,CAAC;SAClF,OAAO,CAAC,wEAAwE,EAAE,EAAE,CAAC;SACrF,OAAO,CAAC,mFAAmF,EAAE,EAAE,CAAC;SAChG,OAAO,CAAC,uEAAuE,EAAE,EAAE,CAAC;SACpF,OAAO,CAAC,gEAAgE,EAAE,EAAE,CAAC,CAAC;AACnF,CAAC;AAaD,8DAA8D;AAC9D,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,UAAqC,EAAE;IACtF,IAAI,IAAI,GAAG,oBAAoB,CAAC,mBAAmB,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjF,IAAI,OAAO,CAAC,mBAAmB;QAAE,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAClE,IAAI,OAAO,CAAC,QAAQ;QAAE,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACvD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -1,11 +1,16 @@
1
1
  /* ============================================================
2
2
  @isaac/blog-reader/styles
3
- Default styles for Blogoto-generated article HTML (wb-* class
3
+ Default styles for Mentionwell-generated article HTML (wb-* class
4
4
  namespace produced by lib/blog/article-html.ts).
5
5
 
6
6
  All colors, fonts, and radii are CSS variables prefixed with
7
7
  --wb-*. Override them in your destination site to re-theme.
8
8
  Defaults below match a warm, editorial palette.
9
+
10
+ Layout uses CSS logical properties (margin-inline-*, padding-inline-*,
11
+ border-inline-*, inset-inline-*, text-align: start/end, float:
12
+ inline-start/end) so setting `dir="rtl"` on `.wb-article-host`
13
+ flips the entire layout for Hebrew/Arabic with no extra rules.
9
14
  ============================================================ */
10
15
 
11
16
  :root {
@@ -54,7 +59,7 @@
54
59
  .wb-article-host ul,
55
60
  .wb-article-host ol {
56
61
  margin: 1rem 0 1.5rem;
57
- padding-left: 1.5rem;
62
+ padding-inline-start: 1.5rem;
58
63
  }
59
64
  .wb-article-host ul:not(.wb-steps) li,
60
65
  .wb-article-host ol:not(.wb-steps) li {
@@ -135,7 +140,7 @@
135
140
  .wb-article-host li a[rel*="noopener"][target="_blank"]::after {
136
141
  content: "↗";
137
142
  font-size: 0.85em;
138
- margin-left: 0.15em;
143
+ margin-inline-start: 0.15em;
139
144
  color: var(--wb-bronze);
140
145
  }
141
146
 
@@ -153,7 +158,7 @@
153
158
  .wb-article-host li a:has(> sup:only-child)::after,
154
159
  .wb-article-host td a:has(> sup:only-child)::after {
155
160
  font-size: 0.65em;
156
- margin-left: 0.05em;
161
+ margin-inline-start: 0.05em;
157
162
  opacity: 0.7;
158
163
  }
159
164
  .wb-article-host sup {
@@ -190,7 +195,7 @@
190
195
  .wb-article-host .wb-related li::before {
191
196
  content: "→";
192
197
  color: var(--wb-bronze);
193
- margin-right: 0.5rem;
198
+ margin-inline-end: 0.5rem;
194
199
  font-weight: 600;
195
200
  }
196
201
  .wb-article-host .wb-related a {
@@ -251,7 +256,7 @@
251
256
  .wb-article-host .wb-tldr {
252
257
  border: 1px solid #D6CFC4;
253
258
  background: #F6F2EB;
254
- border-left: 4px solid #9A7453;
259
+ border-inline-start: 4px solid #9A7453;
255
260
  border-radius: 12px;
256
261
  padding: 1.25rem 1.5rem;
257
262
  margin: 0 0 2.5rem;
@@ -269,13 +274,13 @@
269
274
  /* --- TOC sidebar ------------------------------------------ */
270
275
  .wb-toc-sidebar .wb-toc {
271
276
  background: transparent; padding: 0; border: 0;
272
- border-left: 1px solid var(--wb-border); margin: 0;
277
+ border-inline-start: 1px solid var(--wb-border); margin: 0;
273
278
  }
274
279
  .wb-toc-sidebar .wb-toc h2 {
275
280
  font-family: var(--wb-font-display);
276
281
  font-size: 0.7rem; font-weight: 600;
277
282
  text-transform: uppercase; letter-spacing: 0.12em;
278
- color: var(--wb-body); margin: 0 0 0.75rem; padding-left: 1rem;
283
+ color: var(--wb-body); margin: 0 0 0.75rem; padding-inline-start: 1rem;
279
284
  }
280
285
  .wb-toc-sidebar .wb-toc ul, .wb-toc-sidebar .wb-toc ol {
281
286
  margin: 0; padding: 0; list-style: none;
@@ -286,15 +291,15 @@
286
291
  color: var(--wb-body); text-decoration: none;
287
292
  font-family: var(--wb-font-body);
288
293
  font-size: 0.9rem; line-height: 1.4;
289
- border-left: 2px solid transparent; margin-left: -1px;
294
+ border-inline-start: 2px solid transparent; margin-inline-start: -1px;
290
295
  transition: color 150ms ease, border-color 150ms ease;
291
296
  }
292
297
  .wb-toc-sidebar .wb-toc a:hover {
293
- color: var(--wb-ink); border-left-color: var(--wb-bronze);
298
+ color: var(--wb-ink); border-inline-start-color: var(--wb-bronze);
294
299
  }
295
300
 
296
301
  /* --- Section headers --------------------------------------- */
297
- /* Cover both Blogoto-generated structure (section.wb-section > h2) AND
302
+ /* Cover both Mentionwell-generated structure (section.wb-section > h2) AND
298
303
  plain h2/h3s from migrated/legacy content. */
299
304
  .wb-article-host section.wb-section { margin-top: 3rem; }
300
305
  .wb-article-host section.wb-section > h2,
@@ -346,7 +351,7 @@
346
351
  margin-top: 0.5rem; font-size: 0.85rem;
347
352
  color: var(--wb-body); font-style: italic; text-align: center;
348
353
  }
349
- .wb-article-host .wb-infographic { max-width: 720px; margin-left: auto; margin-right: auto; }
354
+ .wb-article-host .wb-infographic { max-width: 720px; margin-inline-start: auto; margin-inline-end: auto; }
350
355
 
351
356
  /* --- YouTube card ------------------------------------------ */
352
357
  .wb-article-host .wb-youtube { margin: 2.5rem 0; max-width: 100%; }
@@ -403,6 +408,9 @@
403
408
  }
404
409
  .wb-article-host .wb-faq-item > summary::-webkit-details-marker { display: none; }
405
410
  .wb-article-host .wb-faq-item > summary::before {
411
+ /* physical: intentional — chevron is a rotated square; rotation math
412
+ is direction-agnostic and the closed/open transform is purely
413
+ visual, not a directional cue. */
406
414
  content: ''; flex: none; width: 10px; height: 10px;
407
415
  border-right: 2px solid var(--wb-bronze-deep);
408
416
  border-bottom: 2px solid var(--wb-bronze-deep);
@@ -415,7 +423,12 @@
415
423
  color: var(--wb-ink); line-height: 1.4;
416
424
  }
417
425
  .wb-article-host .wb-faq-answer {
418
- padding: 0 1.25rem 1.25rem 2.75rem;
426
+ padding-block: 0 1.25rem;
427
+ padding-inline: 1.25rem 2.75rem;
428
+ /* Note: the larger inset is on the inline-end side to clear the chevron
429
+ that lives at the inline-start of the summary. In RTL, summary content
430
+ reverses so the chevron sits at inline-start (the visual right) and the
431
+ larger inset still lands away from it. */
419
432
  color: #3A3732; line-height: 1.65;
420
433
  }
421
434
  .wb-article-host .wb-faq-answer p { margin: 0.5rem 0; }
@@ -505,7 +518,7 @@
505
518
  .wb-article-host thead th {
506
519
  background: #3C5445 !important;
507
520
  color: #FAF7F2 !important;
508
- text-align: left;
521
+ text-align: start;
509
522
  font-family: var(--wb-font-display);
510
523
  font-weight: 600;
511
524
  font-size: 0.78rem;
@@ -524,7 +537,7 @@
524
537
  .wb-article-host tbody tr:nth-child(even) { background: var(--wb-cream); }
525
538
  .wb-article-host tbody tr:hover { background: #F0EBE1; }
526
539
  .wb-article-host th + th,
527
- .wb-article-host td + td { border-left: 1px solid #E2DBCE; }
540
+ .wb-article-host td + td { border-inline-start: 1px solid #E2DBCE; }
528
541
 
529
542
  /* Mobile: tighten table cells. (Horizontal scroll is already enabled at
530
543
  all breakpoints in the base table rule above.) */
@@ -548,6 +561,8 @@
548
561
  .wb-article-host hr.wb-divider {
549
562
  border: 0;
550
563
  height: 1px;
564
+ /* physical: intentional — the linear-gradient direction here is a
565
+ visual fade that reads identically in both LTR and RTL. */
551
566
  background: linear-gradient(to right, transparent, var(--wb-border) 20%, var(--wb-border) 80%, transparent);
552
567
  margin: 2.5rem auto;
553
568
  max-width: 60%;
@@ -555,8 +570,10 @@
555
570
 
556
571
  /* --- Pull quote ------------------------------------------- */
557
572
  .wb-article-host blockquote.wb-quote, .wb-article-host blockquote {
558
- margin: 2rem 0; padding: 0.5rem 0 0.5rem 1.5rem;
559
- border-left: 3px solid var(--wb-bronze);
573
+ margin: 2rem 0;
574
+ padding-block: 0.5rem;
575
+ padding-inline-start: 1.5rem;
576
+ border-inline-start: 3px solid var(--wb-bronze);
560
577
  font-family: var(--wb-font-display); font-weight: 500;
561
578
  font-size: 1.2rem; line-height: 1.5;
562
579
  color: var(--wb-ink); font-style: normal;
@@ -574,7 +591,7 @@
574
591
  margin: 2rem 0;
575
592
  border-radius: var(--wb-radius-md);
576
593
  border: 1px solid;
577
- border-left-width: 4px;
594
+ border-inline-start-width: 4px;
578
595
  font-size: 0.97rem;
579
596
  line-height: 1.6;
580
597
  }
@@ -598,7 +615,7 @@
598
615
  .wb-article-host .wb-callout-tip {
599
616
  background: linear-gradient(180deg, #F2F7F0 0%, #ECF3E9 100%);
600
617
  border-color: #C2D0BD;
601
- border-left-color: var(--wb-forest);
618
+ border-inline-start-color: var(--wb-forest);
602
619
  color: #1F3324;
603
620
  }
604
621
  .wb-article-host .wb-callout-tip .wb-callout-label { color: var(--wb-forest); }
@@ -606,7 +623,7 @@
606
623
  .wb-article-host .wb-callout-warning {
607
624
  background: linear-gradient(180deg, #FCF3E5 0%, #F8EAD4 100%);
608
625
  border-color: #E5C7A0;
609
- border-left-color: #C58A2D;
626
+ border-inline-start-color: #C58A2D;
610
627
  color: #4A3618;
611
628
  }
612
629
  .wb-article-host .wb-callout-warning .wb-callout-label { color: #9A6E2D; }
@@ -614,7 +631,7 @@
614
631
  .wb-article-host .wb-callout-stat {
615
632
  background: linear-gradient(180deg, #F2EFF9 0%, #ECE7F5 100%);
616
633
  border-color: #C7BFD9;
617
- border-left-color: #6C5BA1;
634
+ border-inline-start-color: #6C5BA1;
618
635
  color: #2C2447;
619
636
  }
620
637
  .wb-article-host .wb-callout-stat .wb-callout-label { color: #5C4F8A; }
@@ -627,13 +644,14 @@
627
644
  }
628
645
  .wb-article-host ol.wb-steps > li {
629
646
  counter-increment: wb-step; position: relative;
630
- padding: 0.85rem 1rem 0.85rem 3rem;
647
+ padding-block: 0.85rem;
648
+ padding-inline: 3rem 1rem;
631
649
  background: var(--wb-paper); border: 1px solid var(--wb-border);
632
650
  border-radius: var(--wb-radius-sm); line-height: 1.55; color: #3A3732;
633
651
  }
634
652
  .wb-article-host ol.wb-steps > li::before {
635
653
  content: counter(wb-step);
636
- position: absolute; left: 0.85rem; top: 0.7rem;
654
+ position: absolute; inset-inline-start: 0.85rem; top: 0.7rem;
637
655
  width: 1.6rem; height: 1.6rem;
638
656
  border-radius: 999px;
639
657
  background: var(--wb-forest); color: #FAF7F2;
@@ -662,7 +680,7 @@
662
680
  .wb-article-host .wb-citation-index {
663
681
  flex: none; font-family: var(--wb-font-display); font-weight: 600;
664
682
  font-size: 0.85rem; color: var(--wb-bronze-deep);
665
- min-width: 1.25rem; text-align: right;
683
+ min-width: 1.25rem; text-align: end;
666
684
  }
667
685
  .wb-article-host .wb-citation-body {
668
686
  display: flex; flex-direction: column; gap: 0.15rem; min-width: 0;
@@ -782,7 +800,7 @@
782
800
  .wb-sticky-toc {
783
801
  position: sticky; top: var(--wb-sticky-top, 6rem); align-self: start;
784
802
  max-height: calc(100vh - 8rem); overflow-y: auto;
785
- padding-right: 0.5rem;
803
+ padding-inline-end: 0.5rem;
786
804
  z-index: 1;
787
805
  }
788
806
  @media (max-width: 1023px) { .wb-sticky-toc { display: none; } }
@@ -891,3 +909,33 @@
891
909
  background: #3C5445 !important;
892
910
  color: #FAF7F2 !important;
893
911
  }
912
+
913
+ /* ============================================================
914
+ Hebrew / Arabic typography presets.
915
+ Activated by [dir="rtl"][lang^="he"] (or [lang^="ar"]) on the host.
916
+ Use webfonts the destination must include OR fall back gracefully
917
+ to the system stack.
918
+ ============================================================ */
919
+ .wb-article-host[dir="rtl"][lang^="he"] {
920
+ --wb-font-display: "Heebo", "Assistant", "Rubik", system-ui, sans-serif;
921
+ --wb-font-body: "Heebo", "Assistant", "Rubik", system-ui, sans-serif;
922
+ line-height: 1.85; /* Hebrew x-height needs a touch more leading */
923
+ letter-spacing: 0; /* Hebrew rendering is tighter; reset any tracking. */
924
+ }
925
+ .wb-article-host[dir="rtl"][lang^="he"] h1,
926
+ .wb-article-host[dir="rtl"][lang^="he"] h2,
927
+ .wb-article-host[dir="rtl"][lang^="he"] h3 {
928
+ font-weight: 700; /* Hebrew display weights need bumping vs Latin */
929
+ }
930
+
931
+ .wb-article-host[dir="rtl"][lang^="ar"] {
932
+ --wb-font-display: "Noto Naskh Arabic", "Cairo", "Tajawal", system-ui, sans-serif;
933
+ --wb-font-body: "Noto Naskh Arabic", "Cairo", "Tajawal", system-ui, sans-serif;
934
+ line-height: 1.9; /* Arabic script benefits from extra leading */
935
+ letter-spacing: 0;
936
+ }
937
+ .wb-article-host[dir="rtl"][lang^="ar"] h1,
938
+ .wb-article-host[dir="rtl"][lang^="ar"] h2,
939
+ .wb-article-host[dir="rtl"][lang^="ar"] h3 {
940
+ font-weight: 700;
941
+ }
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "mentionwell",
3
- "version": "1.4.2",
3
+ "version": "1.4.3",
4
4
  "description": "Destination-side API reader + styles for Mentionwell-generated blog posts.",
5
5
  "license": "MIT",
6
6
  "author": "Isaac Horowitz <horowitzisaac@gmail.com>",
7
- "homepage": "https://github.com/isaachorowitz/Witz-Blog-Bot-1",
7
+ "homepage": "https://mentionwell.com",
8
8
  "repository": {
9
9
  "type": "git",
10
- "url": "git+https://github.com/isaachorowitz/Witz-Blog-Bot-1.git",
10
+ "url": "git+https://github.com/ZipLyne-Agency/MentionWell.git",
11
11
  "directory": "packages/blog-reader"
12
12
  },
13
13
  "keywords": [