原稿用紙プレビューの横書き対応

about novel-writer

今日リリースしたnovel-writer 1.9.0で、従来「縦書きプレビュー」と呼んでいた原稿用紙プレビューの横書きに対応しました。VS Codeの設定 > Novel.preview.WritingDirectionで設定できます。

特に要望が多かったわけではないのですが、中国語や韓国語でも使いたいケースが出てきたので、まずは横書きに対応することにしました。繁体字を用いる台湾や香港では縦書きの本も多いのですが、それ以外はすべて横書き文化になってしまっているのです。

切り替え機能の実装は思ったよりも簡単でした。ほとんどのCSSには画面に対する位置関係の指定する物理指定を、論理構造ベースに置き換えることができました。横書きの時に画面上部に物を配置したい時、topと書くのではなくブロックの先頭方向を指定するblock-startを指定するようなやり方です。

Web出版や技術文書、英文の多い作品を書く場合にお使いください。

novel-writerで新聞寄稿

about novel-writer

小説を含め、ほとんど全ての文章をVS Codeの小説執筆支援機能拡張 novel-writerで書くようになった。新聞の書評や、3月14日から始まった「どこから来たの?」も、VS Code + novel-writerで書いてGit + GitHubで管理している。

自分で作っておいてなんだが、novel-writerの縦書きプレビューはかなり出来がいい。段落ではなく行番号を表示し、ページ区切りも確認できるし、禁則処理も標準的な形で行われる。本紙の組版とほとんど同じ字切りを見ながら執筆できるので、文字が多過ぎたり少なすぎたりすることはなくなった。

最近はスクリーンショットのようにエディターの下に横中のプレビューを配置することにしている。1.7.1ではクリックした場所にカーソルを動かす機能も少し強化した。

新聞連載でPDFを出すタイミングも増えたので、PDFのフッターに「16文字25行」のように柱を追加することにした。本当はPDFにも罫線と行番号をつけるオプションが欲しいのだけど、そこまでは手が回らない。

本誌と同じ組版を確認しながら執筆することができるようになった

ストレスなく書けるようになったけど課題は多い。

縦書きプレビューの組版はかなり良くできているのだが、句読点をブロックの外に追い出す「ぶら下げ」はまだできない。Safariはぶら下げを行うcss「hanging-punctuation: allow-end」に対応しているけれど、VS CodeのWeb Viewではまだ動かない。利用できるようになったらぶら下げのオンオフスイッチも搭載する予定。最近はぶら下げをする媒体もそんなに多くないけどね。

日本語のシンタックスハイライト

about novel-writer

