神テキスト問題：スペースでレイアウトされたテキストをスマホで見やすくする3つの方法

## 「ネ申テキスト」、もしくは「神テキスト」とは
皆様、「ネ申Excel問題」、というものをご存知でしょうか？
「ネ申Excel」とは「紙（への出力しか考えていない）Excel」の隠語で、
データ再利用性の低さが三重大・奥村氏などから指摘されています。

>「ネ申」は「神」の隠語であるが，「紙（への出力しか考えていない）Excel」の意味も含んでいる。
http://oku.edu.mie-u.ac.jp/~okumura/SSS2013.pdf

この「紙への出力しか考えていない」レイアウトはExcelにかぎらず、
当然テキストでも存在します。
多くは「スペース」により文字間隔を調整し、見事なテーブル組みを行っているものもあります。

本稿では、こうした「スペースにより文字間隔を調整したテキスト」を「ネ申テキスト」と呼びます。

ネ申テキストは様々なところで使われています。
プログラマが馴染み深いところでは一昔前の「Readme」テキストでも使われていましたし、
公的機関などが提供しているデータがネ申テキストで提供されていることもあります。
私は[治療ノート](https://www.c-notes.jp/)という医療系のウェブサイトの開発に携わっているのですが、
そこでもやはり「ネ申テキスト」に遭遇します。

![indent_sample.png](https://qiita-image-store.s3.amazonaws.com/0/8893/859e2bc8-e348-469a-b4d4-69e0ffbef230.png)

ネ申テキストの例。[https://www.c-notes.jp/otcmedicines/後藤散](https://www.c-notes.jp/otcmedicines/%E5%BE%8C%E8%97%A4%E6%95%A3) より抜粋。

このように字下げを駆使したレイアウトは、パッと見ただけで文書の論理構造が理解しやすいですし、
テーブルレイアウトのような表現を使うことで、2次元で情報構造を把握することも可能で、
「視覚に訴えるドキュメント」といえます。



## 「ネ申テキスト」はスマートフォンでの表示が苦手
こうしたネ申テキストの問題とは何でしょうか。
データの"Machine Readability"が低く、データの再利用性が低いこと以上に、
本稿では「スマートフォンでの表示がツライ」点を大きな問題として取り扱いたいと思います。

![sp-view.png](https://qiita-image-store.s3.amazonaws.com/0/8893/d4358749-0725-3625-a7c4-4931c6ed25a3.png)
ネ申テキストをそのままスマートフォンで表示した例(´・ω・｀)
残念すぎますね・・・。

この画像は、さっきと同一のテキストをスマホで表示した場合の見た目です。
スマホの狭い幅ではレイアウトが崩れてしまい、
先ほどの「視覚に訴えるドキュメント」が見る影もなくなっています。

ネ申テキストは一定の幅で表示されることを前提としており、
綺麗に表示するために必要な幅は全角で40文字程度必要なことが多いようです。
（半角にして80文字、というのはCOBOLの時代からの歴史的経緯のようです）
一方、縦にもったスマートフォンで表示できる幅は高々 20 〜 30 文字程度であり、
それ以上の長さの文字列は折り返しが発生してしまい、レイアウトが大きく崩れてしまいます。

以下に、スマホサイトで表示するための対策を3つ、示します。

## 方法1. フォントサイズを小さくする
実装は一瞬でできますが、少しのフォントサイズでも大きく効果が出る場合がありますので、試す価値はあります。
例えば文字サイズを16ptから11ptに変更すると、1行あたりの文字数を 1.4 倍にすることができます。

>![スクリーンショット 2015-12-13 23.05.26.png](https://qiita-image-store.s3.amazonaws.com/0/8893/9d1ff671-17e1-47a6-0697-1062dbe5077b.png)
参考：http://touch-slide.jp/column/202/

「もう少しwidthが広ければ折り返しがなくなるのに、、、＞＜」みたいな時にはこの方法でしょう。
一方「お歳を召した方にも見ていただきたいから、フォントサイズは大きくしたい＞＜」といった要望には応えられませんね。。

## 方法2. 一部だけ幅を拡張する
スマホの幅のコンテンツの途中で、仮想的に横長いブロックを用意する方法です。
![wide-sp.png](https://qiita-image-store.s3.amazonaws.com/0/8893/28139c3a-7ec4-306d-bb7b-6d1caa30d24c.png)


HTML

```html
<div class="parent-box">
  <div class="width-overflow">
    // ここにネ申テキストを記述する
  </div>
</div>

```

CSS

```css
.parent-box {
  width: 100%;
  overflow-x: scroll;
  -webkit-overflow-scrolling: touch;
}

.width-overflow {
  width: 800px; /* スマホの幅より大きい */
  padding-right: 0px; 
}

```


  overflow-x: scroll;と、
  -webkit-overflow-scrolling: touch;
という記述を行うことによって、
縦に長いスマホサイトの一部で横スクロール(慣性スクロール)を可能にします。

メリットはオリジナルのレイアウトを保持しながら表示できること。
デメリットは大きい面積の一部を切り取って覗きこむ感じで、
俯瞰的にみにくいところです。

####動作を確認してみる
[https://www.c-notes.jp/otcmedicines/後藤散](https://www.c-notes.jp/otcmedicines/%E5%BE%8C%E8%97%A4%E6%95%A3) 
にスマートフォンからアクセスし、「注意・副作用」ボタンを押してみてください。
同じくPCでもアクセスして、その違いを感じていただければメリット＆デメリットがより伝わるかと思います。



### 方法3. ネ申テキスト用ワードラップ処理を実装する
ネ申テキストの特徴を利用した、ワードラップ処理を自前で実装する方法です。
ネ申テキストは、
(1)レイアウトの行の上下で位置を揃えるため等幅フォントを使う。
特に日本語環境下では、英数記号含めすべて全角を利用する。
(2)レイアウトの「ブロック」は、スペースなど限られた文字・記号で分割されている
という特徴があり、「レイアウトが崩れる理由は最後のブロックの分がワードラップされてしまうからだ」といえます。

>![スクリーンショット 2015-12-13 23.41.21.png](https://qiita-image-store.s3.amazonaws.com/0/8893/3d7b2544-8154-30c3-e2aa-cfbcf72cd223.png)

折り返された1行を抜き出した例です。最後のブロックが折り返されていますが、
2行目の先頭が、1行めの最後の空白直後、「吐き気」の下にくれば、見栄えが改善するはずです。

今回、この実装を "kami-text" gemとしてまとめ、簡単に試せるようにしています。

### そこで、kami-textを使ってみる

```bash
$ gem install kami-text
```

使うときは 

```rb
KamiText::wrap(文字列の配列, 折り返し文字数) 
```
のような形で渡します。
お試しテキストはこちらに用意しています。
https://gist.githubusercontent.com/zucay/fe8203f061b74a315781/raw/7b3f5149a1ca85e26e2fd05c6a6a2ed1b00f7aaa/document-sample

では、このテキストを読み込んでみましょう。

```bash
$ irb
irb(main):001:0> require 'open-uri'
=> true
irb(main):002:0>$ require 'kami_text'
=> true
irb(main):003:0>url = 'https://gist.githubusercontent.com/zucay/fe8203f061b74a315781/raw/7b3f5149a1ca85e26e2fd05c6a6a2ed1b00f7aaa/document-sample'

irb(main):004:0>KamiText.wrap(open(url), 25).each { |line| puts line }
２．服用後、次の症状があらわれた場合は副作用の可能
　　性があるので、直ちに服用を中止し、
この文書を持って医師、薬剤師又は登録販売者に相談し
てください
　　　　　〔関係部位〕　　：　　　　　〔症　　状〕
　　　　　　皮　膚　　　　：　　　発疹・発赤、かゆ
　　　　　　　　　　　　　　　　　み、青あざができ
　　　　　　　　　　　　　　　　　る
　　　　　　消化器　　　　：　　　吐き気・嘔吐、食
　　　　　　　　　　　　　　　　　欲不振、胸やけ、
　　　　　　　　　　　　　　　　　胃もたれ、腹痛、
　　　　　　　　　　　　　　　　　下痢、血便、胃腸
　　　　　　　　　　　　　　　　　出血
　　　　　　精神神経系　　：　　　めまい
　　　　　　その他　　　　：　　　鼻血、歯ぐきの出
　　　　　　　　　　　　　　　　　血、出血が止まり
　　　　　　　　　　　　　　　　　にくい、出血、
　　　　　　　　　　　　　　　　　発熱、のどの痛み
　　　　　　　　　　　　　　　　　、背中の痛み、過
=> (折り返されたテキストの配列が表示される)
```


### アルゴリズムを適用した場合
今回のプログラムの適用結果は以下のとおりです。数字の下のインデントや、テーブル組みの雰囲気を残したままで、折り返しがなされていることがわかります。
![8029a8fe-bad9-d6f5-dee4-99171a5f615d.png](https://qiita-image-store.s3.amazonaws.com/0/8893/d0351495-4b82-719e-d2c1-6d73653aa9bc.png)


ソースコードはこちら。
https://github.com/zucay/kami_text

今回実装したのは20行ほどのコードですが、そんな簡単なロジックでも「視覚に訴えるドキュメント」の匂いを残せているかと思います。
この方式のデメリットは「2カラム目が細いとワードラップがたくさん発生してしまい、行数が増えてしまう」点です。
こうしたケースでは方法2と組み合わせるなど、テキストの特性に応じたチューニングが必要です。
また、レスポンシブデザインなどでに動的に幅を変えたいケースでは、Javascriptで同様の実装をする必要があります。
Rubyで試行錯誤しながらJavascriptにポーティングしていく場合、「Opal」というRubyのJavascriptコンパイラが便利に使えます。
http://opalrb.org/try/

## まとめ
スマホから電子ドキュメントを見る機会が増えた現在ですが、
残念ながらまだまだ「ネ申テキスト」はなくなりそうもありません。
そんな中で「ネ申テキスト」を少しでもナチュラルに見せる方法をいくつか提示しました。
適材適所で技術を使いながら、試行錯誤しながら、よりよいモバイルウェブのユーザ体験を作りだせるとよいですね。

###謝辞
スマホの使い勝手を高めるCSSまわりは一緒にサービスを作ってるuemurakentaさんに教えて頂きました。
http://qiita.com/uemurakenta
uemurakentaさんは、ここのページをスマホで見た時の「用語解説」とかクールなUIを作っています。
https://www.c-notes.jp/disease/allergic_urticaria
この場を借りてありがとうございます。