あなたとJAVA,今すぐダウンロード
上の
もう
Chromium系word-break: auto-phrase
を
な
準備
まずは
npm add -D budoux
READMEにParser.parse()
HTMLProcessingParser.applyToElement()
など、HTMLProcessingParser.translateHTMLString()
を
さて、.translateHTMLString()
のU+200B
HTMLProcessorOptions.separator
)。<wbr>
)を
また、word-break: keep-all; overflow-wrap: anywhere;
とHTMLProcessorOptions.className
をbudoux
と
以上を
import { HTMLProcessingParser, jaModel } from "budoux";import type { HTMLProcessingParser as HTMLProcessingParserType } from "budoux";import { win } from "budoux/dist/win";
let cachedParser: HTMLProcessingParserType | null = null;
export function getBudouxParser() { if (!cachedParser) { const wbr = win.document.createElement("wbr"); cachedParser = new HTMLProcessingParser(jaModel, { className: "budoux", separator: wbr, }); } return cachedParser;}
export const budouxProcess = (html: string) => getBudouxParser().translateHTMLString(html);
グローバルCSSも
.budoux { word-break: keep-all; overflow-wrap: anywhere;}
本文 (Markdown / MDX)
Markdownや<p>
や<li>
)を
import { fromHtml } from "hast-util-from-html";import { toHtml } from "hast-util-to-html";import { SKIP, visit } from "unist-util-visit";import { budouxProcess } from "./budoux";
import type { Element, ElementContent, Root } from "hast";import type { Plugin } from "unified";
const targetTagNames = ["p", "li", "h1", "h2", "h3", "h4", "h5", "h6"];
function isElement(node: Element | ElementContent): node is Element { return node.type === "element";}
function isTargetNode(node: Element | ElementContent): node is Element { return isElement(node) ? targetTagNames.includes(node.tagName) : false;}
const rehypeBudoux: Plugin<[], Root> = () => { return (tree) => { visit(tree, "element", (node, index, parent) => { if (typeof index !== "number" || !isTargetNode(node)) { return; } const newNode = fromHtml(budouxProcess(toHtml(node)), { fragment: true, }).children[0]; newNode && parent?.children.splice(index, 1, newNode); return SKIP; }); };};
export default rehypeBudoux;
本文 (上記以外)
それ以外の<Budoux />
<Budoux />
---import { budouxProcess } from "@/lib/budoux";
const slotContent = await Astro.slots.render("default");const parsed = budouxProcess(slotContent);---
<Fragment set:html={parsed} />
---import Budoux from "@/components/Budoux.astro";---
<Budoux><p>{post.data.description}</p></Budoux>
OpenGraph画像
本文だけでなく、
おわりに
BudouXの
Google の
使命は、 世界中の 情報を 整理し、 世界中の 人が アクセスできて 使えるように する ことです。
との
脚注
-
とは
いえ実測で 20KB (gzip前) 程度だが …… ↩ -
HTMLProcessorOptions.separator
にはstring
または HTML要素 ( Node
)を指定できる。 Node.jsなど 非ブラウザ環境で HTML要素を 作成するのは 少々 厄介だが、 BudouXが 内部で 利用している jsdomの Windowを 流用すると うまくいく。 ↩ -
構文木
(hast)を HTML化して、 また hastに 戻しているのは 明らかに 非効率なので、 本来は hastの 状態のまま 処理を 行いたい ところだが、 その ためには BudouXが 行っている 処理を (hastに 即した形で) 再実装する 必要が あり、 やや 面倒に なる。 誰か暇なら やって ほしい。 ↩ -
Astro.slots.render()
を使うと、 子要素を HTMLと して レンダリングできると いうのが ポイントかもしれない。 ↩