プログラム用のエディターは賑やかだ。変数や修飾子、プロパティ、関数、制御用の予約語などが異なる色でハイライトされている。下のスクリーンショットはnovel-writerの「〜た」「〜る」変換を行うコードの一部だが、この短い部分だけでも、色分けされていなければコードを読み解くのに苦労してしまう。

    // 対象の文だけ処理する
    if (processingSentence === targetSentence) {
      // 自立「〜る」の変換
      if (
        token.conjugated_form === "基本形" &&
        token.conjugated_type.match(/.+ガ行$/) &&
        nextToken.pos_detail_1 === "句点" &&
        nextToken.surface_form === "。"
      ) {
        const attributedVerbeForm = token.surface_form.replace(
          /(.+)[ぐ]/,
          "$1いだ"
        );

もちろん読める。だけど括弧やクォーテーションの閉じ忘れひとつとっても、色分けされているのに越したことはない。

というわけで、日本語でも品詞ごとにハイライトするといいんじゃないかと思った次第。VS Codeを使い始めて三日目で作ったのが、会話の部分を色分けする言語拡張だった。行頭が「、行末が」で終わる行を、プログラミング言語のコメントアウトに指定するだけの簡単な色分けだ。ついでに、青空文庫のルビにも色をつけることにした。

もちろん鉤括弧があるかどうかなんて読めばわかる。しかし色分けをしたことで視認性は上がった。エディターの右にあるミニマップ(テキストの縮小表示)では、会話が続くか続かないかを俯瞰することもできた。

書いている時に見やすくても、出版した後で読みにくければ意味がない。そこで縦書きプレビューを表示することにした。VS Codeを使い始めた時は、n-fukujuさんの作った縦書きプレビューを使っていた。これが想像していたよりもずっと良かったので、自分でも機能拡張を作ろうと決意したのだ。

Novel-writerで縦書きプレビューを表示しているところ

色分け機能だけだったnovel-writerは縦書きプレビューを内蔵してサーバー化し、原稿用紙のような見た目に変え、文字数カウントをつけ、バラバラに書いたテキストファイルをひとつに結合する機能をつけて、PDF出力もできるようにした。Textlintも導入して、正規表現を使う校正機能や、タイプミスで生まれる助詞の連続をエラー表示できるようにもなった。

仕事に使えるようになったVS Codeだが、どうしようもない弱点もあった。

テキストが単語分割されていないので、カーソルを単語ごとに移動できなかったのだ。「てにをは」や「、。」などを区切り文字にして凌いでいたがストレスから解放されるには、日本語を単語に分解する形態素解析をするしかない。形態素解析ができれば、日本語のハイライトをもう一段階進められるし、「です・ます」を「だ・である」に変換したり、「していた」を「している」に変換できることもわかっていた。ルビの読み仮名も自動で挿入できる。

というわけで、昨年の秋にようやくKuromoji.jsという形態素解析ライブラリを導入することに成功した。日本語をハイライトできるようになったのだ。

動き出した時にようやく気づいたのだけど、日本語の品詞がハイライトされているのを見るのは初めてだった。色分けはちょっとだけ難航した。

文法が緩い会話はグリーン系統で統一することにした。「あはははっ」のように、2文字目の「は」と3文字目の「は」が異なる品詞に分解されてしまう可能性がある。地の文の色分けは、品詞の種類が多いので少し悩んだ。名詞グループの中でも、普通名詞と代名詞、固有名詞は扱いを変えたいのだ。

特に代名詞は可読性を落とすので積極的に消していきたい品詞のひとつだ。逆に名詞の中でも接尾語として使われる単語は目立たせたくないし、普通名詞には主張してほしくない。動詞は重要なので目立ってほしい。副詞は本質的に不要だ。なければない方がいいので思い切り目立たせたい。助詞は、タイプミスが一番多く現れる部分なので見えてほしいが意味は欲しくない――そんな基準で色をつけてみた。

結果的にびっくりするような色合いになってしまったが、使うと違和感はすぐに消えると思う。単語は探しやすくなるし、入力ミスにも気付きやすくなる。読む速度も上がるはずだ。難点は、見た目がちょっと煩雑ということか。いずれ、カラーリングを簡単に指定できる画面も作ってみようとは思う。

ルビ追加機能の搭載

about novel-writer

novel-writer 1.7.0で青空文庫記法ルビの追加機能を搭載しました。

novel-writer – Visual Studio Marketplace

テキストエディターでルビを追加したい場所を選択して ⌘+R(WindowsやLinuxではCtrl+R)すると、ルビを入力するためのダイアログボックスが現れます。

選択範囲がある場合には、その範囲全体に有効なルビを追加します。たとえば「国際宇宙ステーション」に「ISS」というルビを付与したいときは以下のように選択しておきます。

今日の夕方、国際宇宙ステーションが東京の空を飛んだ。

ここで⌘+R(WindowsやLinuxではCtrl+R)を押してルビの追加を行うと、ルビを指定する入力ボックスが現れます。ここでISSと入力してEnterを押すと、ルビが挿入されます。

今日の夕方、|国際宇宙ステーション《ISS》が東京の空を飛んだ。

「|(縦棒)」は青空文庫記法で漢字以外の文字グループにルビをつける時の開始記号です。novel-writerは選択範囲が漢字だけでない場合には開始記号を自動的に挿入します。

novel-writerは、選択範囲がない場合にルビ追加を行うと、直前の単語、またはカーソルの入っている単語にルビを追加します。

今日の夕方、国際宇宙ステーションが東|京の空を飛んだ。
今日の夕方、国際宇宙ステーションが東京|の空を飛んだ。

上のいずれかの状態でルビを追加すると、ルビ入力ボックスが現れます。

この時には、読み仮名も推測したものが入っていますのでこのままEnterを押すと、ルビが挿入されます。

今日の夕方、国際宇宙ステーションが東京《とうきょう》の空を飛んだ。

novel-writerはカーソルが入っている場所の単語と読みを判定するために、Kuromoji.jsによる形態素解析を行なっています。

ちょっとした機能ですが、とても快適になりました。

たんごカーソル

2021年の春から、マイクロソフト社のプログラム開発用エディター、Visual Studio Codeで執筆のほとんどを行うようになりました。

高速なユニコードエディターに複数ファイルを閲覧できるエクスプローラー、正規表現を用いた検索置換、このブログの「小説Git」でも紹介したGitとの連携機能、統合されたターミナルに魅力的なエクステンションの数々は、これで小説を書こうと思うのに充分な動機になりました。

しかし欠陥がないわけではありません。

行が折り返す部分での日本語入力の表示の崩れ方は見苦しいし、あらゆる設定がプログラミング用なので、標準の状態ではとても日本語の執筆に向いているとは言えません。何より致命的なことに、VS Codeは日本語の単語分割を理解してくれないのです。

Optionキーを押しながら右カーソルキーを押すと、VS Codeのカーソルは次の単語の先頭ではなく行末に移動してしまいます。

|たしは今日、旅に出ます。  「わ」の後ろにカーソルがある時に
      ↓          option + → キーで
わたしは今日、旅に出ます。|   行末に移動してしまう

本当は下のように動いて欲しいんですよね。選択なら右のような感じ。削除も単語単位でやりたいわけです。

わたし|は今日、旅に出ます。→    わたし今日、旅に出ます。⇧→
わたしは|今日、旅に出ます。→    わたしは今日、旅に出ます。⇧→
わたしは今日|、旅に出ます。→    わたしは今日、旅に出ます。⇧→
わたしは今日、|旅に出ます。→    わたしは今日、旅に出ます。⇧→
わたしは今日、旅|に出ます。→    わたしは今日、旅に出ます。⇧→
わたしは今日、旅に|出ます。→    わたしは今日、旅に出ます。⇧→
わたしは今日、旅に出|ます。    わたしは今日、旅に出ます

ないのなら作ってしまえ、ということで作ってしまえるのがVS Code用のいいところです。

たんごカーソル

紹介ページの先頭にも書いてありますが、独力で書いた機能拡張ではありません。VS Codeとのインターフェイスは、Suguru Yamamoto氏のJapanese Word Handlerzlib License)のコードを丸ごと使っています。日本語の単語分割はTaku Kudo氏のTinySegmenter 0.1(修正BSDライセンス)を組み込むことで、実用的な速度で動作するようになりました。

たんごカーソルはWebブラウザ版のVS Code、codespacesでも動作しますので、github.devやvscode.devからオンライン編集を行う時にもお使いいただけます。

小説の執筆だけでなく、ドキュメント執筆にも有用な機能拡張になりました。どうぞご自由にお使いください。