未分類

なぜそんな説明をするのか?

そろそろLuxeritasからの移行を考えているからです。公開した以上どこかでメンテナンスをやめるなら、引き継ぎ可能な状態にしようという意味合いです。

どうして移行したいのか?

改変パッチの配布が面倒だからです。配布物に含まれるコードはGPLなのにminifyしたソースしか含んでいなかったり、各ファイルのライセンスが明確ではありません。通常GPLならminifyする前のソースを要求し、そのソースは再配布も堂々とできるのですが、これだけしっかり配布している中それらソースをどこにも置いていません。サイトを読む限りGPLについても独自の見解をお持ちのようで、弁護士を頼んで云々とあり、正直あんまり関わりたくありません。

本来であればパッチ配布などという形態にしなくても、gitリポジトリごとどこかに置いてもらえば、こちらもフォークして修正して公開できるわけです。あとはプルリクエスト出したりと健全な活動で取り込まれれば私の作業はなくなるし、リジェクトされても他の人がフォークしたものに取り込むのは容易なわけで、いずれにしても私の作業はかなり楽になります。極めつけが先のminifyソースなのですが…これは実際の作業で実感してもらうべきですね。

未分類

事件

今日何気なく記事を編集して、「ああ、そういや過去記事で似たような画像作ったな…作った画像どこだっけ?」って過去記事を探していたところ、どこを探しても見つかりません。

この画像には alt 属性が指定されておらず、ファイル名は image-27-1024x188.png です

あれれ?それもそのはず消えているのです。そう言えばアップロードしたときも↓な感じでメッセージが出てました。

プレビューとかでは見えていたので、「警告かなぁ…まあいいや」と気にしていなかったのですが、実際にアップロードには失敗していた模様。そしてこのファイルこそがsvgだったのです。

なぜ拒否られてたのか?

アップロードできるファイル・タイプがWordPress側で決められているからです。

Uploading Files « WordPress Codex

これはメッセージに出ていたようにセキュリティ上の理由です。

どうすればいいのか?

メッセージから調べたところ、対応方法の記事が以下に見つかりました。

https://www.elegantthemes.com/blog/wordpress/how-to-fix-the-sorry-this-file-type-is-not-permitted-for-security-reasons-error-in-wordpress

大きく分けて、プラグインを使う方法とそうでない方法があるようです。遅くなりそうだからプラグインを使いたくなくて、

3. Use the Upload_Mimes Filter by Editing Your Theme’s functions.php File

の方法にしようと考えました。テーマのファイルをいじるようですが、テーマと言えばLuxeritas、誰かやってないかなぁとググって↓の記事を見つけました。

https://it-blue-collar-dairy.com/svg-upload/

ピッタリですね。読んで見ると、今までインストールはしたものの、面倒だったので使ってこなかった「子テーマ」を使うのがいいようです。

子テーマの適用

よく分からないけどポチっと変えてみたら、、、

『設定が共通化されてない!』

直後からカスタマイズした設定の全てがデフォルトに戻っています。親テーマに戻すと戻るのですが、子テーマに変えるとまたデフォルトに…。どうやら設定が共通化されてないようなのです。ここを分ける意味はあったんでしょうか…。どこかに相互にコピーする機能があるのかもしれませんが、まあいうてそんな変えてないので、ポチポチ再設定して復元しました。凝った設定をしてる方、お気をつけください

functions.phpの編集

どうやら子テーマとは、親テーマを直接いじることなく、テーマのphpファイルを書き換えるなどヘビーな操作をWebから行えるようにした、カスタマイズの申し子のようです。どおりでアップデートの頻度が少ないわけです。↓な感じでサクっと編集できます!

でも、これ書き間違えたら二度と直せないような…要るのかな?…この画面…

ちなみに修正は↓のみ。参考文書ではいろいろ他にも処理していましたが、本家のコードにないことはしたくなかったので…

function my_custom_mime_types( $mimes ) {
	$mimes['svg'] = 'image/svg+xml';
	$mimes['svgz'] = 'image/svg+xml';
	return $mimes;
}
add_filter( 'upload_mimes', 'my_custom_mime_types' );

無事アップロード出来たので問題なし、です。ちなみに↓が投稿した記事内のsvg画像のレスポンスヘッダ。

