PB-100の宇宙の中の人
PBロッキーの日記

マイコンプログラムをHTMLで表示するCSSのポイント、禁則処理、コピーペーストなど

とてもニッチかつめんどくさい問題を扱っている為、なるべく汎用的に書くことに苦労しました。

2003年のホームページの開設以来、HTML を書いて17年が経ちました。この間に Web 技術を生業とすることになった僕ですが、テキストを表示するという一点だけでもまだまだ Web ブラウザには苦労をさせられます。ブラウザによっては意図した見た目や動作をしてくれません。

HTML5 を信じない、しかし Web ブラウザを愛す。ということで頑張っていきたいと思います。

マイコンBASICのプログラムリストをHTMLで表示するCSSのポイント

Smile Basic プログラムリスト掲載ページ

さて、CASIO PB-100 用 CSS ライブラリ hamura.css はお陰様でようやく形になってきました。本記事では hamura.css の中でプログラムリスト等の表示を担当する pbList.css について、黒魔術、バッドノウハウが堆積してきたので、ここで2点とおまけの1点について記事にして整理します。

使いどころとしては、プチコンでのプログラミング学習のように、ユーザーが手入力するプログラムを Web サイトで公開する際です。ニッチです。

  1. テキストの折り返し位置、禁則処理の無効化について
  2. コピーペーストしたテキストの改行
  3. おまけ IE6 以下では連続する空白文字を DOM インターフェイスで取得する際に1つの空白文字になってしまう問題を回避する

検証結果

  • レイアウトの手段、text-indent または float
  • 1. コピペしたテキストの折り返し、○または×
  • 2. Web フォント時の折り返し、○またはイマイチ
ブラウザレイアウト1.折り返し2.コピペ品質
Windows 10 Chrome 80.0float?×
text-indent○(*1)
Windows 10 Chrome 79.0floatイマイチ×
text-indentイマイチ
Windows 10 Edge 44.18362(*2)floatイマイチ×
text-indentイマイチ
Windows 10 Firefox 72.0float?
text-indent○(*1)
Mac OSX Safari 13.0float??
text-indent○(*1)?
Windows 10 IE5, IE7floatイマイチ
text-indent??
Windows 10 IE8, IE9float
text-indent??
Windows 10 IE10, IE11float
text-indentイマイチ
  1. line-break:anywhere に対応している
  2. EdgeHTML 18

まとめ

行番号付きの BASIC リストを整列して表示する方法は複数考えられます。パっと思いつくだけでも、positon:absolute, display:table, float, text-indent があります。今回は殆どのブラウザ向けには text-indent を使ってレイアウトしました。

しかし IE8~11 では float でレイアウトした場合にだけ、テキストの折り返しが意図したものになりました。条件付きコメントで分けることのできる IE8~9 は良いとして、他のブラウザ用と共通の CSS ファイルを読み込む IE10~11 は CSS ハックで float レイアウトに上書きする必要がありました。

他のモダンブラウザも float でレイアウトしても一見では良かったのですが、コピーペーストに難があったため text-indent でレイアウトする他ありませんでした。

1. テキストの折り返し位置、禁則処理の無効化について

"コマンドが行の途中で折り返す問題は、IE11以下で解消できた。" 2020年1月14日のツイート

テキストの折り返しはかつてのマイコン BASIC のプログラムリストがそうであったように、ボックス幅での折り返しを目指しました。結局、これが出来ているのは IE8~11 と Firefox と Safari, Chrome でした。

この内、IE8~11 が右端で折り返す条件が特殊で、ボックス幅を無視する筈の white-space:pre といった意外な指定が効きました。この動作は Trident エンジンの個性の様で EdgeHTML エンジンはこれと異なります。旧バージョンの方が良質な表示をするケースはちょっと複雑な気分です。

Firefox と Safari では line-break:anywhrere をサポートしているお陰で意図した折り返しをします。Chrome はこの記事を書いている最中にバージョンが80に上って anywhrere をサポートしました。


これは、ブラウザの禁則処理によって、文書作成者の意図しない位置でテキストが折り返されることが関係しています。禁則処理は通常の文章では不都合は起き難いですが、プログラムリストでは異なってきます。

PB-100 のプログラムの場合、"" 内で折り返された際にスペースの存否が分からなくなります。このような禁則処理を CSS で制御して、空白文字を正確に表現することが上記環境で実現しました。

2. コピペしたテキストの改行

普段はここまでチェックすることは無いのですが、プログラムの配布に使用するものなので検証しました。

float でレイアウトした際に Edge(EdgeHTML) と Chrome で、テキストのコピーペーストの際に不要な改行が現れました。これらのブラウザでは要素に効いているスタイルを元に改行を挿入するようです。一方 IE と Firefox はスタイルを反映しないようです。

float レイアウトでは <span> をブロック要素にするため、要素の後に改行が追加されてしまいました。これを回避するために <span> がインライン要素のままレイアウトする手段を選ぶ必要がありました。そこで text-indent のレイアウトを採用しました。

3. おまけ IE6以下では連続する空白文字をDOMインターフェイスで取得する際に1つの空白文字になってしまう問題を回避する

僕は、クロスブラウザを考慮しなくなると途端にモチベーションが下がってしまう特殊性癖なので、IE6 以下の対応も続けています。

IE6 以下では、連続する空白文字をDOMインターフェイスから取得する際に1つの空白文字になってしまう挙動があります。プログラムコードをマークアップする際には <pre><code> を使用しますが、この為に IE6 時代のコードハイライターは、空白文字に関する情報を失わない <textarea> でのマークアップを推奨していました。

しかし <textarea> はマークアップとして不適であり、Javascript が無効でコードハイライト出来なかった場合の CSS でのスタイリングも大きく制限されます。そこで hamura.css では、<pre> を使いつつ、連続する空白文字をひとつおきに &nbsp; に置換する苦肉の策を弄しました。以下のような変換を pbList エディタで行っています。

return cmd.split( '  ' ).join( ' &nbsp;' );

本件に関する素晴らしい検証記事は次になります。

驚いたことに Firefox 2.0 の出力結果とまったく異なるのだ。先頭の改行文字は無視され、残りの改行文字やタブは、半角スペース(0x20)にすべて変換されてしまっている。これはブラウザ上の表示に一致する。つまり IE の TextNode に対する考え方は、それをなるべくブラウザの表示結果と一致させようということらしい。