VS Code用WordPress Post拡張機能を修正してみる その7

VS Code用WordPress Post拡張機能を修正してみる その7WordPress
スポンサーリンク

前回では、WordPressの記事をVS Codeで作成できる拡張機能であるWordPress Post拡張機能さらに更新しました。

これでもう修正することもないだろうと思ったのですが、実際に使って見るといろいろ不満が出てくるものです。

ソースコードがあるので飽きずに修正してみます。

スポンサーリンク

VSIXファイルのダウンロード

最初に今回の修正後のファイルの案内をしておきます。

今回の修正でバージョンを「0.0.6-f」となっています。

これを利用してみたい方は下記のURLからVSIXファイルをダウンロードして、VS Codeにインストールしてみてください。

Release v0.0.6-f · scratchpadjp/vscode-wordpress-post
This is unofficial version of WordPress Post extension for VS Code. The following features are added to the original version of WordPress Post 0.0.5. customize...
スポンサーリンク

新たに気になる点

WordPress Post拡張機能を利用して記事を作成していると、画像の扱い関係で2点気になる点が出てきました。

画像リンクが常に有効になってしまう

WordPress Post拡張機能に元からある機能の1つに「linkable image」というのがあります。

この機能を有効にすると、画像(imgタグ)に対して、リンク(aタグ)を付加してくれます。このとき、元々のWordPRess Post拡張機能では、imgタグとaタグには同じ画像がされるようになっていました。

以前、WordPress Post拡張機能を修正して、Markdownで埋め込んだ画像を縮小する機能をつけたときには、この機能を利用して

  • imgタグには縮小済みの画像データを指定
  • aタグには縮小前の画像データを指定

となるようにしました。

これにより画像をクリック(選択)すると、縮小前の画像が表示されるようになり、画像を確認したい人は大きな画像をみることができます。

これはこれで便利なのですが、Markdownで貼り付けた画像が小さいときにはわざわざリンクにして欲しくないところです。

というのも、画像が小さいときには縮小が行われないため、imgタグの画像とaタグの画像がまったく同じになるからです。画像を選択しても同じ画像が表示されるだけでリンクの意味がありません。

Markdownで埋め込んだ画像が縮小されない場合は、「linkable image」を有効にしてもリンクを生成して欲しくないところです。

個々の画像サイズを指定できない

以前、WordPress Post拡張機能を修正して、Markdownで埋め込んだ画像の最大サイズを指定できる機能をつけました。

最大サイズは拡張機能の設定で指定することになるので、全画像に共有して適用されます。

この修正では、拡張機能の設定で画像の最大サイズを指定できるようにしました。この機能を使うと、Markdownで埋め込んだ画像がその最大サイズより大きければ、画像を最大サイズまで縮小してHTMLに埋め込みます。

このとき「linkable image」の設定をオンにしておくと、画像をクリック(選択)したときに縮小前のオリジナルの画像が表示されるようになります。

これはこれで便利なのですが、実際に記事を作成してみると特定の画像だけ最大サイズを変えたいという状況がありました。

たとえば、縦長の画像を利用する際は、最大幅を少し小さくしたくなります。

デフォルトの最大サイズは拡張機能の設定で行うとして、個々の画像に必要に応じて最大サイズを指定できると便利になりそうです。

拡張機能の設定がごちゃごちゃしてわかりにくい

これまでの修正で拡張機能の設定項目がかなり増えました。

特にカスタムコンテナ機能を追加する際に設定項目が増えてしまい、この問題が顕著になりました。

ここは見やすく・使いやすくするために

  • 拡張機能の設定項目を階層化(カテゴライズ)する
  • 設定項目の順序を意味があるようにする (現状はアルファベット順になってしまっている)

としたいところです。

画像リンク(linkable image)の修正

やりたいことは、シンプルに「imgタグとaタグに指定される画像が異なるときのみlinkable imageにする」と言うことです。