HTTP/1.1 200 OK
Date: Tue, 04 Feb 2020 22:21:33 GMT
Server: Apache
Last-Modified: Tue, 04 Feb 2020 22:16:33 GMT
ETag: "a3c0204-10b0b-59dc7647855c6"
Accept-Ranges: bytes
Content-Length: 68363
Vary: User-Agent
Connection: close
Content-Type: image/svg+xml

普通に返されてるので、少なくとも私のアップロード操作で、別のファイルタイプと勘違いしているような問題は起きてないように見えます。

未分類

顔文字に他意はありません?。単にインパクトを狙っただけの話です?。

?本日2020年2月2日、Luxeritas 3.7.8がリリースされました?。目玉はうるさいくらいに使ってるこの『emoji 』 です?。恐らく以前から文字自体は使えてた?と思いますが、これがブロックエディタに追加され、ポチポチするだけで入れられるようになった?ということだと思います?。

先日ご報告させて頂いた問題にも対策して頂き、追随する必要のあるパッチが減って喜んだ束の間、この「ブロックエディタ」の変更だけは個人的にインパクトが大きく驚愕した次第です?。シンタックスハイライターもブロックエディタの一種なので、ここに入っているのですが、このファイルだけなぜか元々minifyされていて、元のファイルがないため、beautify→手作業で編集→minifyしないといけないのです。minifyしてるとパッチを機械的に当てられなくなるだけでなく、シンボルがワケワカメな名前になったり?、文がコンマ並びの式になったり?、いろいろ 可読性が低下してしまいます?。まあそうそう編集されるファイルではないと思うので、そんな気にしてませんが、できればやりたくないというのが本音です?。

もう二度とこんなにemojiを使う機会はないと思いますが、 3.7.8リリースおめでとうございます?。


追伸

私が仕込んだバグが発見されたそうで、3.7.8.2がリリースされたそうです?
謹んでお詫び申し上げます ?

未分類

前回HTML内でJavaScriptを書いてみたらハイライトされなくて、おかしいな〜と調べてたら3件不具合を見つけた。

不具合

HTML内のJavaScriptなどをハイライトできない場合がある

現象

記事内にシンタックスハイライターを単独で置き、HTML内にJavaScriptを記述した上で言語をHTML/XHTMLにしておくと、JavaScriptがハイライトされない。

原因

HTMLのハイライトを行う(prism-)markup.jsとJavaScriptのハイライトを行う(prism-)javascript.jsの読み込み順序が逆であるため。依存されているjsが後に読み込まれる必要がある。

JavaScriptなのにJava用のハイライタまで読み込まれる

現象

読み込みがごくごく僅かに遅くなるだけだが、わざわざ言語別に必要ハイライタだけ読み込んでるからもったいない

原因

言語指定の先頭4文字がjavaかで判断しているため、javascriptまでjavaと勘違いされた

JavaScriptのハイライタが2回読み込まれる場合がある

現象

読み込みがごくごく僅かに遅くなるだけだが、わざわざ言語別に必要ハイライタだけ読み込んでるからもったいない

原因

JavaScript単体で言語指定された場合と、依存言語として他の言語指定から読み込まれる場合に、別の言語指定文字列が使われているため(highlight-javascriptとjavascript)、重複して読み込まれる

対策

パッチを作成した。

