ビジュアルエディタで起こるSyntaxHighlighterコード改変現象

wordpressのビジュアルエディタにはコード自動整形機能がついている。改行コードの自動付加や<p>タグの自動挿入です。時にこの自動整形機能が悪さをしてコードが崩れる現象が発生します。

Initializing...

どのような悪さをしてしまうのかまたこれを防ぐ手だてがないのか実験してみました。実験してみると、勝手に改行がどんどん増えてしまったり逆に必要な改行コードが取り除かれてしまったりします(ケース1)。これを防ぐ一般的な手当をして実験したのがケース2。ケース2でも改善はみられず、文字実態化により勝手に改行される現象は収まったもの&(アンパサンド)がダブって挿入される状態となってます。このコード改変の実体と最終的に当現象を改善するところまで実験を進めたいとおもっています

この現象は、ビジュアルエディタと通常のテキストエディタを何度も切り替えると発生する現象です。

発生しているコード改変状況

  1. 自動整形機能で改行が勝手に増える※1
  2. 文字実態化により&(アンパサンド)がダブって挿入される
※1:wordpressの自動整形は以下の動作をやります
  • 改行コードを「<br>タグ」に変換
  • 改行を2回続けて入力すると「<p>タグ」に変換
  • 「<br>タグ」を2個以上連続して入れると「<p>タグ」に変換
  • 「テキストモード」で入力した「<p>タグ」や「<br>タグ」が、「ビジュアルモード」に切り替えると削除されてしまう

再現する環境

当実験は、ワードプレス本体のバージョンおよび関連するプラグインとしてTinyMCE Advancedが関係します。本現象で特に困ったのは記事中にコードを記述するためのSyntax Highligheter Evolvedプラグインです。せっかくの参考例のコードがコピペでは動かなくなってします。

  • WordPressバージョン:4.3.4
  • TinyMCE Advanced:4.1.9
  • Syntax Highlighter Evolved:3.2.1
  • SyntaxHighlighter TinyMCE Button:0.7.8.4

実験するために使ったコード

実験のため、html/phpのコードの両方を使い、改行コードの勝手な挿入/削除がわかるように、1行1ステートメントの実験コードを以下の通りとしました。

<div>line1:本表示は1行に1ステートメントです。</div>
<div>line2:余計な改行が挿入されていない、改行が削除されていないことを確認!</div>
<?php //line3
$temp =1; //line4
$temp2 =1; //line5
$temp3 =1; //line6
// line7 ?>
<div>line8:end</div>

ケース1:改行問題

ケース1では、どのような現象が発生しているのかSyntax Highlighter Evolvedを使ったコード表示をスクリーンショットで撮ってみた。

なお、ワードプレス本体は全くの無修正、TinyMCE Advancedの該当オプション
”Stop removing the and tags when saving and show them in the Text editor”
はオフの状態です。

症状

ビジュアルエディタと通常テキストエディタを切り替えると、htmlコード内では改行コードが勝手に挿入しされ、phpコード内では必要な改行が削除されてしまっている。

実験のスクリーンショット

改変開始前のSyntax Highlighterのスクリーンショット画像。htmlやphpのコードは1行に1ステートメント表示され、キーワードで見やすくカラー表示されています。

kaigyo-case1-1

ケース1:改変前

最初に通常テキストエディタからビジュアルエディタに切り替えた場合には、前述の改行問題が発生しています。下図の2,3行目および6行目に注目。

kaigyo-case1-2

ケース1:ビジュアルエディタ移行後

テキストエディタに戻った次の画像では、特に直前のビジュアルディタと表示状態の変わりはなく問題はビジュアルエディタの切り替える場合に発生しているものと予想されます。

kaigyo-case1-3

ケース1:テキストエディタ戻り後

さらに1往復してテキストエディタに戻った場合のスクリーンショットが下図。phpコード内はその後改変は行われていないようですが、htmlコードはさらに改行が増殖しています。改行の数は2行ずつ増えている部分と1行ずつふえている部分が見られます。

kaigyo-case1-4

ケース1:2往復目テキストエディタ画面

ケース2:対処後の症状

適用した対処方法

いろいろと調べた結果、自動整形へのトラブル対処として

wpautopフィルターをはずす