ただオリジナルのWordPress Post拡張機能と同じ動作をできるようにしたいので

  • 「imgタグとaタグの画像が異なるときのみLinkable imageにする」という設定を新設する(デフォルトは「オフ」)

という方針で修正を行うことにしました。

ただ問題なのがこの「画像が異なる」と言うことをどう判定するかです。

当初はURLが異なったら別画像と判定しようと思ったのですが、外部画像のURLを利用している場合は、現在の実装ではimgタグとaタグが同じURLになってしまうことがわかりました。

そこで単純ではありますが、画像のサイズが異なったら、画像が異なると判定することにしました。

ソースコードの修正

この対応を行ったコミットは次になります。

Add "useLinkableImageOnlyIfSizeIsDifferent" option · scratchpadjp/vscode-wordpress-post@cba78dc
Contribute to scratchpadjp/vscode-wordpress-post development by creating an account on GitHub.

package.json

package.jsonでは、拡張機能の設定項目の追加と、動作に必要なパッケージ(ライブラリ)の追加のために変更します。

今回は設定項目の追加のみが必要で、今回は「contributes」→「configuration」→「properties」に下記の項目を追加しました。

        "wordpress-post.useLinkableImageOnlyIfSizeIsDifferent": {
          "type": "boolean",
          "default": false,
          "description": "Enable link only if linked image size is different from image size in img tag. To use this feature, please enable \"Use Linkable Image\" also."
        },

「wordpress-post.useLinkableImageOnlyIfSizeIsDifferent」が「true」であると、likable imageの処理を行うときにimgタグとaタグの画像の違いをチェックするようにします。
デフォルトはfalseになります。

post.ts

post.tsはこの拡張機能のメイン動作を記述しているファイルです。

この修正前はlinkable imageの処理は次のように、拡張機能の設定のuseLinkableImageがtrueであればaタグを追加するようになっていました。

    if ( context.useLinkableImage() ) {
      context.debug(`[07I] use a tag`);
      ch(imgs[i]).replaceWith(`<a href="${linkUri}">${newImgTag}</a>`);
    } else {
      context.debug(`[07I] not use a tag`);
      ch(imgs[i]).replaceWith(`${newImgTag}`);
    }

今回の修正ではこのif文の条件を変えています。

    if ( context.enableLinkToImage([displayImgWidth, displayImgHeight], [orgImgWidth, orgImgHeight] ) ) {
      context.debug(`[07I] use a tag`);
      ch(imgs[i]).replaceWith(`<a href="${linkUri}">${newImgTag}</a>`);
    } else {
      context.debug(`[07I] not use a tag`);
      ch(imgs[i]).replaceWith(`${newImgTag}`);
    }

条件分岐で使用しているenableLinkToImage()についてはcontext.tsの修正内容で説明しますが、この関数にimgタグの画像のサイズ(displayImgWidthとdisplayImgHeight)、aタグの画像のサイズ(orgImgWidthとorgImgHeight)を渡しているのがポイントです。

context.ts

この拡張機能では設定項目関係の情報を取得する関数がcontext.tsに記述されています。

今回はこのファイルに次のコードを追加しました。

  useLinkableImageOnlyIfSizeIsDifferent(): boolean {
    return this.getConf("useLinkableImageOnlyIfSizeIsDifferent");
  }

  enableLinkToImage([imgWidth, imgHeight] : [number, number], [linkWidth, linkHeight] : [number, number]): boolean {
    if ( !this.useLinkableImage() ) {
      return false;
    }
    if ( !this.useLinkableImageOnlyIfSizeIsDifferent() ) {
      return true;
    }

    return (imgWidth !== linkWidth) || (imgHeight !== linkHeight);  // return true if size is different
  }

