« ^ »

文章を書く事を工夫する

所要時間: 約 4分

最近、文章を書く機会が特に増えた。ブログも書いているし、ソフトウェア開発で必要な文章も書くし、書籍に関連する仕事でも当然文章を書く。誰かとコミュニケーションを取る場合でも、テキストチャットやメールの比率が大きく、音声や映像でのコミュニケーションよりも文章でのコミュニケーションを使う。

文章を作成する作業は、使用頻度が多いため重要だ。良い文章を作成できる事は、いろんなものの品質を上げてくれる。「良い文章」とは何かを考える事は大切な事だが、それには時間がかかるし、継続的な反復が必要だろう。今回はそういった点にはあまり焦点を当てず、もっと手軽なところから実践している工夫について書く。あくまで僕が主観を元に考えた事だったり、他の人の考えた事や記事等を参考にした内容だ。

読み上げ機能で誤字や脱字を減らす

文章の誤字や脱字は無い方が良い。誤字や脱字があると正しく意味が伝わらなかったり、意味不明になったり、読みにくかったりする。

これは明らかな間違いなのだから無い方が当然良い。しかし時間がない時に作成した文章は、見直しの時間が取れず、特に誤字や脱字が多くなってしまう。また自分が作成した文章は、あらかじめ頭の中でイメージが出来上がっているため、どうしても間違いに気がつけない事もある。

しかし、一度音声で聞いてみると、意外と文章の抱える問題に気が付く事ができる。できれば他人他人に読んでもらう方が問題に気付く事ができる。他人という人に音読してもらう事は難しいかもしれないけれど、コンピュータの読み上げ機能で読ませると、不自然な文章は不自然に読むため、音声を聞いた時の違和感を強く感じる。

僕はmacOSを使っているが、macOSには say というコマンドが予めインストールされている。これを使用すれば簡単に読み上げさせる事ができる。 say コマンドは標準入力に渡した文字列を音声で読み上げる。

echo "こんにちは" | say
sayコマンドで「こんにちは」を読み上げる

これを利用しEmacs Lispでリージョン選択した範囲を読み上げるsay-on-regionコマンドを用意した1

(defun say-on-region ()
  (interactive)
  (let ((proc (or (if-let* ((buf (get-buffer "*SAY*")))
		      (if-let* ((current-proc (get-buffer-process buf)))
			  (when (eq 'run (process-status current-proc))
			    current-proc)))
		  (start-process "*SAY*" (get-buffer-create "*SAY*")
				 "say" "--rate" "500"))))
    (process-send-region proc (region-beginning) (region-end))
    (process-send-string proc "\n")))

今回はsayを利用したが、読み上げ機能はいろんなものがいろんな形式で提供していて何を使っても良い。音声で聞いてみるというは、読み返すのも楽になるし、黙読では気付きにくい内容にも気付けるので試してみて欲しい。

textlint

これらの記事を参考にtexlintの整備をする。

それぞれ記述している内容はほとんど同じ内容だ。ここでやったことはそれらの記事の内容をほぼそのまま行っている。ファイル名やファイルパスなど微妙に変更したが、概ね同じ方法になっている。

まずはtextlintをインストールする。

npm install -g textlint

次に校正ルールをインストールする。ここでは技術文書向けの校正ルールを用いる。

npm install -g textlint-rule-preset-ja-technical-writing textlint-rule-preset-ja-spacing
npm install -g textlint-rule-unexpanded-acronym textlint-rule-write-good textlint-rule-ginger textlint-rule-alex textlint-rule-common-misspellings textlint-rule-en-max-word-count

Org-modeでtextlintを実行するためにパーサーをインストールする。

npm install -g textlint-plugin-org traverse
npm install -g @textlint/ast-node-types

textlintを実行するスクリプトを実装する。

#! /usr/bin/env bash
SCRIPT_DIR=$(cd $(dirname $0); pwd)

FILENAME=$1

if grep -q [ぁ-ん] $FILENAME; then
    TEXTLINTRC="${SCRIPT_DIR}/../textlint/ja.json"
else
    TEXTLINTRC="${SCRIPT_DIR}/../textlint/en.json"
fi

EXTENTION=${FILENAME##*.}

if [ $EXTENTION = "org" ]; then
    PLUGIN="--plugin org"
else
    PLUGIN=""
fi

exec textlint --format unix --config ${TEXTLINTRC} ${PLUGIN} ${FILENAME}

flycheckのチェッカーを定義する。

(flycheck-define-checker textlint
  "A linter for text."
  :command ("textlint-check" source)
  :error-patterns
  ((warning line-start (file-name) ":" line ":" column ": "
            (id (one-or-more (not (any " "))))
            (message (one-or-more not-newline)
                     (zero-or-more "\n" (any " ") (one-or-more not-newline)))
            line-end))
  :modes (text-mode markdown-mode gfm-mode org-mode))

ただし、textlintの実行とflycheckの組み合わせには問題もある。例えば、textlintは文章が多い場合にはエラーを出力し異常終了する。またtextlintの環境を整備するのも若干面倒だ。それ用のDocker Imageを作成してしまってもよいかもしれない。あと、textlintの技術文書の校正ルールが結構厳しくて「〜だと思う」や「〜かもしれない」のような表現は校正によってエラーとなる。曖昧な表現は許されず、断定することを強制してくる。論文を記述するという意味では問題にならないが、テクニカルエッセイのような文章の場合は、これらの表現は頻繁に使いたくなる。そもそも断定できることなんてこの世にあるのだろうか。