home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / go / prog / sgf2mi13.taz / sgf2mi13 / game2tex.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-05  |  11.1 KB  |  488 lines

  1. /* #[info:            */
  2. /************************************************************************
  3.  *                                    *
  4.  *      ####     #    #    # #####       ####### ##### #     #    *
  5.  *     #        # #   ##  ## #      ###     #    #      #   #        *
  6.  *     #       #   #  # ## # #     #   #    #    #       # #        *
  7.  *     #  ##  ####### #    # ###      #     #    ###      #        *
  8.  *     #    # #     # #    # #       #      #    #       # #        *
  9.  *     #    # #     # #    # #      #       #    #      #   #        *
  10.  *      ####  #     # #    # ##### ######   #    ##### #     #    *
  11.  *                                    *
  12.  *                Jan van der Steen                *
  13.  *                                    *
  14.  *          Centre for Mathematics and Computer Science        *
  15.  *              Amsterdam, the Netherlands            *
  16.  *                                    *
  17.  *----------------------------------------------------------------------*
  18.  * File      : game2tex.c                         *
  19.  * Purpose : Emit a Go Game Using TeX directives            *
  20.  * Version : 1.27                         *
  21.  * Modified: 3/5/93 17:34:46                        *
  22.  * Author  : Jan van der Steen (jansteen@cwi.nl)             *
  23.  ************************************************************************/
  24. /* #]info:            */ 
  25. /* #[include:            */
  26.  
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include <time.h>
  31. #include "gogame.h"
  32. #include "game2asc.h"
  33. #include "game2tex.h"
  34. #include "game2eps.h"
  35. #include "tools.h"
  36. #include "sysdep.h"
  37.  
  38. /* #]include:            */ 
  39. /* #[define:            */
  40.  
  41. #define MAXUSER        1024    /* Maximum length of username    */
  42.  
  43. /* #]define:            */ 
  44. /* #[extern:            */
  45.  
  46. extern    int     prn_dev;
  47. extern    EPSFINFO epsf;
  48. extern    int     figlist[];    /* Figure  list                */
  49. extern    int     dialist[];    /* Diagram list                */
  50. extern    int     user_figs;    /* Users fig list?            */
  51. extern    int     user_dias;    /* Users dia list?            */
  52. extern    int     textout;    /* Emit the text too            */
  53. extern    int     statout;    /* Emit the kibitz stats        */
  54.  
  55. /* #]extern:            */ 
  56. /* #[prototype:            */
  57.  
  58. #ifdef __STDC__
  59. #    define    PROTO(s) s
  60. #else
  61. #    define    PROTO(s) ()
  62. #endif
  63.  
  64. static void    tex_header     PROTO((GOGAME *g));
  65. static void    tex_trailer      PROTO((void));
  66. static void    tex_text     PROTO((GOMOVE *m, int label));
  67. static void    text2tex     PROTO((char *t));
  68. static void    move2tex     PROTO((GOGAME *g, GOMOVE *m1, GOMOVE *m2,
  69.                     int dianr));
  70.  
  71.  
  72. #undef PROTO
  73.  
  74. /* #]prototype:            */ 
  75.  
  76. /* #[list2tex:            */
  77.  
  78. void
  79. list2tex(gogame)
  80. /*
  81.  * Print the game according to the user defined list of figures.
  82.  * Exchange kibitz and move and label the text output with move number.
  83.  */
  84. GOGAME *gogame;
  85. {
  86.     /*
  87.      * Diagram handling
  88.      */
  89.     GOMOVE *    m;
  90.     GOMOVE *    m1    = gogame->gm_move;
  91.     GOMOVE *    m2    = gogame->gm_move;
  92.     /*
  93.      * Text handling
  94.      */
  95.     GOMOVE *    t;
  96.     int        dianr    = 0;
  97.     int        fx    = 0;
  98.  
  99.     tex_header(gogame);
  100.  
  101.     for (m = gogame->gm_move; m != (GOMOVE *) 0; m = m->mv_next) {
  102.     m2 = m;
  103.     if (m->mv_nr == figlist[fx]) {
  104.         move2tex(gogame, m1, m, ++dianr);
  105.         m2 = m->mv_next;
  106.         /*
  107.          * Print all text associated with this diagram
  108.          */
  109.         for (t = m1; t != m2; t = t->mv_next) {
  110.         if (t->mv_text != (TEXT *) 0) tex_text(t, 1);
  111.         }
  112.         m1 = m->mv_next;
  113.         fx++;
  114.     }
  115.     }
  116.     /*
  117.      * Print diagram with the left-overs
  118.      */
  119.     if (figlist[fx] && m1 != (GOMOVE *) 0) {
  120.     move2tex(gogame, m1, m2, ++dianr);
  121.     /*
  122.      * Print all text associated with this diagram
  123.      */
  124.     for (t = m1; t != m2; t = t->mv_next) {
  125.         if (t->mv_text != (TEXT *) 0) tex_text(t, 1);
  126.     }
  127.     }
  128.  
  129.     tex_trailer();
  130. }
  131.  
  132. /* #]list2tex:            */ 
  133. /* #[game2tex:            */
  134.  
  135. void
  136. game2tex(gogame)
  137. /*
  138.  * Print the game events, exchanging kibitz and move
  139.  */
  140. GOGAME *gogame;
  141. {
  142.     GOMOVE *m;
  143.     GOMOVE *p1 = gogame->gm_move;
  144.     GOMOVE *p2 = gogame->gm_move;
  145.     int        dianr = 0;
  146.  
  147.     tex_header(gogame);
  148.  
  149.     for (m = gogame->gm_move; m != (GOMOVE *) 0; p2 = m, m = m->mv_next) {
  150.     if (m->mv_text != (TEXT *) 0) {
  151.         if (p1 != m) {
  152.         move2tex(gogame, p1, m->mv_prev, ++dianr);
  153.         p1 = m;
  154.         }
  155.         tex_text(m, 0);
  156.     }
  157.     }
  158.     move2tex(gogame, p1, p2, ++dianr);
  159.  
  160.     tex_trailer();
  161. }
  162.  
  163. /* #]game2tex:            */ 
  164.  
  165. /* #[tex_header:        */
  166.  
  167. static void
  168. tex_header(gogame)
  169. GOGAME *gogame;
  170. {
  171.     GOGAME *g = gogame;
  172.  
  173.     /*
  174.      * Ascii header of final position
  175.      */
  176.     fprintf(stdout, "%%%% #[Final position:\n");
  177.     game2ascii(gogame);
  178.     fprintf(stdout, "%%%% #]Final position: \n");
  179.  
  180.     /*
  181.      * Document header
  182.      */
  183.     fprintf(stdout, "\\documentstyle[a4wide%s,sgf%s]{article}\n",
  184.         (prn_dev == DEVICE_EPS) ? ",epsf" : "",
  185.         (prn_dev == DEVICE_TEX) ? ",go"   : "");
  186.     switch (prn_dev) {
  187.     case DEVICE_TEX:
  188.         fprintf(stdout, "\\gofontsize{8}\n");
  189.         break;
  190.     case DEVICE_EPS:
  191.         fprintf(stdout, "\\special{header=gopro.eps}\n");
  192.         break;
  193.     }
  194.  
  195.     /*
  196.      * Title page
  197.      */
  198.     fprintf(stdout, "\\title{%%\n");
  199.     fprintf(stdout, "    \\centerline{");
  200.         text2tex((g->gm_black) ? g->gm_black : "NN");
  201.         fprintf(stdout, ", ");
  202.         text2tex((g->gm_brank) ? g->gm_brank : "NR");
  203.     fprintf(stdout, "}\n");
  204.     fprintf(stdout, "    \\centerline{versus}\n");
  205.     fprintf(stdout, "    \\centerline{");
  206.         text2tex((g->gm_white) ? g->gm_white : "NN");
  207.         fprintf(stdout, ", ");
  208.         text2tex((g->gm_wrank) ? g->gm_wrank : "NR");
  209.     fprintf(stdout, "}\n");
  210.     fprintf(stdout, "}\n");
  211.     fprintf(stdout, "\\author{(generated by sgf2misc)}\n");
  212.     fprintf(stdout, "\\date  {");
  213.         text2tex((g->gm_date) ? g->gm_date : "");
  214.     fprintf(stdout, "}\n");
  215.     fprintf(stdout, "\\begin{document}\n");
  216.     fprintf(stdout, "\\maketitle\n");
  217.     fprintf(stdout, "\\clearpage\n");
  218.  
  219.     /*
  220.      * One or twocolumn depends on the mode and the diagram size
  221.      */
  222.     if ((prn_dev == DEVICE_EPS && epsf.eps_size <= 200) ||
  223.     (prn_dev == DEVICE_TEX                  ))
  224.     fprintf(stdout, "\\twocolumn\n");
  225.  
  226.     /*
  227.      * Section header
  228.      */
  229.     fprintf(stdout, "\\section{The Game}\n");
  230.  
  231.     /*
  232.      * Game header (players, rank, date, place and result)
  233.      */
  234.     fprintf(stdout, "\\Black{");
  235.             text2tex((g->gm_black) ? g->gm_black : "NN");
  236.             fprintf(stdout, "}{");
  237.             text2tex((g->gm_brank) ? g->gm_brank : "NR");
  238.     fprintf(stdout, "}\n");
  239.     fprintf(stdout, "\\White{");
  240.             text2tex((g->gm_white) ? g->gm_white : "NN");
  241.             fprintf(stdout, "}{");
  242.             text2tex((g->gm_wrank) ? g->gm_wrank : "NR");
  243.     fprintf(stdout, "}\n");
  244.     fprintf(stdout, "\\Date{");
  245.             text2tex((g->gm_date) ? g->gm_date : "");
  246.     fprintf(stdout, "}\n");
  247.     fprintf(stdout, "\\Place{");
  248.             text2tex((g->gm_place) ? g->gm_place : "");
  249.     fprintf(stdout, "}\n");
  250.     fprintf(stdout, "\\Result{");
  251.             text2tex((g->gm_result) ? g->gm_result : "");
  252.     fprintf(stdout, "}\n");
  253. }
  254.  
  255. /* #]tex_header:        */ 
  256. /* #[tex_trailer:        */
  257.  
  258. static void
  259. tex_trailer()
  260. {
  261.     if (statout) {
  262.     /*#[Name:*/
  263.  
  264.     fprintf(stdout, "%%%% #[By name:\n");
  265.     fprintf(stdout, "\\clearpage\n");
  266.     fprintf(stdout, "\\section{Kibitzers sorted by name}\n");
  267.     kib_list(0, "\\kdict");
  268.     fprintf(stdout, "%%%% #]By name: \n");
  269.  
  270.     /*#]Name:*/ 
  271.     /*#[Rank:*/
  272.  
  273.     fprintf(stdout, "%%%% #[By rank:\n");
  274.     fprintf(stdout, "\\vskip1000pt\n");
  275.     fprintf(stdout, "\\section{Kibitzers sorted by rank}\n");
  276.     kib_list(1, "\\krank");
  277.     fprintf(stdout, "%%%% #]By rank: \n");
  278.  
  279.     /*#]Rank:*/ 
  280.     /*#[Freq:*/
  281.  
  282.     fprintf(stdout, "%%%% #[By frequency:\n");
  283.     fprintf(stdout, "\\vskip1000pt\n");
  284.     fprintf(stdout, "\\section{Kibitzers sorted by frequency}\n");
  285.     kib_list(2, "\\kfreq");
  286.     fprintf(stdout, "%%%% #]By frequency: \n");
  287.  
  288.     /*#]Freq:*/ 
  289.     /*#[Byte:*/
  290.  
  291.     fprintf(stdout, "%%%% #[By amount:\n");
  292.     fprintf(stdout, "\\vskip1000pt\n");
  293.     fprintf(stdout, "\\section{Kibitzers sorted by amount}\n");
  294.     kib_list(3, "\\kbyte");
  295.     fprintf(stdout, "%%%% #]By amount: \n");
  296.  
  297.     /*#]Byte:*/ 
  298.     }
  299.  
  300.     fprintf(stdout, "\\end{document}\n");
  301.     fprintf(stderr, "\n");    /* To flush the messages on stderr */
  302. }
  303.  
  304. /* #]tex_trailer:        */ 
  305. /* #[tex_text:            */
  306.  
  307. static void
  308. tex_text(m, label)
  309. GOMOVE *m;
  310. int    label;            /* Do we need to label the text comment    */
  311. {
  312.     TEXT *t;
  313.     char lastname[MAXUSER];
  314.  
  315.     /*
  316.      * Collect kibitz statistics
  317.      */
  318.     kib_add(m->mv_text);
  319.  
  320.     if (!textout) return;
  321.     lastname[0] = 0;
  322.     if (label)
  323.     fprintf(stdout,
  324.         "\\n{%s: %d}\n",
  325.         (m->mv_side == BLACK) ? "Black" : "White",
  326.         m->mv_nr);
  327.     for (t = m->mv_text; t != (TEXT *) 0; t = t->cc_next) {
  328.     if (strcmp(lastname, t->cc_name)) {
  329.         /*
  330.          * New username
  331.          */
  332.         strcpy(lastname, t->cc_name);
  333.         fprintf(stdout, "\\k{");
  334.             text2tex((t->cc_name) ? t->cc_name : "NN");
  335.         fprintf(stdout, "}{(");
  336.             text2tex((t->cc_rank) ? t->cc_rank : "NR");
  337.         fprintf(stdout, ")}{");
  338.     } else {
  339.         /*
  340.          * Same username
  341.          */
  342.         fprintf(stdout, "\\k{}{}{"/*}*/);
  343.     }
  344.     text2tex(t->cc_text);
  345.     fprintf(stdout, "}\n");
  346.     }
  347. }
  348.  
  349. /* #]tex_text:            */ 
  350. /* #[text2tex:            */
  351.  
  352. static void
  353. text2tex(t)
  354. /*
  355.  * Copy t to standard output while taking care of LaTeX special characters.
  356.  */
  357. char *t;
  358. {
  359.     for (; *t; t++) {
  360.     /*
  361.      * Special characters
  362.      */
  363.     if (*t == '_' || *t == '#' || *t == '{' || *t == '}' ||
  364.         *t == '&' || *t == '%' || *t == '$') {
  365.         fprintf(stdout, "\\%c", *t);
  366.     } else
  367.  
  368.     /*
  369.      * Accent characters
  370.      */
  371.     if (*t == '^') {
  372.         fprintf(stdout, "\\%c{}", *t);
  373.     } else
  374.  
  375.     /*
  376.      * Math characters
  377.      */
  378.     if (*t == '+' || *t == '-' ||
  379.         *t == '<' || *t == '>' ||
  380.         *t == '|' || *t == '=') {
  381.         fprintf(stdout, "$%c$", *t);
  382.     } else
  383.  
  384.     /*
  385.      * Backslash
  386.      */
  387.     if (*t == '~') {
  388.         fprintf(stdout, "\\Tilde%c", (*(t+1) == ' ') ? '\\' : ' ');
  389.     } else
  390.  
  391.     /*
  392.      * Backslash
  393.      */
  394.     if (*t == '\\')
  395.         fprintf(stdout, "$\\backslash$");
  396.  
  397.     else  putc(*t, stdout);
  398.     }
  399. }
  400.  
  401. /* #]text2tex:            */ 
  402. /* #[move2tex:            */
  403.  
  404. static void
  405. move2tex(gogame, m1, m2, diagram)
  406. /*
  407.  * Emit a diagram from move m1 up to and including m2.
  408.  * m1 may be equal to m2.
  409.  */
  410. GOGAME *gogame;
  411. GOMOVE *m1;
  412. GOMOVE *m2;
  413. int    diagram;
  414. {
  415.     int move_min = m1->mv_nr;
  416.     int move_max = (m1 == m2 || m2 == (GOMOVE *) 0) ? move_min : m2->mv_nr;
  417.  
  418.     /*
  419.      * Keep diagram and caption on the same page
  420.      */
  421.     fprintf(stdout, "\\vbox{%%\n");
  422.  
  423.     /*
  424.      * Print the PS file/emit the TeX diagram
  425.      */
  426.     game2eps(gogame, diagram, move_min, move_max);
  427.  
  428.     /*
  429.      * Print the diagram caption
  430.      */
  431.     if (move_min == move_max) {
  432.     /*
  433.      * Single move diagram
  434.      */
  435.     switch (prn_dev) {
  436.     case DEVICE_TEX:
  437.         /*
  438.          * Print the diagram moves/caption
  439.          */
  440.         fprintf(stdout, "    \\texmove{%d}{%s}{%d}\n",
  441.             diagram,
  442.             (m1->mv_side == BLACK) ? "Black" : "White", m1->mv_nr);
  443.         break;
  444.     case DEVICE_EPS:
  445.         /*
  446.          * Print the diagram moves/caption
  447.          */
  448.         fprintf(stdout, "    \\epsmove{%s%c%s.%03d}{%s}{%d}\n",
  449.             epsf.eps_dir, PATHSEP, epsf.eps_name,
  450.             diagram,
  451.             (m1->mv_side == BLACK) ? "Black" : "White", m1->mv_nr);
  452.         break;
  453.     }
  454.     } else {
  455.     /*
  456.      * Multiple move diagram
  457.      */
  458.     switch (prn_dev) {
  459.     case DEVICE_TEX:
  460.         /*
  461.          * Print the diagram moves/caption
  462.          */
  463.         fprintf(stdout, "    \\texmoves{%d}{%s}{%d}{%s}{%d}\n",
  464.             diagram,
  465.             (m1->mv_side == BLACK) ? "Black" : "White", m1->mv_nr,
  466.             (m2->mv_side == BLACK) ? "Black" : "White", m2->mv_nr);
  467.         break;
  468.     case DEVICE_EPS:
  469.         /*
  470.          * Print the diagram moves/caption
  471.          */
  472.         fprintf(stdout, "    \\epsmoves{%s%c%s.%03d}{%s}{%d}{%s}{%d}\n",
  473.             epsf.eps_dir, PATHSEP, epsf.eps_name,
  474.             diagram,
  475.             (m1->mv_side == BLACK) ? "Black" : "White", m1->mv_nr,
  476.             (m2->mv_side == BLACK) ? "Black" : "White", m2->mv_nr);
  477.         break;
  478.     }
  479.     }
  480.  
  481.     /*
  482.      * Keep diagram and caption on the same page
  483.      */
  484.     fprintf(stdout, "}\n");
  485. }
  486.  
  487. /* #]move2tex:            */ 
  488.