Hi, I detected your main language is not Japanese. I have an english version of about me, so please try it!

この投稿は2年半前の記事です。 情報が古くなっている可能性があるので、その点ご了承ください。
2015 年 7 月 3 日 757日前)
2,282文字 (読了時間5分)

SPONSORED LINK

WordPressのビジュアルエディタであるTinyMCEで自動行頭一字下げを実現したのでご報告(?)です。要はこういうことです。

自動行頭一字下げとは?

「段落一字下げ」とかいろんな言い方がありますが、「段落の一番最初を一文字分空白にする」というアレですね。ブログでは段落(pタグ)の前後にマージンがつくことが多いのですが、日本語の段落では特に前後一行あけなどせず、「段落の開始時点で一字下げる」というのが通常のルールです。

MS Wordなんかにはこの機能があって、改行するとその時点で次の行からは一字下げになったりします。

行頭一字下げの機能がないとなにが問題か

破滅派に投稿される作品はWordPressの管理画面から投稿するというより、なんらかのソフトを使って作成したテキスト(ないしリッチテキスト)をコピペするというパターンが多いようです。

で、特にWordの場合は自動行頭一字下げが変になることが多いですね。小説などを書いていると「鉤括弧ではじまる行は一字下げをしない」というルールを遵守することが多いのですが、次のようなケースで自動行頭一字下げが壊れます。

  •  地の文を書く(この行は一字下げ)
  • 「そして、会話を書く」(この行は自動一字下げされてしまったので、BSキーなどで一字下げを解除)
  • そして、この行は一字下げじゃなくなる

Wordは一度一字下げが解除されるとその後も自動一字下げが解除されたままなので、それ以降、全角スペースを入れていくことになります。次の日になると、保存・起動をした結果かどうかわかりませんが、再び自動一字下げが有効になっていたりします。結果として、何日もかけて小説を書いたりすると、一字下げが自動と手動の入り混じった変なテキストデータが出来上がります。

自動行頭一字下げを実現するには?

さて、管理画面から入稿したデータを表示するテーマ側で自動行頭一字下げを実現するのはそれほど難しくありません。こんなCSSを用意します。

.indent{
    text-indent: 1em;
}

indentというクラスがついた要素は1文字インデントするということですね。で、Javascriptを利用して、該当する要素すべてにindentというクラスをつけてまわります。

jQuery(document).ready(function($){
    // 投稿本文のpタグを全部取得
    $('.post-content p').each(function(i, p){
        if( ! /^[  【】《〔〝『「(”"'’\(\)]/.test($(p).text()) ){
            // 正規表現で一字下げしない文字から始まっていなかったら
           // インデント用のクラスを付与
            $(p).addClass('indent');
        }
    });
});

これを行うことで、「全角スペースがあろうがなかろうが行頭一字下げ」という状況が実現できます。

赤い四角の部分は自動一字下げ
赤い四角の部分は自動一字下げ

ところがどっこい、投稿編集画面で同じような機能を提供するために同様のアプローチを取ることはできません。いままさに編集している画面で内容に応じてクラスを付与する、つまり、いままさに編集しているDOMをJSで勝手にいじるというのはあまりよくないアプローチだからです。

WordPressにはeditor-styleという機能があり、ビジュアルエディタの見栄えをある程度コントロールできるのですが、自動行頭一字下げはCSSだけでは実現できない(foo:contains()はない)のです。

では、どうしたらよいでしょう?

TinyMCEのAPIを使う

さて、ビジュアルエディタはiframeとtextareaを交互に通信させるもので、WordPressのHTMLエディタというのはようするにtextareaで、ビジュアルエディタというのはbody以下がcontentEditableなiframeです。

それではどうすればよいかというと、ビジュアルエディタが更新されるにつれ、iframeの中のHTMLにstyleタグを書いていけばいいんですね。戦略としてはこうなります。

  1. TinyMCEのプラグインを登録する
  2. プラグインにビジュアルエディタの変更イベントを監視させる
  3. 変更があるたび、pタグを全部調査し、それが行頭一字下げの必要なテキストから成り立っているかを調べる
  4. 該当する行のインデックスを保存し、その全てに対してCSSを書く ex. body p:nth-child(7){ text-indent: 1em; }
  5. styleタグを生成し、それをheadに突っ込む

こうすることで、「編集中のDOMを汚染しないで自動行頭一字下げする」という機能が実現できます。

で、これをどうやるかというと、ちょっとコードを書くのが面倒くさいので該当するコミットへのリンクを貼って終わりにします。ほんとうにありがとうございました。

文字組版入門

文字組版入門 [書籍]

クリエーターモリサワ

出版社日本エディタースクール出版部

出版日2013 年 4 月 1 日

商品カテゴリー単行本

ページ数63

ISBN4888884048

Supported by amazon Product Advertising API

 

SPONSORED LINK

この記事について

この記事はが2015 年 7 月 3 日にプログラミングの記事として公開しました。

フォローしてください

ここで会ったのもなにかの縁。
高橋文樹.comの最新情報を見逃さないためにもフォローをお願いします。
めったに送らないメルマガもあります。