⌨️

LaTeX + TikZでキーボードを描画する

に公開

はじめに

\LaTeXでキーボードを描画するという場合、筆者はにせねこさんのLaTeX (TikZ)でキーボード配列表を作成を利用している。これはとてもよくできたマクロとなっているが、一部のキーを強調表示したくなったり、キーボードの一部だけを表示したくなった場合に不便となっていた。そこでにせねこさんのマクロを少し改造することで、下記のように色を付けたりできるようにした。


AMキーだけ色を変更

さらに、Shiftキーなどを含む形で一部のキーだけを表示したりもできるようにした。


キーボードの一部だけを描画

今回の実装は下記のGitHubリポジトリーで公開している。

\keyassignマクロの改造

元々の実装は\keyassignマクロの中で次の2つのマクロを利用するようになっている

  1. 普通のキーを描画するためのpics/vhsplit/.styleを利用する\my@keypathマクロ
  2. Shiftキーなどのキーを描画するpics/specialkey/.styleを利用する\my@specialkeyマクロ

そして\keyassignのユーザーは(1)の\my@keypathの引数を下記のようにCSV形式で入力していく形となる。

\keyassign{{}{}{\char"07E}{\char"060},{}{}!1,{}{}@2,{}{}\#3,{}{}\$4,{}{}\%5,{}{}{\char"05E}6,{}{}\&7,{}{}*8,{}{}(9,{}{})0,{}{}\_-,{}{}+=}%
{{}{}{}Q,{}{}{}W,{}{}{}E,{}{}{}R,{}{}{}T,{}{}{}Y,{}{}{}U,{}{}{}I,{}{}{}O,{}{}{}P,{}{}\{[,{}{}\}],{}{}|{\char"05C}}%
{{}{}{}A,{}{}{}S,{}{}{}D,{}{}{}F,{}{}{}G,{}{}{}H,{}{}{}J,{}{}{}K,{}{}{}L,{}{}{:}{;},{}{}{\char"022}{\char"027}}%
{{}{}{}Z,{}{}{}X,{}{}{}C,{}{}{}V,{}{}{}B,{}{}{}N,{}{}{}M,{}{}{<}{\char"02C},{}{}{>}.,{}{}?/}

{}{}{}Qのような表記はそれぞれ{north-west}{south-west}{north-east}{south-east}となっており、たとえば{ou}{っ}{\char"022}{\char"027}[1]では下記のようなキーが描画される。


{ou}{っ}{\char"022}{\char"027}のキー

元々の\keyassignの引数はこのようにvhsplitスタイルを利用する\my@keypathマクロを前提としていたため、Shiftキー周辺の一部のキーだけを表示するというのが難しい状況になっている。そこで次のような改造でユーザーからShiftキーを入力できるようにする。

pics/specialkey/.styleの改造

まずpics/vhsplit/.styleの引数は4つだがpics/specialkey/.styleは2つとなっており、この2つには互換性がない。よってまずは次のようにpics/specialkey/.styleの(使わない)引数を2つ増やしてまずはこの2つに互換性を与える。

\tikzset{
-  pics/specialkey/.style n args = {2}{
+  pics/specialkey/.style n args = {4}{
    code = {
      \draw[rounded corners=1mm,fill=gray!20] (-3mm,-9.5mm) rectangle (#2-1mm,2.5mm);  
      \node[inner sep=1mm,anchor=south west,text width=#2,align=center] (A) at (-3mm,-9.5mm) {#1};  
    }
  }
}

\my@keypathで普通のキーも特殊キーも利用できるようにする

もともと\my@keypathは8つの引数だったが、xparseパッケージの省略可能引数を駆使して次のように改造した。

  1. 新たに省略可能な第3引数を追加してここで[vhsplit][specialkey]でスタイルを指定できるようにした(省略した場合はvhsplitになる)
  2. 最後の2つの引数が元々は{vertical-index}{left-offset}の順序であったが、left-offsetを省略可能引数にしつつこの2つの順序を入れ替えた
-%{name}{index}{north-west}{south-west}{north-east}{south-east}{vertical-index}{left-offset}
-\def\my@keypath#1#2#3#4#5#6#7#8{%
-  \path pic (#1) at ([xshift=#8\my@keylength]#2\my@keylength,#7\my@keylength) {vhsplit={#3}{#4}{#5}{#6}};
-  \typeout{#1/#2/}
-}
+\def\my@xshift{0}
+%{name}{index}[style]{north-west}{south-west}{north-east}{south-east}[left-offset]{vertical-index}
+\NewDocumentCommand\my@keypath{m m O{vhsplit} m m m m O{\my@xshift} m}{%
+  \typeout{#1/#2/#3/#4/#5/#6/#7/#8/#9}
+  \path pic (#1) at ([xshift=#8]#2\my@keylength,#9\my@keylength) {#3={#4}{#5}{#6}{#7}};
+}

これによって元々は\keyassignの引数が{ou}{っ}{\char"022}{\char"027}のような4つ組であったものが、2つの省略可能引数が拡張されて次のように前後にスタイルと左右オフセットを入力できるようになった。

\keyassign{}%
{[specialkey]{Ctrl}{15mm}{}{}[0],{}{}{}A,{}{}{}O,{}{}{}E[100]}%
{}%
{}


複数スタイルのキーやオフセットを\keyassignで表示

元々のpics/specialkey/.styleの引数がpics/vhsplit/.styleと順序含めて互換性がないため、やや分かりにくい状況となっている。とりあえずこのようにすることで\keyassignを使って複数種類のキーを入力することができるようになった。
そして、使いやすくするためにCtrlキーのようによく用いられる特殊キーについては次のようにコマンド化しておくことにする。

\def\BSKey{[specialkey]{Back\\Space}{1.27\my@keylength}{}{}}
\def\TabKey{[specialkey]{Tab}{1.27\my@keylength}{}{}[0]}
\def\CtrlKey{[specialkey]{Ctrl}{1.57\my@keylength}{}{}[0]}
\def\EnterKey{[specialkey]{Enter}{1.47\my@keylength}{}{}}
\def\LeftShiftKey{[specialkey]{Shift}{2.07\my@keylength}{}{}[0]}
\def\RightShiftKey{[specialkey]{Shift}{1.97\my@keylength}{}{}}

これによって次のように特殊キーを表示することができる。

\keyassign{\BSKey}%
{\TabKey}%
{\CtrlKey,\EnterKey}%
{\LeftShiftKey,\RightShiftKey}


簡単化したマクロで特殊キーを\keyassignで表示

\@forの中で\keyassignの引数を\edefで展開

上述のように\keyassignの中で\CtrlKeyのようなマクロを利用した場合に備えて、元々の実装に加えてイテレーターを\edefで展開するコードを次のように追加した。

\@for\lp@elem:=#1\do{%
+ \edef\lp@temp{\lp@elem}%
  \expandafter\def\expandafter\my@cnum\expandafter{\the\my@keycount} %
  \expandafter\def\expandafter\my@keyname\expandafter{\expandafter{\expandafter a\my@cnum}} %
  \expandafter\def\expandafter\my@keyindex\expandafter{\expandafter{\my@cnum}} %
  \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\my@keypath%
- \expandafter\expandafter\expandafter\my@keyname\expandafter\my@keyindex\lp@elem{0}
+ \expandafter\expandafter\expandafter\my@keyname\expandafter\my@keyindex\lp@temp{0} %
  \advance\my@keycount by 1 %
}

別のスタイルemphkeyを追加

また、たとえば他にも次のように別のスタイルemphkeyを定義することによって、特定のキーに色をつけることもできる。

\tikzset{
  pics/emphkey/.style n args = {4}{
    code = {
      \draw[rounded corners=1mm,fill=yellow!10] (-3mm,-9.5mm) rectangle (9mm,2.5mm);
      \node[anchor=west] (A) at (-3mm,-0.5mm) {#1};
      \node[anchor=west] (B) at (-3mm,-6.5mm) {#2};
      \node[anchor=east] (C) at (9mm,-0.5mm) {#3};
      \node[anchor=east] (D) at (9mm,-6.5mm) {#4};
    }
  }
}
\keyassign{}%
{[emphkey]{}{}{}A,{}{}{}O,{}{}{}E}%
{}%
{}


Aキーにemphkeyを指定して色を変えて表示

まとめ

やや雑なところもあるが、このように少しの改造で\keyassignマクロの表現力をさらに高めることができたと思う。一方で\TeX\defマクロで定義されたマクロと、xparseパッケージの\NewDocumentCommandマクロで定義されたマクロが混在してしまった。この部分はいずれなんとかしたいと考えている。

脚注
  1. \char"022"(ダブルクォーテーション)、\char"027'(シングルクォーテーション)をそれぞれ意味する。 ↩︎

Discussion