にせねこメモ

はてなダイアリーがUTF-8じゃないので移ってきました。

LaTeX (TikZ)でキーボード配列表を作成

XeLaTeXでTikZを使ってキーボード配列表を作っていた。101キーボード向け。
多言語用のキーボード配列を作るときに便利…なはず。とても泥臭いので誰か改良してください。

ちなみにXeTeXを使ったのはモンゴル文字への対応がLuaLaTeXは良くないためで、試してないがfontspecが使えればLuaLaTeXなどでも普通に使えるかもしれない。

ソース

\documentclass{standalone}
\usepackage{fontspec}
\usepackage{lmodern}
\setmainfont{Times New Roman}

\usepackage{readarray}

\usepackage{calc}
\usepackage{xparse}
\usepackage{listings}
\usepackage{tikz}
\usetikzlibrary{positioning,shapes,fit}

\tikzstyle{abstract}=[rectangle, draw=black, rounded corners, fill=white,text centered, text=black, text width=8mm]
\tikzstyle{gkey}=[rectangle, draw=black, rounded corners, fill=gray!20,text centered, text=black, text width=8mm]

\newcommand{\mykey}[2]{%
\begin{tikzpicture} \node (Item) [abstract, rectangle split, rectangle split, rectangle split parts=2]%
{#1 \nodepart{second}#2};%
\end{tikzpicture}}


\tikzset{
    pics/vhsplit/.style n args = {4}{
        code = {
        \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};
        \draw[rounded corners=1mm] (-3mm,-9.5mm) rectangle (9mm,2.5mm); 
        }
    }
}
\tikzset{
    pics/specialkey/.style n args = {2}{
        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};  
        }
    }
}


\makeatletter

\newlength{\my@keylength}
\setlength{\my@keylength}{13mm}

% {name}{label}{xpos}{ypos}{width}
\def\my@specialkey#1#2#3#4#5{%
  \path pic (#1) at (#3\my@keylength,#4\my@keylength) {specialkey={#2}{#5\my@keylength}};
}
% {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/}
}
% \keyassign{1st}{2nd}{3rd}{4th line}
\def\keyassign#1#2#3#4{%
  \begin{tikzpicture}%
    \newcount\my@keycount %
    % 1st line
    \my@keycount=0
    \@for\lp@elem:=#1\do{%
      \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}{0} %
      \advance\my@keycount by 1 %
    } %
    \my@specialkey{BS}{Back\\Space}{13}{0}{1.27}
    % 2nd line
    \my@specialkey{Tab}{Tab}{0}{-1}{1.27}
    \my@keycount=0
    \@for\lp@elem:=#2\do{%
      \expandafter\def\expandafter\my@cnum\expandafter{\the\my@keycount} %
      \expandafter\def\expandafter\my@keyname\expandafter{\expandafter{\expandafter b\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{-1}{1.5} %
      \advance\my@keycount by 1 %
    } %
    % 3rd line
    \my@specialkey{CapsLock}{Caps Lock}{0}{-2}{1.57}
    \my@keycount=0
    \@for\lp@elem:=#3\do{%
      \expandafter\def\expandafter\my@cnum\expandafter{\the\my@keycount} %
      \expandafter\def\expandafter\my@keyname\expandafter{\expandafter{\expandafter c\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{-2}{1.8} %
      \advance\my@keycount by 1 %
    } %
    \my@specialkey{Enter}{Enter}{12.80}{-2}{1.47}
    % 4th line
    \my@specialkey{Shift}{Shift}{0}{-3}{2.07}
    \my@keycount=0
    \@for\lp@elem:=#4\do{%
      \expandafter\def\expandafter\my@cnum\expandafter{\the\my@keycount} %
      \expandafter\def\expandafter\my@keyname\expandafter{\expandafter{\expandafter d\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{-3}{2.3} %
      \advance\my@keycount by 1 %
    } %
    \my@specialkey{Shift}{Shift}{12.3}{-3}{1.97}
  \end{tikzpicture}%
}
\makeatother


\begin{document}

\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},{}{}{>}.,{}{}?/}


\end{document}

これをXeLaTeXでコンパイルすると次の様に描画される。
f:id:nixeneko:20170106192541p:plain

雑な解説

簡単に解説しておくと、\keyassignマクロは4つの引数、すなわち順に(上から)第1行目(キー13個)、第2行目(キー13個)、第3行目(キー11個)、第4行目(キー10個)のキー配列を引数としてとり、キー配列を描画する。
キー配列はキーをカンマ“,”で区切ったものである。
キーは文字4つ(何も文字がないところには{}を置く)からなり、左上、左下、右上、右下の順である。複数文字を一つの場所に入れる場合には{}で囲む。なお(La)TeXの特殊記号となっているものはエスケープしたりしないといけない。


\begin{document}~\end{document}の中の\keyassignマクロの部分を変えると他のキーボード配列を作成することができる。例えばロシア語キーボード配列だと、

\keyassign{{\char"07E}{\`{}}{}Ё,!1{}{},@2{\char"022}{},\#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}{}Б,{>}.{}Ю,?/.{\char"02C}}

のようにして、次のような画像が得られる。
f:id:nixeneko:20170106202632p:plain



なぜこんなものを作ったかというと、モンゴル文字キーボードのキー配列表を作りたかったからで、フォントの変更や文字の回転などを組み合わせて次のようになった。なかなかいい感じだと思う。
f:id:nixeneko:20170106200748p:plain


というか、作ってから時間たってるので、マクロ内部で何やってるのか覚えていない。何やら\expandafterとTikZに苦しんでいたのは覚えているが……。