このwpautopというフィルターは、

  • 改行コードを <br> タグに変換
  • インラインタグまたは文章には <p> タグを適用
  • 改行が2回続いたら <p> タグを適用

という3つの作用をするもので、まさしくこの事案に対処可能と思いましたので、次のとおりfunctions.phpに登録してみました。

/* フィルターの削除 */
remove_filter( 'the_content', 'wpautop' );
remove_filter( 'the_excerpt', 'wpautop' );
/* フィルターの削除2(ビジュアルエディタ用) */
function override_mce_options( $init_array ) {
    $init_array['indent']  = true;
    $init_array['wpautop'] = false;
    return $init_array;
}
add_filter( 'tiny_mce_before_init', 'override_mce_options' );

実験のスクリーンショット

はじめは1番目の実験と同様にコード改変前の状態!

kaigyo-case2-1

ケース2:改変前

ビジュアルエディタに移行すると、さっきの状態とは少し異なり改行こそ挿入されていませんが、文字の実態化が行われておりhtmlタグは&lt;や&gt;と変換されています。

kaigyo-case2-2

ケース2:ビジュアルエディタ移行後

テキストエデッタに戻ってもこのように全く同じ状態の表示になっています。

kaigyo-case2-3

ケース2:テキストエディタ戻り後

前と同じようにさらに1往復してみると、文字の実態化のための&lt;の先頭の&が&amp;amp;とさらに変換され、以後ビジュアルエディタのいくたびに際限なく増え続ける状態となってしまいました。

kaigyo-case2-4

ケース2:2往復目テキストエディタ画面

wordpressで文字の実態化を担当しているフィルターは、wptexturizeというです。とりあえず、実験としてfunctions.phpに登録

remove_filter( 'the_content', 'wptexturize' );

結果は無残にも&アンパサンドの増殖はとまらず。文字の実態化自体は、wp-include/js/tinymce/tinymce.min.jsという情報がありました。以下のブログを参考にしてみてください。

もうひとつの回避方法として、
<pre><code>等の特定のタグや登録したショートコード内では、コードの改変を行われないというルール。


※上記のアポストロフィ、ダッシュ、省略符号(…)、商標記号、乗算記号等の文書記号に作用することが判明。関係なかったようです。

最終結論:問題は入力の仕方!

これらの作業をやりああだこうだしながらようやく結論らしきものにたどりつきました。結局のところ、Syntax highlighter自体は<pre>コードを利用したコード拡張ですが、、Syntax Highlighter Evolvedをつかっていたため、[php][html]等のショートコードでこれを代用していたため、ビジュアルエディタでこのショートコードが展開されずコード改変対象外およびhtmlタグの認識において謝りがあったということです。この対応のための結論が以下の2つ

コード改変を防ぐ方法!

  • ショートコードを使わずに<pre lang=”php”>等で書き始めること。
  • htmlタグはアンパサンドでエスケープする

これで、ビジュアルエディタ側は、コード改変が不可な範囲であることの認識とエスケープされたhtmlコードであることを認識。よって改変はおこなわれず、無用な改行コードの挿入も文字実態化もおこなわず、何度ビジュアルエディタと往復してもコードレイアウトがくずれることはなくなります。

今回の例題のコードは、以下のようにテキスト画面から入力するようになります。

<pre class="brush: php; gutter: true; first-line: 1; html-script: true">
&lt;div&gt;line1:本表示は1行に1ステートメントです。&lt;/div&gt;
&lt;div&gt;line2:余計な改行が挿入されていない、改行が削除されていないことを確認!&lt;/div&gt;
&lt;?php 				//line3
	$temp	=1; 	//line4
	$temp2	=1;		//line5
	$temp3	=1;		//line6
// line7 ?&gt;
&lt;div&gt;line8:end&lt;/div&gt;
</pre>

コード改変に対応するプラグイン

Syntax HighLighterでコードを公開するユーザは必須です。上記のコード改変を防ぐ方法に紹介したコードに対応するプラグインがありました。Syntax Highlighter Evolvedにも対応! 「SyntaxHighLighter TinyMCE Button」というプラグインです。ぜひ使ってみてください。

コメント

  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

スポンサーリンク
ページ上部へ戻る