Codync
免費、開源的 1:1 替代方案,取代 Grok Bot 與 Muse。從 iPhone、Mac 或 Linux 桌面將 Claude Code、Codex、Cursor 與 40+ 程式碼代理人作為持續機器人傳訊。群組聊天、主題串…
AI 翻譯
製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗Palt Typesetting は、美しいテキスト表示を実現するための JavaScript ライブラリです。和欧混植、およびツメ組み (font-feature-settings: 'palt') の版面設計において、最大限の力を発揮します。
四分アキの自動挿入、カーニングルールの適用、英語のような単語区切りでの改行など、洗練された組版機能を提供します。
npm でパッケージをインストールする場合
npm install palt-typesetting
import Typesetter from 'palt-typesetting'
import 'palt-typesetting/dist/typesetter.css'
// Typesetter のインスタンスを作成
const typesetter = new Typesetter()
// セレクターにマッチする要素に対して組版を適用
typesetter.renderToSelector('.my-class')
WordPress や jQuery などの環境で使用する場合
<head>
<!-- head タグ内でスタイルの読み込み -->
<link rel="stylesheet" type="text/css" href="https://unpkg.com/[email protected]/bundle/typesetter.min.css" />
</head>
<body>
<!-- body 閉じタグの前でスクリプトの読み込み -->
<script src="https://unpkg.com/[email protected]/bundle/typesetter.min.js"></script>
</body>
<script>
// Typesetter のインスタンスを作成
const typesetter = new Typesetter()
// セレクターにマッチする要素に対して組版を適用
typesetter.renderToSelector('.my-class')
</script>
生成された組版用 HTML にカスタム CSS を適用
/**
* 共通のスタイリング(例)
*/
.typesetting-wrapper {
/* プロポーショナルメトリクス(ツメ組み)の設定 */
font-feature-settings: 'palt';
/* 行間 */
line-height: 1.8;
/* 文字間 */
letter-spacing: 0.1em;
/**
* Safari のフォントレンダリング対策。
* 英数(.typesetting-latin)で -webkit-text-stroke を使う場合は必須。
* text-stroke-weight > 0, text-stroke-color: transparent
*/
-webkit-text-stroke: 0.01em transparent;
}
/**
* 英数のみのスタイリング(例)
*/
.typesetting-latin {
/* フォントの拡大・縮小 */
font-size: 105%;
/* ベースラインの調整 */
vertical-align: 0.02em;
/**
* 行間の調整。親要素 .typesetting-wrapper の行間と視覚的に合わせます。
* [.typesetting-wrapper の line-height] ÷ [フォントの拡大率] - [ベースラインの調整値の絶対値] × 2
*/
line-height: calc(1.8 / 1.05 - 0.02 * 2);
/* 文字間の調整 */
letter-spacing: 0.05em;
/* 文字の細らせ・太らせ */
-webkit-text-stroke: 0.01em #000;
}
Palt Typesetting では、Typesetter クラスを使用して HTML 文字列に組版を適用します。
ライブラリの機能はオプションを通じてカスタマイズできます。
/**
* options: TypesettingOptions
* オプションの設定
*/
const options = {
// 単語や助詞など、単語区切りでの改行を行います。
useWordBreak: true,
// 英数を `.typesetting-latin` でラップします。
wrapLatin: true,
// 特例文字 `char` を `.typesetting-char-[label]` でラップします。
wrapChars: [
{
char: 'あ',
label: 'hira-a',
// output: <span class="typesetting-char-hira-a">あ</span>
},
{
char: '」',
// output: <span class="typesetting-char-」">」</span>
// label が未指定の場合は、char の値がそのまま label として使用されます。
},
{
char: ['(', ')'],
label: 'parenthesis',
// output: <span class="typesetting-char-parenthesis">()</span>
// 配列で複数の文字をまとめて指定できます。
// 配列の長さが2以上の場合は label の指定が必須です。
},
],
// 罫線などの分離禁則文字を `.typesetting-no-breaks` でラップし、文字間を 0 に設定します。
noSpaceBetweenNoBreaks: true,
// 四分アキスペースを自動で挿入します。
insertThinSpaces: true,
// 四分アキスペースの幅を設定します。
thinSpaceWidth: '0.2em',
// 特定の文字間のカーニングルールを設定します。
kerningRules: [
{
between: ['し', 'ま'],
value: '60',
},
{
between: ['す', '。'],
value: '-80',
},
],
}
/**
* Typesetter(options?: TypesettingOptions)
* インスタンスの作成
*/
const typesetter = new Typesetter(options)
/**
* renderToSelector(selector: string): void
* セレクターにマッチする要素に対して組版を適用
*/
typesetter.renderToSelector('div')
typesetter.renderToSelector('.my-class')
typesetter.renderToSelector('#my-id')
/**
* renderToElements(elements: string): void
* HTML 文字列に組版を適用
*/
const elements = document.querySelectorAll('.my-class')
typesetter.renderToElements(elements)
/**
* render(srcHtml: string): string
* 組版を適用した HTML 文字列の取得
*/
const srcHtml = '「日本語」とEnglish'
console.log('output: ' + typesetter.render(srcHtml))
// output: <span class="typeset typesetting-wrapper typesetting-word-break">「日本語<span class="typesetting-char-」">」</span><span class="typesetting-thin-space" style="letter-spacing: 0.2em;" data-content=" "></span>と<span class="typesetting-thin-space" style="letter-spacing: 0.2em;" data-content=" "></span><span class="typesetting-latin">English </span></span>
| コンストラクタ | 説明 | 引数の型 |
|---|---|---|
Typesetter(options?) | Typesetter インスタンスを作成します。オプションを指定することでカスタムの組版設定を適用できます。 | options?: TypesettingOptions |
| メソッド名 | 説明 | 引数の型 | 戻り値の型 |
|---|---|---|---|
render(srcHtml) | スタイルを適用した HTML 文字列を返します。 | string | string |
renderToElements(elements) | 指定された Element または Element の配列にスタイルを適用します。 | Element | Element[] | void |
renderToSelector(selector, root?) | 指定された CSS セレクタに一致するすべての要素にスタイルを適用します。 | selector: string | null, root?: ParentNode | null | void |
root には Document、Element、DocumentFragment を指定できます。省略時は実行時のグローバル document を使用し、DOMがない場合や null を指定した場合は何もしません。
| オプション名 | 説明 | オプションの型 | デフォルト値 |
|---|---|---|---|
useWordBreak | 単語や助詞など、単語区切りでの改行を行います。 | boolean | true |
wrapLatin | 英数を span.typesetting-latin でラップします。 | boolean | true |
wrapChars | 特例文字の設定です。指定された文字 char をラッピングし、<span> タグで囲みます。ラッピングされた文字には、span.typesetting-char-[label] の形式で CSS クラスが付与されます。※ 指定が 1 文字の場合は、label を省略できます。その際、char の値がそのままクラス名の一部に使用されます。 | {char: string | string[], label?: string}[] | [] |
noSpaceBetweenNoBreaks | 罫線などの分離禁則文字を span.typesetting-no-breaks でラップし、文字間を 0 に設定します。 | boolean | true |
insertThinSpaces | 四分アキスペースを自動で挿入します。 | boolean | true |
thinSpaceWidth | 四分アキスペースの幅を設定します。※四分アキは本来 0.25em ですが、視覚上の補正としてデフォルト値を 0.2em に設定しています。 | string | '0.2em' |
kerningRules | 特定の文字間のカーニングルールを設定します。 | {between: [string, string], value: string | number}[] | [] |
| CSS クラス名 | 説明 |
|---|---|
.typesetting-wrapper | HTML 文字列中のテキストコンテンツをラップします。オプションの指定に関わらず、常に生成されます。 |
.typesetting-word-break | HTML 文字列中のテキストコンテンツをラップします。useWordBreak: true のときに生成されます。 |
.typesetting-latin | テキストコンテンツ中の英数をラップします。wrapLatin: true のときに生成されます。 |
.typesetting-char-[label] | wrapChars で指定された特例文字に付与される CSS クラスです。指定した label がクラス名の一部に使用されます。 |
.typesetting-no-breaks | テキストコンテンツ中の分離禁則文字をラップします。noSpaceBetweenNoBreaks: true のときに生成されます。 |
.typesetting-thin-space | 挿入される四分アキスペースエレメントの CSS クラスです。insertThinSpaces: true のときに生成されます。 |
.typesetting-kerning | 挿入されるカーニングエレメントの CSS クラスです。有効な kerningRules が存在するときに生成されます。 |
TypeScript の型定義を提供しています。完全な型定義はこちらをご参照ください。
import Typesetter from 'palt-typesetting'
import type { TypesettingOptions, KerningRule, WrapChar } from 'palt-typesetting/types'
import 'palt-typesetting/dist/typesetter.css'
const chars: WrapChar[] = [
{
char: 'あ',
label: 'hira-a',
},
{
char: ['(', ')'],
label: 'parenthesis',
},
]
const kerning: KerningRule[] = [
{
between: ['し', 'ま'],
value: '60',
},
]
const options: TypesettingOptions = {
thinSpaceWidth: '0.25em',
kerningRules: kerning,
wrapChars: chars,
}
const typeset = new Typesetter(options)
typesetter.renderToSelector('.my-class')
モダンな JavaScript フレームワーク用のサンプル集です。
Typesetting コンポーネントの作成
components/Typesetting.jsx
'use client'
import React, { useEffect, useState } from 'react'
import Typesetter from 'palt-typesetting'
import 'palt-typesetting/dist/typesetter.css'
import './Typesetting.css'
const Typesetting = ({ content }) => {
const [renderedHtml, setRenderedHtml] = useState('')
useEffect(() => {
const typesetter = new Typesetter()
setRenderedHtml(typesetter.render(content))
}, [content])
return <span dangerouslySetInnerHTML={{ __html: renderedHtml }} />
}
export default Typesetting
components/Typesetting.css
/* 共通のスタイル */
.typesetting-wrapper {
font-feature-settings: 'palt';
letter-spacing: 0.1em;
}
/* 英数のスタイル */
.typesetting-latin {
font-size: 105%;
letter-spacing: 0.05em;
}
Typesetting コンポーネントの作成
components/Typesetting.astro
---
import Typesetter from 'palt-typesetting'
import 'palt-typesetting/dist/typesetter.css'
const { content } = Astro.props
const slot = await Astro.slots.render('default')
const srcHtml = content || slot || ''
const typesetter = new Typesetter();
---
<Fragment set:html={typesetter.render(srcHtml)} />
<style is:global>
/* 共通のスタイル */
.typesetting-wrapper {
font-feature-settings: 'palt';
letter-spacing: 0.1em;
}
/* 英数のスタイル */
.typesetting-latin {
font-size: 105%;
letter-spacing: 0.05em;
}
</style>
Typesetting コンポーネントの読み込み
pages/index.astro
---
import Typeset from '../components/Typesetting.astro'
---
<div>
<!-- props を使った書き方 -->
<Typesetting content="「日本語」とEnglish、晴れ・28度。" />
<!-- slot を使った書き方 -->
<Typesetting>
<a href="/work">作品ページ</a>
</Typesetting>
</div>
<style>
p {
font-size: 1.8rem;
}
</style>
Palt Typesetting ライブラリは、テキストを言語固有のセグメントに分割する Intl.Segmenter という機能に一部依存しています。そのため、以下の環境要件があります。
SSG など、サーバーサイドで実行する場合
クライアントサイドで実行する場合
Intl.Segmenter がない環境でも、ES2020 の構文に対応している必要があります(UMD バンドル bundle/typesetter.min.js と dist/ は ES2020 で出力しています)クライアントサイドで実行する場合、この機能は一部のブラウザで利用できません。Palt Typesetting ライブラリは、Firefox などの Intl.Segmenter がサポートされていない環境1 では、useWordBreak(単語区切りでの改行)と insertThinSpaces(四分アキの自動挿入)オプションがスキップされます。全てのモダンブラウザで同様の見え方を再現するには、サーバーサイドでの事前処理(Astro.js での SSG など)が必要となります。
Intl.Segmenter の対応状況については、Can I use... で確認できます。
render(html) はDOMライブラリなしで利用できます。jsdomは必須依存に含まれません。
ブラウザでは、従来どおり renderToSelector(selector) がグローバルの document を検索します。
Node.jsなど document が存在しない環境では、このメソッドは何もしません。
サーバー側でセレクタを使う場合は、自分で用意した Document または検索対象の Element を第2引数に渡してください。
例えばjsdomを使う場合は、利用するプロジェクトで別途インストールします。
import { JSDOM } from 'jsdom'
import Typesetter from 'palt-typesetting'
const dom = new JSDOM('<p>日本語English</p>')
const typesetter = new Typesetter()
typesetter.renderToSelector('p', dom.window.document)
// renderToElements(element) も引き続き使用できます。
従来の内部モジュール dist/win.js / dist/win-browser.js は廃止しました。
これらを直接importしていた場合は、呼び出し元でDOMを用意する方法に移行してください。
thinSpaceWidth は 0.2em、20%、calc(1em / 2)、var(--spacing, 0.2em) などを指定できます。使用できる文字はASCII英数字、スペース、および .%()+*,/_- です。CSSコメント、HTML属性や別のCSS宣言を挿入する文字を含む値、空文字は既定値の 0.2em に置き換えられます。
Palt Typesetting ライブラリは HTML 入力をサポートしていますが、入力された HTML をサニタイズする機能は含まれていません。 入力を信頼できない場合は、適切なサニタイザライブラリと共に使用することを強く推奨します。
改行判定には、UAX #14(Unicode 15.0)に基づく内蔵の実装を使用しています。
本ライブラリは 2 文字の境界だけを判定するため、Line_Break クラスの区間表と組み合わせ表だけを持ち、実行時の依存はありません。
これは従来 linebreak にセグメント境界の 2 文字だけを渡していた挙動との互換を保つためのもので、文章全体に対する UAX #14 の完全な判定ではありません
(例: 地域指示子の個数に依存する LB30a は考慮しません)。
区間表は npm run generate:line-break で、scripts/ucd/ に置いた Unicode の LineBreak.txt から生成します。
判定結果は、Unicode の LineBreak.txt の全コードポイントのクラスと、LineBreakTest.txt の 2 文字のテストケースに照らしてテストしています。
テストケースのうち、前後の文脈や East_Asian_Width に依存する規則(LB25, LB30, LB30b)による 18 件は、従来の挙動に合わせた既知の差異です。
開発・テストには Node.js 22.13 以上の 22 系、24 系、または 26 系を使用してください。CI でもこれらのメジャーバージョンを検証します。
npm ci
npm test -- --run
npm run lint
npx tsc --noEmit
npm run build
npm ci --prefix demo
npm run build --prefix demo
Firefox では、バージョン 125 から Intl.Segmenter のサポートが予定されています。 ↩