diff --git a/inc/load-inline.php b/inc/load-inline.php
index cc707c5..3374c70 100644
--- a/inc/load-inline.php
+++ b/inc/load-inline.php
@@ -51,10 +51,14 @@ function thk_highlighter_load( $loads, $list, $active ) {
 
 		// Javascript
 		foreach( $list as $key => $val ) {
-			if( strpos( $post->post_content, '<code class="language-' . str_replace( 'highlight_', '', $key ) ) !== false ) {
+			if( strpos( $post->post_content, '<code class="language-' . str_replace( 'highlight_', '', $key ) . '"' ) !== false ) {
 				$lang = str_replace( 'highlight_', '', $key );
 
-				if( !isset( $loads[1][$key] ) ) {
+				if( !isset( $loads[1][$lang] ) ) {
+					// 言語ごとの読み込み
+					$loads[0] .= thk_fgc( $jsdir . $lang . '.js' );
+					$loads[1][$lang] = true;
+
 					/*
 					 * 他言語の依存チェック
 					*/
@@ -114,10 +118,6 @@ function thk_highlighter_load( $loads, $list, $active ) {
 						$loads[0] .= thk_fgc( $jsdir . 'sql.js' );
 						$loads[1]['sql'] = true;
 					}
-
-					// 言語ごとの読み込み
-					$loads[0] .= thk_fgc( $jsdir . $lang . '.js' );
-					$loads[1][$key] = true;
 				}
 			}
 		}

保管場所は以下。


Luxeritas作者様に報告させて頂きました。次バージョンで対応して頂けるとのお話なので、個々にパッチを当てる必要はないと思います。


2020年2月2日にリリースされたLuxeritas3.7.8本体で、対応されたことを確認しました。なので以降本件のパッチリリースはありません。


2020年2月3日本パッチには、ほとんどの言語でハイライトできなくなるという重大な不具合が発見されました?。
同日にリリースされたLuxeritas3.7.8.2で作者様が対応してくれております。詳細は↓で。

未分類

背景

最近Dockerを使った記事を書くにあたり、シンタックスハイライターの対応言語が足りてないことに気付きました。シンタックスハイライターを実装しているのは、WordPressテーマのLuxeritasなのですが、このシンタックスハイライターに使われているprism.jsではもっと大量の言語に対応しています。そこで、今回必要になった、YAMLファイル(docker-compose.yml)、Dockerfile、 iniファイル(php.iniで欲しくなる)の3つの言語に簡単に対応してみました。

Luxeritasのコード解析

簡単とはいえ、説明書があるわけではないので、Luxeritasのコード解析をしないと、どこを修正していいか分かりません。調べてみたところ、大まかにいかの流れでシンタックスハイライターが動いています。

  1. シンタックスハイライターが扱える言語とその言語を表す文字列のリスト(wpfunc.php)を元にシンタックスハイライターの言語選択画面でリストアップする
  2. 記事のDB保存時にユーザーが選んだ言語を表す文字列を個々のコードブロックに紐づけて保存する
  3. 記事の表示時は、シンタックスハイライターを以下のように表示する
    1. コードブロックに紐付けられた言語を表す文字列と、先のリスト (wpfunc.php) を照合して、言語を確認(loadinline.php)
    2. その言語が複数の言語で構成されていればそれらを追加し、記事内で必要な言語のリストを作る(loadinline.php)
    3. 必要な言語のリストを元に、必要なprism.jsのファイルを特定し、最小限の組み合わせでJavaScriptファイルを合成(minify)してクライアントに返す
    4. クライアント側ではprism.jsの機能により、自動的に各言語はparseされてハイライトされていく

言語の追加

今回追加する言語は、複数の言語で構成される言語ではないので(例えばHTMLの中にJavaScriptが入るとか)、 シンタックスハイライターが扱える言語とその言語を表す文字列のリストに必要な言語を追加し、その言語に必要なprism.jsの部品を追加すれば完成です。

シンタックスハイライターが扱える言語の追加

wpfunc.php

diff --git a/inc/wpfunc.php b/inc/wpfunc.php
index fac76e8..7039e66 100644
--- a/inc/wpfunc.php
+++ b/inc/wpfunc.php
@@ -1970,6 +1970,9 @@ function thk_syntax_highlighter_list() {
                'highlight_sql'         => 'SQL',
                'highlight_vbnet'       => 'VB.NET',
                'highlight_vim'         => 'Vim',
+               'highlight_yaml'        => 'YAML',
+               'highlight_docker'      => 'Docker',
+               'highlight_ini'         => 'Ini',
        );
 }
 endif;

必要なprism.jsの部品を追加

今回は現在の最新リリースである、prism.js v1.16.0を取得し、その中からcomponents/prism-言語名.min.jsとなっているファイルを抽出し、必要な言語をLuxeritasパッケージ内にjs/prism/言語名.jsというファイルで配置しました。

パッチ

以下にまとめてあります。

未分類

ルクセリタスのコード表示部分をいじり、パス表示を追加してみました。

diff --git a/js/luxe-blocks.js b/js/luxe-blocks.js
index 47d3ce8..a6e77ef 100644
--- a/js/luxe-blocks.js
+++ b/js/luxe-blocks.js
@@ -4411,6 +4411,10 @@ window.addEventListener("DOMContentLoaded", function() {
         language: {
           type: "string",
           default: ""
+        },
+        filename: {
+          type: "string",
+          default: ""
         }
       },
       supports: {
@@ -4464,45 +4468,66 @@ window.addEventListener("DOMContentLoaded", function() {
             value: ""
           }];
         return Object.keys(luxeHighlighterList).forEach(function(e) {
-          c.push({
-            label: this[e],
-            value: e
-          })
-        }, luxeHighlighterList), l.push(s(d.SelectControl, {
-          label: u("Code Language", "luxeritas"),
-          value: a,
-          options: c,
-          onChange: function(e) {
-            return n({
-              language: e
-            })
-          }
-        })), t = s("p", null, u("* The theme can be changed from the CSS tab of Luxeritas menu.", "luxeritas")), [s(p.InspectorControls, {
-          key: "syntaxHighlighterInspectorControls"
-        }, s(d.PanelBody, {
-          title: u("Settings")
-        }, l, t)), s("div", {
-          className: r + " wp-block-code"
-        }, s(p.PlainText, {
-          value: i,
-          onChange: function(e) {
-            return n({
-              content: e
+            c.push({
+              label: this[e],
+              value: e
             })
-          },
-          placeholder: u("To the right, choose a code language from the block settings.", "luxeritas"),
-          "aria-label": u("Syntax Highlighter", "luxeritas")
-        }))]
+          }, luxeHighlighterList), l.push(s(d.SelectControl, {
+            label: u("Code Language", "luxeritas"),
+            value: a,
+            options: c,
+            onChange: function(e) {
+              return n({
+                language: e,
+                filename: o.filename
+              })
+            }
+          })),
+          l.push(s(d.TextControl, {
+            label: u("File Name", "luxeritas"),
+            value: o.filename,
+            onChange: function(e) {
+              return n({
+                language: a,
+                filename: e
+              })
+            }
+          })), t = s("p", null, u("* The theme can be changed from the CSS tab of Luxeritas menu.", "luxeritas")), [s(p.InspectorControls, {
+            key: "syntaxHighlighterInspectorControls"
+          }, s(d.PanelBody, {
+            title: u("Settings")
+          }, l, t)), s("div", {
+            className: r + " wp-block-code"
+          }, s(p.PlainText, {
+            value: i,
+            onChange: function(e) {
+              return n({
+                content: e
+              })
+            },
+            placeholder: u("To the right, choose a code language from the block settings.", "luxeritas"),
+            "aria-label": u("Syntax Highlighter", "luxeritas")
+          }))]
       },
       save: function(e) {
         var t = e.attributes,
           o = t.content,
           n = t.language.replace("highlight_", "");
-        return "" != n ? s("pre", {
-          className: "line-numbers language-" + n
-        }, s("code", {
-          className: "language-" + n
-        }, o)) : s("pre", null, s("code", null, o))
+        var obj;
+        if ("" != n) {
+          var pre = {
+            className: "line-numbers language-" + n,
+          };
+          if (t.filename) {
+            pre["data-label"] = t.filename;
+          }
+          obj = s("pre", pre, s("code", {
+            className: "language-" + n
+          }, o));
+        } else {
+          obj = s("pre", null, s("code", null, o));
+        }
+        return obj;
       }
     })
   }(),
diff --git a/languages/admin/luxeritas-ja-luxe-blocks.json b/languages/admin/luxeritas-ja-luxe-blocks.json
index 4d04781..8381a3c 100644
--- a/languages/admin/luxeritas-ja-luxe-blocks.json
+++ b/languages/admin/luxeritas-ja-luxe-blocks.json
@@ -200,6 +200,9 @@
                        "Code Language": [
                                "言語"
                        ],
+                       "File Name" : [
+                               "ファイル名"
+                       ],
                        "* The theme can be changed from the CSS tab of Luxeritas menu.": [
                                "※ テーマ(見た目)は Luxeritas メニューの CSS タブから変更できます。"
                        ],

luxe-blocks.jsはminifyされてたので、以下で整形してから編集してdiffを取っています。

$ npx js-beautify -s 2 luxe-blocks.js >luxe-blocks.js.new
$ mv luxe-blocks.js.new luxe-blocks.js

編集後は以下でminifyして使っています。

$ npx -p uglify-js uglifyjs luxe-blocks.js -c --output luxe-blocks.js.new
$ mv luxe-blocks.js.new luxe-blocks.js
$ 手作業でライセンスの貼り付け

上記作業はパッチにして以下にまとめてあります。