使用Scheme在TeXmacs中生成图片

刚开始使用TeXmacs的时候就想照着Henri Lesourd写的A TeXmacs graphics tutorial用Scheme做一个图,结果由于对TeXmacs和Scheme的了解都不够深入,以及教程的时效性,没能成功。最近读了一点TeXmacs的文档之后,才有所领悟,花了一点时间读懂了这个教程示例代码,做了些许更改后,才做出下图:

A rose
A rose

本文将结合TeXmacs的内在机制简单介绍做图的整个过程和原理。我所用TeXmacs版本为1.99.2

作图过程

  • 新建一个名为hello/progs的目录:$ mkdir $HOME/.TeXmacs/plugins/hello/progs
  • 在该目录中新建文件init-hello.scm,其中内容为:
(define-macro (foreach i . b)
  `(for-each (lambda (,(car i))
               ,(cons 'begin b))
             ,(cadr i)))

(define-macro (foreach-number i . b)
  `(do ((,(car i) ,(cadr i)
         (,(if (memq (caddr i) '(> >=)) '- '+) ,(car i) 1)))
       ((,(if (eq? (caddr i) '>)
              '<=
              (if (eq? (caddr i) '<)
                  '>=
                  (if (eq? (caddr i) '>=) '< '>)))
         ,(car i) ,(cadddr i))
        ,(car i))
     ,(cons 'begin b)))

(define (rose r nsteps)
           (define pi (acos -1))
           (define points '())
           (define lines '())
           (set! r (tree->number r))
           (set! nsteps (tree->number nsteps))
           (foreach-number (i 0 < nsteps)
                           (with t (/ (* 2 i pi) nsteps)
                                  (set! points
                                        (cons `(point ,(number->string (* r (cos t)))
                                                      ,(number->string (* r (sin t))))
                                              points))))
           (foreach (p1 points)
                    (foreach (p2 points)
                             (set! lines (cons `(line ,p1 ,p2) lines))))
           `(with  "gr-geometry"  ,(cons 'tuple '("geometry" "0.5par" "0.5par" "center")) ,(cons 'graphics (append lines points))))
  • 启动TeXmacs,在文档中输入,回车即得所求图片。

相关的TeXmacs机制

  • 所有TeXmacs的文档或文档片段都可以看作是一棵树,而一棵树对应着一段TeXmacs Scheme代码。

  • 编辑文档并保存后,通过文件->导出->TeXmacs Scheme...就可以导出当前文档对应的TeXmacs Scheme代码。

  • TeXmacs提供了一套插件的机制,你可以撰写插件定义自己的函数,用该函数生成文档所需的Scheme代码。这样一来,文档就可以通过编程生成了,大大增加了撰写文档的灵活性。

  • 图像也有相应的Scheme代码。如一个点就是(point "0" "0"),一条线段就是(line (point "0" "0") (point "1" "1"))。原教程中关于图像指定大小的写法(with gr-geometry ...)已经被遗弃了,现在的写法是(with "gr-geometry" ...)。关于这点的验证可以通过使用菜单提供的功能画图,保存后导出成TeXmacs Scheme文档,观察其图像部分就可以知道。

  • 通过传递的两个参数半径和步数从TeXmacs传递到后台会变成tree类型,需要通过tree->number函数转换成数字。