Documentation

段階的に導入する

導入は、スクリプトを1つ読み込むか、CSSプリセットを読み込むところから始まります。標準CSSだけでは揃わない環境には、DOMフォールバックを追加してください。ReactでもMarkdown / MDXでも手順は変わらず、本文の文字列に手を加えないという方針も共通です。

01

スクリプトタグで使う

ビルド設定を持たないサイトでは、スクリプトを1つ読み込むだけで動作します。CSSはバンドルに含まれているため、読み込むファイルは1つです。設定はタグの属性で渡し、読み込み後に追加された記事も自動的に対象になります。

HTML
<script
  src="https://cdn.mojikumi.jp/v1/mojikumi.min.js"
  data-target=".entry-content"
  data-style="article"
></script>
属性既定値内容
data-targetauto本文のセレクター。autoは既知の本文要素を順に探します
data-styleminimalminimal(控えめ)、article(両端揃え)、book(書籍の体裁)
data-precisionautonative、auto、fullのいずれか
data-indentプリセット任せfalseで字下げなし。2emのように量も指定できます
data-justifyプリセット任せfalseで両端揃えをやめます
data-hangingプリセット任せtrueで行末の句読点を版面の外へ出します
data-heading-breakプリセット任せtrueで見出しを文節で折ります
data-excludeなし追加で除外するセレクター。カンマ区切り
data-csstrue同梱CSSを読み込むかどうか
data-autotruefalseにするとMojikumi.start()を呼ぶまで何もしません

02

CSSだけで使う

CSSプリセットを読み込み、本文の要素にクラスを付けます。標準CSSに対応したブラウザなら、これだけで約物まわりの空白が詰まります。ビルド設定の変更もJavaScriptの追加も不要です。プリセットはminimal、article、bookの3つで、印刷の体裁にどこまで寄せるかが違います。

TSX
import "mojikumi/css";

<article lang="ja" className="mjk mjk-book">
  <p>『Webの日本語』を端正にする</p>
</article>

03

DOMフォールバックを追加する

標準CSSが未実装のブラウザでも同じ表示を得たい場合は、DOM層を追加します。約物が連続する箇所や、行頭・行末に置かれた括弧など、CSSだけでは揃わない位置を実行時に計測して補正する層です。precisionをautoに設定しておけば、対応済みのブラウザでは処理そのものが実行されません。

TypeScript
import "mojikumi/css";
import { mojikumi } from "mojikumi";

const instance = mojikumi(".article", {
  preset: "book",
  precision: "auto"
});

04

Reactで使う

サーバーでは通常のHTMLを出力し、ブラウザに届いた時点で不足分だけを補います。要素を囲むComponentと、既存の要素に適用するHookのどちらでも利用できるため、現在のレイアウトを組み替える必要はありません。

TSX
import { Mojikumi } from "@mojikumi/react";

export function Article({ children }) {
  return (
    <Mojikumi as="article" preset="book">
      {children}
    </Mojikumi>
  );
}

05

Astroで使う

Astroが出力するのは静的なHTMLなので、コンポーネントのscriptタグから呼び出します。フロントマターでCSSを読み込み、クライアント側のscriptでDOM層を適用します。ページ遷移でDOMが差し替わる構成では、astro:page-loadでもう一度呼んでください。

Astro
---
import "mojikumi/css";
---

<article class="article" lang="ja"><slot /></article>

<script>
  import { mojikumi } from "mojikumi";
  mojikumi(".article", { preset: "book" });
</script>

06

Vue / Nuxtで使う

onMountedはブラウザでしか実行されないため、Nuxtのサーバーレンダリングでも本文はそのまま出力されます。コンポーネントが破棄されるときにdestroyを呼び、生成した要素を残さないようにします。

Vue
<script setup>
import { onBeforeUnmount, onMounted, ref } from "vue";
import { createMojikumi } from "mojikumi";

const root = ref(null);
let instance;

onMounted(() => {
  instance = createMojikumi({ preset: "book" }).mount(root.value);
});

onBeforeUnmount(() => instance?.destroy());
</script>

<template>
  <article ref="root" lang="ja"><slot /></article>
</template>

07

SvelteKitで使う

$effectはブラウザでのみ実行されるため、サーバーレンダリングの結果には手が入りません。返した関数が後片付けになるので、コンポーネントが消えるときにdestroyが呼ばれます。

Svelte
<script>
  import { createMojikumi } from "mojikumi";

  let root;

  $effect(() => {
    const instance = createMojikumi({ preset: "book" }).mount(root);
    return () => instance.destroy();
  });
</script>

<article bind:this={root} lang="ja"><slot /></article>

08

Markdown / MDXで使う

rehypeプラグインとして組み込むと、記事本文にプリセットが適用されます。原稿のMarkdownは変更する必要がなく、書き手が字組みを意識することもありません。コードブロックと数式は処理の対象から除外されるため、記号の並びが崩れることはありません。

TypeScript
import rehypeMojikumi from "@mojikumi/rehype";

export default {
  rehypePlugins: [
    [rehypeMojikumi, { preset: "article" }]
  ]
};

09

プリセットを選ぶ