enableLinkToImage()は次の条件のときにtrueを返すようになっています。

  • 設定項目のuseLinkableImageが有効(true)かつ、useLinkableImageOnlyIfSizeIsDifferentが無効(false)の場合
    (画像のサイズにかかわらず強制的にlinkable imageを有効にする)
  • 設定項目のuseLinkableImageが有効(true)かつ、useLinkableImageOnlyIfSizeIsDifferentが有効(true)かつ、引数に渡された2つの画像サイズが異なる場合

実行

ここまで紹介した修正を行った上で、拡張機能の実行(デバッグ)を行うと、「設定」→「拡張機能」→「WordPress Post Configuration」に「Use Linkable Image Only If Size Is Different」が現われます。

追加された設定項目

このチェックボックスを有効にすると、画像をクリック(選択)することで拡大画像(元々の画像)が表示される場合のみリンクが有効になります。

画像サイズを個別に設定できるようにする修正

次に個々の画像サイズの指定ができない問題を修正します。

このWordPress拡張機能では、MarkdownをHTMLに変換するためMarkdown-itというパッケージを使っています。いろいろ調べてみると、Markdownで画像サイズを指定できるようにするプラグインがありました。

markdown-it-imsize
Markdown-it plugin to specify image size. Latest version: 2.0.1, last published: 7 years ago. Start using markdown-it-imsize in your project by running `npm i m...

今回はこのプラグインを活用し、次のような方針で対応することにしました。

  • markdown-it-imsizeを導入して、個々の画像に対してサイズを指定できるようにする
  • 画像にサイズが指定されている場合は、表示時の最大サイズと解釈し、設定項目の最大サイズを上書きする
  • 画像の幅あるいは高さに「0」が指定されている場合は、表示サイズとしては制限無しとする

幅・高さが「0」のときの扱いは、画像の最大サイズを拡張機能の設定で指定できるようにしたときと同じになります。

ソースコードの修正

この対応を行ったコミットは次になります。

Support image max size override · scratchpadjp/vscode-wordpress-post@28b9093
Contribute to scratchpadjp/vscode-wordpress-post development by creating an account on GitHub.

package.json

package.jsonでは、拡張機能の設定項目の追加と、動作に必要なパッケージ(ライブラリ)の追加のために変更します。

今回は、とくに設定項目は追加せず、動作に必要なパッケージの追加のみを行いました。

利用するパッケージの情報はpackage.jsonの「dependencies」に次のように追加します。

    "markdown-it-imsize": "^2.0.1"

なお、package.jsonの「dependencies」を変更した場合には、「npm install」を実行する必要があるようです。

「npm install」を実行すると、package-lock.jsonが更新されるので、このファイルもコミットしておきます。

post.ts

post.tsはこの拡張機能のメイン動作を記述しているファイルです。

まず、markdown-itを初期化している部分に

    md.use(require('markdown-it-imsize'));

を追加して、markdown-it-imsizeを利用できるようにします。

これでmarkdown-it-imsizeが使えるようになり、たとえば画像のサイズを幅100・高さ200とするのであれば次のようにMarkdownで記載します。

![画像の説明](画像のURL =100x200)  

これをHTMLに変換すると

<p><img src="画像のURL" alt="画像の説明" width="100" height="200"></p>

となります。

そこで、拡張機能の設定項目における画像最大サイズを取得していた部分

    const [maxImgWidth, maxImgHeight] = context.getImageMaxSize();

    let   [maxImgWidth, maxImgHeight] = context.getImageMaxSize();
    const [givenWidth, givenHeight ] = [ Number(ch(imgs[i]).attr("width")), Number(ch(imgs[i]).attr("height")) ];
    if ( !Number.isNaN(givenWidth) ) {
      maxImgWidth = givenWidth;
    }
    if ( !Number.isNaN(givenHeight) ) {
      maxImgHeight = givenHeight;
    }

として、画像の最大サイズ(maxImageWidthとmaxImgHeight)をHTMLに埋め込まれたサイズ(givenWidthとgivenHeight = markdown-it-imsizeの形式で指定されたサイズ)で上書きします。

なお、markdown-it-imsizeの形式で画像サイズを指定していない場合は、givenWidth・givenHeightが非数(NaN)になります。この場合はmaxImageWidthとmaxImageHeightがそのまま使われることになります。

あとは、このように設定された最大画像サイズを使って、表示する画像サイズ(=HTMLのwidth属性とheight属性)を決定します。

なお、以前の修正でHTMLのimgタグにwidth・height属性をつけるかどうかを拡張機能の設定で選択可能にしていました。markdown-it-imsizeの形式で画像のサイズを指定しているとimgタグにwidth・heightが付いてしまうのでこの設定とバッティングしてしまいます。

そこでimgタグにwidth・heightをつけない設定になっている場合は、imgタグからwidth・heightを削除する処理も追加しました。

        if ( context.imageAddSizeAttributes() ) {
          ch(imgs[i]).attr("width", orgImgWidth.toString());
          ch(imgs[i]).attr("height", orgImgHeight.toString());
        } else {
          ch(imgs[i]).removeAttr("width");
          ch(imgs[i]).removeAttr("height");
        }

このelseの部分が今回追加した処理になります。

実行

ここまで紹介した修正を行うと、個々の画像に対して画像サイズの指定ができるようになります。

たとえば、拡張機能の設定で画像の最大サイズを横640・縦0(無制限)にしていたとしても、次のようなMarkdownを記述することでこの画像だけを幅480にできます。

![画像の説明](img/test.png =480x0)

この例では縦を0にすることで縦方向の最大サイズは無制限としています。

従って、単純に横幅が480になるように縮小されます。

記事に縦長の画像を埋め込む場合は、幅を他の画像よりも小さくした方が見やすいと思っているので、このように設定できると便利です。

拡張機能の設定項目の整理

これまでWordPress Post拡張機能を修正してきてかなり設定項目が増えてきました。

しかも設定項目の並び順がアルファベット順のため、使いにくくなってきました。

ごちゃごちゃした拡張機能の設定

たまたま重要な設定項目(APIのURIや認証のための設定)が「a」で始まっているため、先頭の方にきていてそれっぽく見えますが、実は単なるアルファベット順です。

さすがにこれは不便なので

  • 設定項目をグループ化(階層化)する
  • 設定項目の順序を意味があるものにする
    • 重要な設定項目を前にする
    • 似ている設定項目は続ける(近くには位置する)

あたりはやっておきたいところです。

修正の方針

拡張機能の設定項目はpackage.jsonというファイルに記載します。

このファイルの仕様については、英語になりますが下記のページに記載されています。

Contribution Points
To extend Visual Studio Code, your extension (plug-in) declares which of the various Contribution Points it is using in its package.json Extension Manifest file...

これを見ると、まず設定項目のグループ化については、

This section can either be a single object, representing a single category of settings, or an array of objects, representing multiple categories of settings. If there are multiple categories of settings, the Settings editor will show a submenu in the table of contents for that extension, and the title keys will be used for the submenu entry names.

と書かれており、package.jsonでconfigurationをオブジェクト配列にすればカテゴリ化できることがわかります。

また、表示の順序については

order
Both categories and the settings within those categories can take an integer order type property, which gives a reference to how they should be sorted relative to other categories and/or settings.

と書かれており、各設定項目にorderという数値を入れることで、表示される際の順序を制御できることがわかります。

今回はこれらの仕様を利用して設定項目を整理していくことをにしました。

ソースコードの修正

この対応は何度かに分けて行ったのですが、最終的な修正は下記のコミットになります。

Categorize configuration options · scratchpadjp/vscode-wordpress-post@9c0de36
Contribute to scratchpadjp/vscode-wordpress-post development by creating an account on GitHub.

package.json

拡張機能の設定項目についてはpackage.jsonに記載するので、変更するのはこのファイルのみです。

設定項目のグループ化

設定項目をグループ化するためには、「contributes」→「configuration」の値をオブジェクトの配列とします。

configurationは、通常は

    "configuration": {
      "title": "WordPress Post",
      "properties": {
        "wordpress-post.siteUrl": {
          "type": "string",
          "default": "https://yoursite",
          "description": "URL of WordPress, used create relative url"
        },
        "wordpress-post.apiUrl": {
          "type": "string",
          "default": "https://yoursite/wp-json/wp/v2",
          "description": "URL of WordPress REST API"
        },
        "wordpress-post.authUser": {
          ...

のようにtitleとpropertiesを並べることになります。このpropertiesが拡張機能の設定項目になります。

これを

    "configuration": [
      {
        "title": "General",
        "order": 10,
        "properties" : {
          "wordpress-post.siteUrl": {
            "type": "string",
            "default": "https://yoursite",
            "description": "URL of WordPress, used create relative url"
          },
          "wordpress-post.apiUrl": {
            ...
      },
      {
        "title": "Additional Link",
        "order": 20,
        "properties": {
          "wordpress-post.useLinkableImage": {
            "type": "boolean",
            "default": false,
            "description": "Add a tag to img tag"
          },
          "wordpress-post.useLinkableImageOnlyIfSizeIsDifferent": {
            ...
      }
    ]

にように、titleとpropertiesを「[]」で囲って複数並べるようにします。

このようにすることで設定項目をグループ化でき、titleがそのグループ名となります。

今回は

  • General
    全体的な設定項目のグループ
  • Additional Link
    リンクを追加する系の設定項目のグループ
  • Featured Image
    アイキャッチ画像関係のグループ
  • Image (img tag)
    imgタグで埋め込む画像関係のグループ
  • Generated HTML
    Markdownから生成されるHTMLに関係するグループ
  • Custom Class
    カスタムコンテナなどの追加機能のグループ

でグループ化してみました。

なお、各グループに「order」を追加すると、orderの数値が少ない順序にグループが表示されます。

数値は連番でなくても良いので、将来的に途中に新しいグループを挿入しやすいように、10の倍数としておきました。

orderを連番にしていると、途中にグループを挿入したときに、それ以降のorderをすべて修正する必要が出てきます。

設定項目の表示順序

拡張機能の設定項目は「contributes」→「configuration」→「properties」以下に記載します。

このとき次のように「order」という項目を追加することで表示順序を制御できます。

        "properties" : {
          "wordpress-post.siteUrl": {
            "order": 10,
            "type": "string",
            "default": "https://yoursite",
            "description": "URL of WordPress, used create relative url"
          },
          "wordpress-post.apiUrl": {
            "order": 20,
            "type": "string",
            "default": "https://yoursite/wp-json/wp/v2",
            "description": "URL of WordPress REST API"
          },
          "wordpress-post.authUser": {
            "order": 30,
            "type": "string",
            "default": "user",
            "description": "User of WordPress REST API"
          },
          ...

数値は連番でなくても良いので、将来的に途中に新しい設定項目を挿入しやすいように、10の倍数としておきました。

orderを連番にしていると、途中に設定項目を挿入したときに、それ以降のorderをすべて修正する必要が出てきます。

なお、設定項目をグループ化している場合は、orderはグループ内での表示順序になります。

実行

ここまで紹介した修正を行った上で、拡張機能の実行(デバッグ)を行うと、「設定」→「拡張機能」→「WordPress Post」以下にカテゴリが表示されるようになります。

カテゴリ化された設定項目

設定項目もこのようにカテゴリに合わせ配置され、見やすくなります。

カテゴリ化された設定項目

自分でも設定項目が見にくくなっていたため、これでだいぶ使い勝手が上がったと思います。

まとめ

今回はWordPress Post拡張機能をさらに修正して、画像の扱いや拡張機能の設定項目を変更してみました。

前回の修正で実用性十分と思ったのですが、実際に使ってみるといろいろ不便なところが出てくるものです。

しかし、自力で修正できるところが、オープンソースのよいところと思います。

コメント