5

This is a question about typesetting diagrams for the Game of Go using the sgf2dg tools (currently in their version 4.252 available at their CPAN home). The sgf2dg tools can be used to create go diagrams from sgf files (smart game format) and to annotate the diagrams as in this example:

Example for a Go diagram

The diagrams look very nice to me and I would like to add comments with numbered stones as well. The sgf2dg TeX library gooemacs.sty makes available the command \textstone{} for exactly that purpose. The lines

This is a black stone: \textstone{\goo\003@}
This is a smaller black stone: {\setGoFonts at 1.8ex \textstone{\goo\003@}}

produce the nice output of:

example of textstone command

Now my problem

The \textstone{} command does everything I want for a price: The input of the go stone's label has to be in that specific \goo (or \goe) format as a four digit code. In the example above \goo\003@ will produce a black stone labeled 3. \goo (and their relatives \goe, \bgoo and \bgoe) are font selection mechanisms. Here is the definition of \goo from the package gooemacs.sty:

\def\goo{\offinterlineskip\parindent=0pt\parskip=0pt\obeylines%black odd, white even
\setbox0\hbox{\gooegb +}\global\goIntWd=\wd0\global\goIntHt=\ht0\global\goTextAdj=2pt%
\def\0##1##2##3{\if##1?\gooegb ##3 \else \gooa\char##1##2 \fi}%
\def\1##1##2##3{\if##1?\gooegb ##3 \else \goob\char##1##2 \fi}%
\def\2##1##2##3{\if##1?\gooegb ##3 \else \gooc\char##1##2 \fi}%
\def\3##1##2##3{\if##1?\gooegb ##3 \else \good\char##1##2 \fi}%
\def\4##1##2##3{\if##1?\gooegb ##3 \else \gobl\char##1##2 \fi}%
\def\5##1##2##3{\if##1?\gooegb ##3 \else \gowl\char##1##2 \fi}%
\def\-##1##2{\gooegb ##1}%
\def\!##1{\leavevmode\hbox to \goIntWd{\hss\raise\goTextAdj\hbox{\rm ##1}\hss}}% #1 on empty intersections
}

I do, however, consider their encryption as too complicated to think about while writing my go diagram's annotation.

For annotating the diagrams I want to use a high (higher) level LaTeX macro like \Black{}. I want to write \Black{3} in my source code and then have it transformed to its corresponding \goo\003@.

Question

My attempt was to define a new command like:

\newcommand{\Black}[1]{%
\ifnum #1 >299 {\goo\#1@}\fi%
}
\Black{301}

but the replacement #1 fails (because of the preceding \ I guess) and produces the output \#1. How can I prevent that? How can I have TeX replace #1 and put it right after a backslash?

Remarks

I do realize there are more problems to solve: font selection based on even/odd label number, missing leading zeros with smaller stone numbers (1-99).

If you try to convert an sgf file to tex be aware of a bug in sgf2dg's version 4.252: stackoverflow.com.