プリセットは、印刷の体裁にどこまで寄せるかの3段階です。minimalは標準CSSで届く範囲の妥協で、行末を揃えません。articleは両端揃えにして行末まで揃える、Mojikumiが本来やろうとしていることです。bookはそれに段落の字下げとぶら下げを足した書籍の体裁です。既定はminimalで、迷う場合はarticleを選んでください。行末を揃えるには両端揃えが要り、両端揃えにはブラウザがtext-spacing-trim: trim-bothを実装するまでDOM補完が要ります。何も指定しなかったページをその負担に署名させない、というのが既定を控えめにしておく理由です。旧名のweb、editorial、nativeもそのまま書けます。

調整minimalarticlebook
連続する約物○○○
行頭の調整○○○
和欧文間○○○
両端揃え—○○
行末の調整条件付き○○
段落の字下げ——1em
ぶら下げ——○

09

字下げと両端揃えを選ぶ

段落の字下げと両端揃えは、日本語組版の正誤ではなく、そのページをどう設計するかの判断です。プリセットに固定せず、indentとjustifyで上書きできます。書き落とせばプリセットの判断がそのまま使われるので、bookの体裁のまま字下げだけをやめる、といった指定ができます。justifyをfalseにすると行末の調整も止まります。両端揃えでなければ効かない調整だからです。

HTML
<script
  src="https://cdn.mojikumi.jp/v1/mojikumi.min.js"
  data-style="book"
  data-indent="false"
></script>

10

ブラウザの実装との切り替え

precisionは、標準CSSとDOM補完のどちらをどこまで使うかの指定です。既定のautoでは、ブラウザが実際に約物を詰めているかを実測してから判断します。構文としては対応していても表示が変わらない実装があるため、対応表ではなく実測で切り替えています。

値動作使いどころ
native標準CSSのみを使用しますJavaScriptを増やしたくない場合
auto不足している処理だけを補います通常はこれで十分です
full常にDOM補完を適用します検証時や、実装差を確認する場合

11

適用範囲を変える

コード、フォーム、編集中の領域、SVG、MathMLは、指定がなくても対象から外れます。任意の範囲を外したい場合は、その要素にdata-no-mojikumiを付けます。まとめて外すなら、excludeやdata-excludeにセレクターを渡します。

HTML
<span data-no-mojikumi>console.log("日本語")</span>
  • 既定の除外:script、style、code、pre、kbd、samp、textarea、input、select、option、contenteditable、svg、math
  • data-no-mojikumiを付けた要素と、その内部
  • data-excludeまたはexcludeで追加したセレクター

12

プログラムから操作する

スクリプトタグで読み込むと、グローバルのMojikumiから操作できます。data-autoをfalseにしておけば、開始のタイミングも自分で決められます。npmから使う場合は、同じ処理をmojikumiパッケージのmojikumi関数が担当します。

JavaScript
Mojikumi.start({ target: ".article", style: "book" });
Mojikumi.refresh();
Mojikumi.stop();
関数内容
start(options)適用を開始し、以降に追加された記事も対象にします
refresh()行頭・行末の判定をやり直します
stop()生成した要素とクラス、読み込んだCSSをすべて取り除きます

13

バージョンを固定する

/v1/は修正が出るたびに中身が入れ替わります。貼り直さずに改善を受け取れる代わりに、こちらの変更がそのまま届きます。変更のタイミングを自分で決めたい場合は、バージョンを含むURLを指定してください。こちらのファイルは書き換えられないため、1年間キャッシュされます。

HTML
<script
  src="https://cdn.mojikumi.jp/0.2.1/mojikumi.min.js"
  data-target=".entry-content"
  data-style="article"
></script>
  • 現在の最新版は0.2.1です
  • 固定したURLは更新されないため、新しい版へ移るときは書き換えが必要です
  • 配信物が置き換わっていないことまで確かめるなら、ファイルからハッシュを作ってintegrity属性を付けます

14

自分のサーバーへ置く

CDNを使わない場合は、npmパッケージに含まれる同じファイルを自分のサーバーへ置けます。node_modules/mojikumi/dist/mojikumi.browser.jsを公開ディレクトリへコピーし、srcをそのパスに変えるだけです。動作は変わりません。

HTML
<script src="/assets/mojikumi.min.js" data-style="article"></script>

15

元に戻す

スクリプトタグを消す、あるいはstop()を呼ぶと、その場で元の状態に戻ります。Mojikumiは本文の文字列を書き換えないため、取り外したあとに痕跡は残りません。

  • 生成した要素とクラスを取り除き、変更した属性を元の値へ戻します
  • 本文の文字列は変更していないため、保存されたデータには何も残りません
  • スクリプトが読み込めなかった場合も、本文はそのまま表示されます

16

設計方針

  • まず標準CSSで動作し、ブラウザが対応していればそれだけで完結します
  • 本文の文字列は書き換えないため、コピーした文章も読み上げの内容も元のまま保たれます
  • ブラウザの対応が進むほど、読み込まれるコードは自然に減っていきます
  • 約物メトリクスを備えていない書体では、詰めを適用しません

次のステップ

実際の文章で見比べる

Playgroundへ