縦軸を出力する際、5行ごとに ‘5 -’ や ‘10 - ’ といった文字列を挿入したいと考えています。また、数値とハイフンの位置を揃えるため、短い数値には先頭にスペースを詰めて埋める必要があります。一部の文字列で2桁の数値を使用する場合、1桁の数値を含む文字列には、数値の前に先頭の空白を入れる必要があります。
数値の長さを求めるには、length関数を使用します。しかし、length関数は文字列に対してのみ有効で、数値には適用できません。そのため、数値を数値から文字列に変換する必要があります。これはnumber-to-string関数を用いて行います。例えば、
(length (number-to-string 35))
⇒ 2
(length (number-to-string 100))
⇒ 3
(number-to-string は int-to-string とも呼ばれます。さまざまな資料でこの別称を目にするでしょう。)
さらに、各ラベルにおいて、各数値の後には ‘ - ’
のような文字列が続いており、これを Y-axis-tic マーカーと呼びます。この変数は defvar で定義されています:
(defvar Y-axis-tic " - " "String that follows number in a Y axis label.")
Y軸ラベルの長さは、Y軸の目盛りの長さとグラフ上部の数値の長さの和です。
(length (concat (number-to-string height) Y-axis-tic)))
この値は、print-graph 関数がその varlist 内で full-Y-label-width として計算し、そのまま渡します。(なお、最初に提案した際は、これを
varlist に含めることは想定していませんでした。)
完全な垂直軸ラベルを作成するには、目盛り記号と数値を連結します。また、数値の長さに応じて、これら2つの前に1つ以上のスペースが置かれる場合があります。ラベルは、(任意の)先頭スペース、数値、および目盛り記号の3つの部分で構成されます。この関数には、特定の行の数値と、print-graphによって(一度だけ)計算される最上行の幅の値が渡されます。
(defun Y-axis-element (number full-Y-label-width) "Construct a NUMBERed label element. A numbered element looks like this ` 5 - ', and is padded as needed so all line up with the element for the largest number."
(let* ((leading-spaces
(- full-Y-label-width
(length
(concat (number-to-string number)
Y-axis-tic)))))
(concat
(make-string leading-spaces ? )
(number-to-string number)
Y-axis-tic)))
Y-axis-element
関数は、先頭のスペース(あれば)、数値を文字列として、およびティックマークを連結します。
ラベルに必要な先頭のスペース数を算出するため、この関数は希望するラベル幅から、ラベルの実際の長さ(数値の長さに目盛りの長さを加えたもの)を差し引きます。
空白は make-string
関数を用いて挿入されます。この関数は2つの引数を取ります。1つ目は文字列の長さを、2つ目は特殊な形式の挿入文字を表す記号を指定します。形式は、‘? ’
のように、クエスチョンマークに続いて空白が入る形です。文字の構文に関する説明については、The GNU Emacs
Lisp Reference Manual の Character
Type を参照してください。(もちろん、空白を別の文字に置き換えたい場合もあるでしょう……やり方はお分かりかと思います。)
連結式ではnumber-to-string関数が使用されており、数値を文字列に変換して先頭のスペースやティックマークと連結しています。