The change of font size command in gooemacs.sty (\setGoFonts at #1) is missing end-of-line-%s, see What is the use of percent signs (%) at the end of lines?.


As a MWE I attach some working TeX code with the sgf2dg package. As mentioned above my attempt at \Black{} failed and is not included here. The example requires the installation of sgf2dg package (with gooemacs), which is also available on many Linux distributions.

\documentclass[margin=1mm]{standalone}
\usepackage{gooemacs}

\begin{document}
This is a black stone: \textstone{\goo\003@}
This is a smaller black stone: {\setGoFonts at 1.8ex \textstone{\goo\003@}}
\end{document}
  • \Black{3} in my source code and then have it transformed to its corresponding \goo\003@ would be \newcommand\Black[1]{\goo\00#1@} but your suggested code is trying something else testing for 299? (sorry not playing go, it's hard to guess what the intended usage is here) – David Carlisle Jan 15 '17 at 11:11
  • Your suggestion works for Black single digit labels 1-9. \Black{13} for example fails: \goo\013@ intended, but \goo\0013@ received. –  Jan 15 '17 at 11:23
  • oh as i say that's easily fixed but I don't know what the input or output should be except in the case you mentioned. \goo\003@ is 5 tokens \goo, \0, 0, 3, @ so for \Black do you want the first two tokens always to be \goo\0 the last token always to be @ and the middle two tokens to be a number #1 padded with a leading zero if less than 10 ? or do you sometimes need 3 digit input and change the \0 token ? – David Carlisle Jan 15 '17 at 11:28
  • I have added the definition of \goo in the question. I require input up to \Black{399} (this is how many labels are offered by the fonts). They need token \0 for labels up to 99 (with additional zero for single digits), then \1 for 100-199, \2 for 200-299 and lastly \3 for 300-399 –  Jan 15 '17 at 11:50
  • yes I had the macro from the code site but didn't want to guess the range of inputs:-) that code seems to be doing testing for ? in the input as well, which isn't handled by my answer – David Carlisle Jan 15 '17 at 11:54
  • indeed, ? is used for a handful of special symbols like triangle or square as label for a go stone. Eventually I want to be able to handle \Black{triangle} or that sort, but I havn't asked about that yet... –  Jan 15 '17 at 12:05

2 Answers2

3

If I understand the requirements I think

\Black{3}

\Black{41}

\Black{99}

\Black{555}

produces

testing:\goo\003@
testing:\goo\041@
testing:\goo\099@
testing:\goo\555@

In this version just echoed to the terminal, remove the \goo definition for your real code.

\documentclass{article}

%this line just for testing without the go package
\def\goo#1@{\typeout{testing:\string\goo\string#1@}}

\newcommand\Black[1]{{%
\count0=#1\relax
\divide\count0 by 100\relax
\count2=\numexpr#1-100*\count0\relax
\count4=\count2\relax
\divide\count2 by 10
\count4=\numexpr\count4-10*\count2\relax
\edef\tmp{\noexpand\goo
\expandafter\noexpand\csname\the\count0\endcsname
\the\count2
\the\count4
@}\tmp
}}
\begin{document}


\Black{3}

\Black{41}

\Black{99}

\Black{555}


\end{document}
David Carlisle
  • 757,742
  • While attempting to use part of your answer I stumbled upon your \tmp. Why doesn't just {\goo\csname #1@\endcsname} work (assuming #1 is a three digit number)? or {\expandafter\goo\csname #1@\endcsname} for that matter? –  Jan 16 '17 at 16:08
  • @flobo you need all three arguments to \goo to be single tokens, so you need to expand \csname #1@\endcsname for the first and \the\count2 for the second and \the\count4 for the third before \goo is executed, it would be possible to chain several \expandafter but the \edef method is simpler here. – David Carlisle Jan 16 '17 at 16:26
  • @flobo no \csname #1@\endcsname would be completely the wrong thing! that would make, given 123 a command with name 123 but \123 as used in \goo\123 is \1 followed by 2 and 3 that is why above I have to do the arithmetic to get the "hundreds" value before passing just that digit to \csname that is you need to make \goo{\1}{2}{3}@ from an argument of 123 – David Carlisle Jan 16 '17 at 16:29
3

In this answer I present a solution that works for even numbered stones as well as for letter markings. Instead of writing a high level macro for \goo we replace it by a new font selection mechanism \mygo.

font test Black

\documentclass[margin=3mm]{standalone}
\usepackage{gooemacs}

\def\mygo{%
  \def\a##1##2##3{\ifodd ##3 \gooa\char##2##3 \else \goea\char##2##3\fi}% 1 - 99
  \def\b##1##2##3{\ifodd ##3 \goob\char##2##3 \else \goeb\char##2##3\fi}% hundreds
  \def\c##1##2##3{\ifodd ##3 \gooc\char##2##3 \else \goec\char##2##3\fi}% two hundreds
  \def\d##1##2##3{\ifodd ##3 \good\char##2##3 \else \goed\char##2##3\fi}% three hundreds
  \def\s##1{\gooegb##1}%
  \def\t##1##2{\gobl\char##1##2}% if label, subst 2 for ##1 ??
}

\newcommand{\Black}[1]{%
\if!\ifnum9<1#1!\fi% if it's a number:
{\ifnum #1<10 {\mygo\a00#1}%
  \else \ifnum #1<100 {\mygo\a0#1}%
  \else \ifnum #1<200 {\mygo\b#1}%
  \else \ifnum #1<300 {\mygo\c#1}%
  \else \ifnum #1<400 {\mygo\d#1}%
  \fi% larger numbers will not be printed, no error message.
  \fi%
  \fi%
  \fi%
  \fi}%
\else%if it's a letter:
{\mygo\t\numexpr`#1-`\a+1\relax}\fi%
}%

\begin{document}
\begin{minipage}{5cm}

\Black{1}\Black{2}\Black{11}\Black{12}\Black{111}\Black{112}\Black{211}\Black{212}\Black{311}\Black{312}\\
\Black{a}\Black{b}\Black{c}\Black{d}\Black{e}\Black{f}\Black{g}\Black{h}\Black{i}\Black{j}

\end{minipage}
\end{document}

The solution can easily be extended for White stones.


Possible extensions/improvements: I wonder if the number of conditionals can be reduced. The order of the if-then-else structure might better test for letters first, as one is more likely to comment on Black a than on Black 312?

Also, symbols are not supported yet. I wonder if optional arguments are the way to go here. For example like \Black[t]{} for a Black stone marked with a triangle. The definition of \mygo is prepared for this with \def\s##1{\gooegb##1}% (\gooegb is sgf2dg font of marked stones).