aboutsummaryrefslogtreecommitdiff
path: root/src/guile/skribilo/package
diff options
context:
space:
mode:
Diffstat (limited to 'src/guile/skribilo/package')
-rw-r--r--src/guile/skribilo/package/Makefile.am7
-rw-r--r--src/guile/skribilo/package/acmproc.scm164
-rw-r--r--src/guile/skribilo/package/base.scm1410
-rw-r--r--src/guile/skribilo/package/eq.scm439
-rw-r--r--src/guile/skribilo/package/eq/Makefile.am4
-rw-r--r--src/guile/skribilo/package/eq/lout.scm217
-rw-r--r--src/guile/skribilo/package/french.scm30
-rw-r--r--src/guile/skribilo/package/jfp.scm328
-rw-r--r--src/guile/skribilo/package/letter.scm157
-rw-r--r--src/guile/skribilo/package/lncs.scm158
-rw-r--r--src/guile/skribilo/package/pie.scm314
-rw-r--r--src/guile/skribilo/package/pie/Makefile.am4
-rw-r--r--src/guile/skribilo/package/pie/lout.scm132
-rw-r--r--src/guile/skribilo/package/scribe.scm240
-rw-r--r--src/guile/skribilo/package/sigplan.scm166
-rw-r--r--src/guile/skribilo/package/skribe.scm85
-rw-r--r--src/guile/skribilo/package/slide.scm274
-rw-r--r--src/guile/skribilo/package/slide/Makefile.am4
-rw-r--r--src/guile/skribilo/package/slide/base.scm185
-rw-r--r--src/guile/skribilo/package/slide/html.scm144
-rw-r--r--src/guile/skribilo/package/slide/latex.scm394
-rw-r--r--src/guile/skribilo/package/slide/lout.scm151
-rw-r--r--src/guile/skribilo/package/web-article.scm241
-rw-r--r--src/guile/skribilo/package/web-book.scm121
24 files changed, 5369 insertions, 0 deletions
diff --git a/src/guile/skribilo/package/Makefile.am b/src/guile/skribilo/package/Makefile.am
new file mode 100644
index 0000000..693f088
--- /dev/null
+++ b/src/guile/skribilo/package/Makefile.am
@@ -0,0 +1,7 @@
+guilemoduledir = $(GUILE_SITE)/skribilo/package
+dist_guilemodule_DATA = acmproc.scm french.scm jfp.scm letter.scm \
+ lncs.scm scribe.scm sigplan.scm skribe.scm \
+ slide.scm web-article.scm web-book.scm \
+ eq.scm pie.scm base.scm
+
+SUBDIRS = slide eq pie
diff --git a/src/guile/skribilo/package/acmproc.scm b/src/guile/skribilo/package/acmproc.scm
new file mode 100644
index 0000000..61eafd5
--- /dev/null
+++ b/src/guile/skribilo/package/acmproc.scm
@@ -0,0 +1,164 @@
+;;; acmproc.scm -- The Skribe style for ACMPROC articles.
+;;;
+;;; Copyright 2003, 2004 Manuel Serrano
+;;;
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;; USA.
+
+;*---------------------------------------------------------------------*/
+;* LaTeX global customizations */
+;*---------------------------------------------------------------------*/
+(let ((le (find-engine 'latex)))
+ (engine-custom-set! le
+ 'documentclass
+ "\\documentclass[letterpaper]{acmproc}")
+ ;; &latex-author
+ (markup-writer '&latex-author le
+ :before (lambda (n e)
+ (let ((body (markup-body n)))
+ (printf "\\numberofauthors{~a}\n\\author{\n"
+ (if (pair? body) (length body) 1))))
+ :action (lambda (n e)
+ (let ((body (markup-body n)))
+ (for-each (lambda (a)
+ (display "\\alignauthor\n")
+ (output a e))
+ (if (pair? body) body (list body)))))
+ :after "}\n")
+ ;; author
+ (let ((old-author (markup-writer-get 'author le)))
+ (markup-writer 'author le
+ :options (writer-options old-author)
+ :action (writer-action old-author)))
+ ;; ACM category, terms, and keywords
+ (markup-writer '&acm-category le
+ :options '(:index :section :subsection)
+ :before (lambda (n e)
+ (display "\\category{")
+ (display (markup-option n :index))
+ (display "}")
+ (display "{")
+ (display (markup-option n :section))
+ (display "}")
+ (display "{")
+ (display (markup-option n :subsection))
+ (display "}\n["))
+ :after "]\n")
+ (markup-writer '&acm-terms le
+ :before "\\terms{"
+ :after "}")
+ (markup-writer '&acm-keywords le
+ :before "\\keywords{"
+ :after "}")
+ (markup-writer '&acm-copyright le
+ :action (lambda (n e)
+ (display "\\conferenceinfo{")
+ (output (markup-option n :conference) e)
+ (display ",} {")
+ (output (markup-option n :location) e)
+ (display "}\n")
+ (display "\\CopyrightYear{")
+ (output (markup-option n :year) e)
+ (display "}\n")
+ (display "\\crdata{")
+ (output (markup-option n :crdata) e)
+ (display "}\n"))))
+
+;*---------------------------------------------------------------------*/
+;* HTML global customizations */
+;*---------------------------------------------------------------------*/
+(let ((he (find-engine 'html)))
+ (markup-writer '&html-acmproc-abstract he
+ :action (lambda (n e)
+ (let* ((ebg (engine-custom e 'abstract-background))
+ (bg (or (and (string? ebg)
+ (> (string-length ebg) 0))
+ ebg
+ "#cccccc"))
+ (exp (p (center (color :bg bg :width 90.
+ (markup-body n))))))
+ (skribe-eval exp e))))
+ ;; ACM category, terms, and keywords
+ (markup-writer '&acm-category :action #f)
+ (markup-writer '&acm-terms :action #f)
+ (markup-writer '&acm-keywords :action #f)
+ (markup-writer '&acm-copyright :action #f))
+
+;*---------------------------------------------------------------------*/
+;* abstract ... */
+;*---------------------------------------------------------------------*/
+(define-markup (abstract #!rest opt #!key (class "abstract") postscript)
+ (if (engine-format? "latex")
+ (section :number #f :title "ABSTRACT" (p (the-body opt)))
+ (let ((a (new markup
+ (markup '&html-acmproc-abstract)
+ (body (the-body opt)))))
+ (list (if postscript
+ (section :number #f :toc #f :title "Postscript download"
+ postscript))
+ (section :number #f :toc #f :class class :title "Abstract" a)
+ (section :number #f :toc #f :title "Table of contents"
+ (toc :subsection #t))))))
+
+;*---------------------------------------------------------------------*/
+;* acm-category ... */
+;*---------------------------------------------------------------------*/
+(define-markup (acm-category #!rest opt #!key index section subsection)
+ (new markup
+ (markup '&acm-category)
+ (options (the-options opt))
+ (body (the-body opt))))
+
+;*---------------------------------------------------------------------*/
+;* acm-terms ... */
+;*---------------------------------------------------------------------*/
+(define-markup (acm-terms #!rest opt)
+ (new markup
+ (markup '&acm-terms)
+ (options (the-options opt))
+ (body (the-body opt))))
+
+;*---------------------------------------------------------------------*/
+;* acm-keywords ... */
+;*---------------------------------------------------------------------*/
+(define-markup (acm-keywords #!rest opt)
+ (new markup
+ (markup '&acm-keywords)
+ (options (the-options opt))
+ (body (the-body opt))))
+
+;*---------------------------------------------------------------------*/
+;* acm-copyright ... */
+;*---------------------------------------------------------------------*/
+(define-markup (acm-copyright #!rest opt #!key conference location year crdata)
+ (let* ((le (find-engine 'latex))
+ (cop (format "\\conferenceinfo{~a,} {~a}
+\\CopyrightYear{~a}
+\\crdata{~a}\n" conference location year crdata))
+ (old (engine-custom le 'predocument)))
+ (if (string? old)
+ (engine-custom-set! le 'predocument (string-append cop old))
+ (engine-custom-set! le 'predocument cop))))
+
+;*---------------------------------------------------------------------*/
+;* references ... */
+;*---------------------------------------------------------------------*/
+(define (references)
+ (list "\n\n"
+ (if (engine-format? "latex")
+ (font :size -1 (flush :side 'left (the-bibliography)))
+ (section :title "References"
+ (font :size -1 (the-bibliography))))))
diff --git a/src/guile/skribilo/package/base.scm b/src/guile/skribilo/package/base.scm
new file mode 100644
index 0000000..bbb2a62
--- /dev/null
+++ b/src/guile/skribilo/package/base.scm
@@ -0,0 +1,1410 @@
+;;; base.scm -- The base markup package of Skribe/Skribilo.
+;;;
+;;; Copyright 2003, 2004 Manuel Serrano
+;;; Copyright 2005, 2006 Ludovic Courtès <ludovic.courtes@laas.fr>
+;;;
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;; USA.
+
+(define-module (skribilo package base)
+ :use-syntax (skribilo lib)
+ :use-syntax (skribilo reader)
+ :use-syntax (skribilo utils syntax)
+ :use-syntax (ice-9 optargs)
+
+ :use-module (skribilo ast)
+ :use-module (skribilo resolve)
+ :use-module (skribilo utils keywords)
+ :autoload (srfi srfi-1) (every any filter)
+ :autoload (skribilo evaluator) (include-document)
+ :autoload (skribilo engine) (engine?)
+
+ ;; optional ``sub-packages''
+ :autoload (skribilo biblio) (default-bib-table resolve-bib
+ bib-load! bib-add!)
+ :autoload (skribilo color) (skribe-use-color!)
+ :autoload (skribilo source) (language? source-read-lines source-fontify)
+ :autoload (skribilo prog) (make-prog-body resolve-line)
+ :autoload (skribilo index) (make-index-table)
+
+ :replace (symbol))
+
+(fluid-set! current-reader (make-reader 'skribe))
+
+;;; Author: Manuel Serrano
+;;; Commentary:
+;;;
+;;; This module contains all the core markups of Skribe/Skribilo.
+;;;
+;;; Code:
+
+
+;;; The contents of the file below are (almost) unchanged compared to Skribe
+;;; 1.2d's `api.scm' file found in the `common' directory.
+
+
+
+;*---------------------------------------------------------------------*/
+;* include ... */
+;*---------------------------------------------------------------------*/
+(define-markup (include file)
+ (if (not (string? file))
+ (skribe-error 'include "Illegal file (string expected)" file)
+ (include-document file)))
+
+;*---------------------------------------------------------------------*/
+;* document ... */
+;*---------------------------------------------------------------------*/
+(define-markup (document #!rest
+ opts
+ #!key
+ (ident #f) (class "document")
+ (title #f) (html-title #f) (author #f)
+ (ending #f) (keywords '()) (env '()))
+ (new document
+ (markup 'document)
+ (ident (or ident
+ (ast->string title)
+ (symbol->string (gensym "document"))))
+ (class class)
+ (required-options '(:title :author :ending))
+ (options (the-options opts :ident :class :env))
+ (body (the-body opts))
+ (env (append env
+ (list (list 'chapter-counter 0) (list 'chapter-env '())
+ (list 'section-counter 0) (list 'section-env '())
+ (list 'footnote-counter 0) (list 'footnote-env '())
+ (list 'figure-counter 0) (list 'figure-env '()))))))
+
+;*---------------------------------------------------------------------*/
+;* keyword-list->comma-separated ... */
+;*---------------------------------------------------------------------*/
+(define-public (keyword-list->comma-separated kw*)
+ ;; Turn the the list of keywords (which may be strings or other markups)
+ ;; KW* into a markup where the elements of KW* are comma-separated. This
+ ;; may commonly be used in handling the `:keywords' option of `document'.
+ (let loop ((kw* kw*) (result '()))
+ (if (null? kw*)
+ (reverse! result)
+ (loop (cdr kw*)
+ (cons* (if (pair? (cdr kw*)) ", " "")
+ (car kw*) result)))))
+
+;*---------------------------------------------------------------------*/
+;* author ... */
+;*---------------------------------------------------------------------*/
+(define-markup (author #!rest
+ opts
+ #!key
+ (ident #f) (class "author")
+ name
+ (title #f)
+ (affiliation #f)
+ (email #f)
+ (url #f)
+ (address #f)
+ (phone #f)
+ (photo #f)
+ (align 'center))
+ (if (not (memq align '(center left right)))
+ (skribe-error 'author "Illegal align value" align)
+ (new container
+ (markup 'author)
+ (ident (or ident (symbol->string (gensym "author"))))
+ (class class)
+ (required-options '(:name :title :affiliation :email :url :address :phone :photo :align))
+ (options `((:name ,name)
+ (:align ,align)
+ ,@(the-options opts :ident :class)))
+ (body #f))))
+
+;*---------------------------------------------------------------------*/
+;* toc ... */
+;*---------------------------------------------------------------------*/
+(define-markup (toc #!rest
+ opts
+ #!key
+ (ident #f) (class "toc")
+ (chapter #t) (section #t) (subsection #f)
+ (subsubsection #f))
+ (let ((body (the-body opts)))
+ (new container
+ (markup 'toc)
+ (ident (or ident (symbol->string (gensym "toc"))))
+ (class class)
+ (required-options '())
+ (options `((:chapter ,chapter)
+ (:section ,section)
+ (:subsection ,subsection)
+ (:subsubsection ,subsubsection)
+ ,@(the-options opts :ident :class)))
+ (body (cond
+ ((null? body)
+ (new unresolved
+ (proc (lambda (n e env)
+ (handle
+ (resolve-search-parent n env document?))))))
+ ((null? (cdr body))
+ (if (handle? (car body))
+ (car body)
+ (skribe-error 'toc
+ "Illegal argument (handle expected)"
+ (if (markup? (car body))
+ (markup-markup (car body))
+ "???"))))
+ (else
+ (skribe-error 'toc "Illegal argument" body)))))))
+
+;*---------------------------------------------------------------------*/
+;* chapter ... ... */
+;* ------------------------------------------------------------- */
+;* doc: */
+;* @ref ../../doc/user/sectioning.skb:chapter@ */
+;* writer: */
+;* html: @ref ../../skr/html.skr:chapter@ */
+;*---------------------------------------------------------------------*/
+(define-markup (chapter #!rest
+ opts
+ #!key
+ (ident #f) (class "chapter")
+ title (html-title #f) (file #f) (toc #t) (number #t))
+ (new container
+ (markup 'chapter)
+ (ident (or ident (symbol->string (gensym "chapter"))))
+ (class class)
+ (required-options '(:title :file :toc :number))
+ (options `((:toc ,toc)
+ (:number ,(and number
+ (new unresolved
+ (proc (lambda (n e env)
+ (resolve-counter n
+ env
+ 'chapter
+ number))))))
+ ,@(the-options opts :ident :class)))
+ (body (the-body opts))
+ (env (list (list 'section-counter 0) (list 'section-env '())
+ (list 'footnote-counter 0) (list 'footnote-env '())))))
+
+;*---------------------------------------------------------------------*/
+;* section-number ... */
+;*---------------------------------------------------------------------*/
+(define (section-number number markup)
+ (and number
+ (new unresolved
+ (proc (lambda (n e env)
+ (resolve-counter n env markup number))))))
+
+;*---------------------------------------------------------------------*/
+;* section ... */
+;* ------------------------------------------------------------- */
+;* doc: */
+;* @ref ../../doc/user/sectioning.skb:section@ */
+;* writer: */
+;* html: @ref ../../skr/html.skr:sectionr@ */
+;*---------------------------------------------------------------------*/
+(define-markup (section #!rest
+ opts
+ #!key
+ (ident #f) (class "section")
+ title (file #f) (toc #t) (number #t))
+ (new container
+ (markup 'section)
+ (ident (or ident (symbol->string (gensym "section"))))
+ (class class)
+ (required-options '(:title :toc :file :toc :number))
+ (options `((:number ,(section-number number 'section))
+ (:toc ,toc)
+ ,@(the-options opts :ident :class)))
+ (body (the-body opts))
+ (env (if file
+ (list (list 'subsection-counter 0) (list 'subsection-env '())
+ (list 'footnote-counter 0) (list 'footnote-env '()))
+ (list (list 'subsection-counter 0) (list 'subsection-env '()))))))
+
+;*---------------------------------------------------------------------*/
+;* subsection ... */
+;* ------------------------------------------------------------- */
+;* doc: */
+;* @ref ../../doc/user/sectioning.skb:subsection@ */
+;* writer: */
+;* html: @ref ../../skr/html.skr:subsectionr@ */
+;*---------------------------------------------------------------------*/
+(define-markup (subsection #!rest
+ opts
+ #!key
+ (ident #f) (class "subsection")
+ title (file #f) (toc #t) (number #t))
+ (new container
+ (markup 'subsection)
+ (ident (or ident (symbol->string (gensym "subsection"))))
+ (class class)
+ (required-options '(:title :toc :file :number))
+ (options `((:number ,(section-number number 'subsection))
+ (:toc ,toc)
+ ,@(the-options opts :ident :class)))
+ (body (the-body opts))
+ (env (list (list 'subsubsection-counter 0) (list 'subsubsection-env '())))))
+
+;*---------------------------------------------------------------------*/
+;* subsubsection ... */
+;* ------------------------------------------------------------- */
+;* doc: */
+;* @ref ../../doc/user/sectioning.skb:subsubsection@ */
+;* writer: */
+;* html: @ref ../../skr/html.skr:subsubsectionr@ */
+;*---------------------------------------------------------------------*/
+(define-markup (subsubsection #!rest
+ opts
+ #!key
+ (ident #f) (class "subsubsection")
+ title (file #f) (toc #f) (number #t))
+ (new container
+ (markup 'subsubsection)
+ (ident (or ident (symbol->string (gensym "subsubsection"))))
+ (class class)
+ (required-options '(:title :toc :number :file))
+ (options `((:number ,(section-number number 'subsubsection))
+ (:toc ,toc)
+ ,@(the-options opts :ident :class)))
+ (body (the-body opts))))
+
+;*---------------------------------------------------------------------*/
+;* paragraph ... */
+;*---------------------------------------------------------------------*/
+(define-simple-markup paragraph)
+
+
+;*---------------------------------------------------------------------*/
+;* ~ (unbreakable space) ... */
+;*---------------------------------------------------------------------*/
+(define-markup (~ #!rest opts #!key (class #f))
+ (new markup
+ (markup '~)
+ (ident (symbol->string (gensym "~")))
+ (class class)
+ (required-options '())
+ (options (the-options opts :class))
+ (body (the-body opts))))
+
+;*---------------------------------------------------------------------*/
+;* footnote ... */
+;*---------------------------------------------------------------------*/
+(define-markup (footnote #!rest opts
+ #!key (ident #f) (class "footnote") (label #t))
+ ;; The `:label' option used to be called `:number'.
+ (new container
+ (markup 'footnote)
+ (ident (symbol->string (gensym "footnote")))
+ (class class)
+ (required-options '())
+ (options `((:label
+ ,(cond ((string? label) label)
+ ((number? label) label)
+ ((not label) label)
+ (else
+ (new unresolved
+ (proc (lambda (n e env)
+ (resolve-counter n env
+ 'footnote #t))))))
+ ,@(the-options opts :ident :class))))
+ (body (the-body opts))))
+
+;*---------------------------------------------------------------------*/
+;* linebreak ... */
+;*---------------------------------------------------------------------*/
+(define-markup (linebreak #!rest opts #!key (ident #f) (class #f))
+ (let ((ln (new markup
+ (ident (or ident (symbol->string (gensym "linebreak"))))
+ (class class)
+ (markup 'linebreak)))
+ (num (the-body opts)))
+ (cond
+ ((null? num)
+ ln)
+ ((not (null? (cdr num)))
+ (skribe-error 'linebreak "Illegal arguments" num))
+ ((not (and (integer? (car num)) (positive? (car num))))
+ (skribe-error 'linebreak "Illegal argument" (car num)))
+ (else
+ (vector->list (make-vector (car num) ln))))))
+
+;*---------------------------------------------------------------------*/
+;* hrule ... */
+;*---------------------------------------------------------------------*/
+(define-markup (hrule #!rest
+ opts
+ #!key
+ (ident #f) (class #f)
+ (width 100.) (height 1))
+ (new markup
+ (markup 'hrule)
+ (ident (or ident (symbol->string (gensym "hrule"))))
+ (class class)
+ (required-options '())
+ (options `((:width ,width)
+ (:height ,height)
+ ,@(the-options opts :ident :class)))
+ (body #f)))
+
+;*---------------------------------------------------------------------*/
+;* color ... */
+;*---------------------------------------------------------------------*/
+(define-markup (color #!rest
+ opts
+ #!key
+ (ident #f) (class "color")
+ (bg #f) (fg #f) (width #f) (margin #f))
+ (new container
+ (markup 'color)
+ (ident (or ident (symbol->string (gensym "color"))))
+ (class class)
+ (required-options '(:bg :fg :width))
+ (options `((:bg ,(if bg (skribe-use-color! bg) bg))
+ (:fg ,(if fg (skribe-use-color! fg) fg))
+ ,@(the-options opts :ident :class :bg :fg)))
+ (body (the-body opts))))
+
+;*---------------------------------------------------------------------*/
+;* frame ... */
+;*---------------------------------------------------------------------*/
+(define-markup (frame #!rest
+ opts
+ #!key
+ (ident #f) (class "frame")
+ (width #f) (margin 2) (border 1))
+ (new container
+ (markup 'frame)
+ (ident (or ident (symbol->string (gensym "frame"))))
+ (class class)
+ (required-options '(:width :border :margin))
+ (options `((:margin ,margin)
+ (:border ,(cond
+ ((integer? border) border)
+ (border 1)
+ (else #f)))
+ ,@(the-options opts :ident :class)))
+ (body (the-body opts))))
+
+;*---------------------------------------------------------------------*/
+;* font ... */
+;*---------------------------------------------------------------------*/
+(define-markup (font #!rest
+ opts
+ #!key
+ (ident #f) (class #f)
+ (size #f) (face #f))
+ (new container
+ (markup 'font)
+ (ident (or ident (symbol->string (gensym "font"))))
+ (class class)
+ (required-options '(:size))
+ (options (the-options opts :ident :class))
+ (body (the-body opts))))
+
+;*---------------------------------------------------------------------*/
+;* flush ... */
+;*---------------------------------------------------------------------*/
+(define-markup (flush #!rest
+ opts
+ #!key
+ (ident #f) (class #f)
+ side)
+ (case side
+ ((center left right)
+ (new container
+ (markup 'flush)
+ (ident (or ident (symbol->string (gensym "flush"))))
+ (class class)
+ (required-options '(:side))
+ (options (the-options opts :ident :class))
+ (body (the-body opts))))
+ (else
+ (skribe-error 'flush "Illegal side" side))))
+
+;*---------------------------------------------------------------------*/
+;* center ... */
+;*---------------------------------------------------------------------*/
+(define-simple-container center)
+
+;*---------------------------------------------------------------------*/
+;* pre ... */
+;*---------------------------------------------------------------------*/
+(define-simple-container pre)
+
+;*---------------------------------------------------------------------*/
+;* prog ... */
+;* ------------------------------------------------------------- */
+;* doc: */
+;* @ref ../../doc/user/prgm.skb:prog@ */
+;* writer: */
+;* html: @ref ../../skr/html.skr:prog@ */
+;*---------------------------------------------------------------------*/
+(define-markup (prog #!rest
+ opts
+ #!key
+ (ident #f) (class "prog")
+ (line 1) (linedigit #f) (mark ";!"))
+ (if (not (or (string? mark) (eq? mark #f)))
+ (skribe-error 'prog "Illegal mark" mark)
+ (new container
+ (markup 'prog)
+ (ident (or ident (symbol->string (gensym "prog"))))
+ (class class)
+ (required-options '(:line :mark))
+ (options (the-options opts :ident :class :linedigit))
+ (body (make-prog-body (the-body opts) line linedigit mark)))))
+
+;*---------------------------------------------------------------------*/
+;* source ... */
+;* ------------------------------------------------------------- */
+;* doc: */
+;* @ref ../../doc/user/prgm.skb:source@ */
+;* writer: */
+;* html: @ref ../../skr/html.skr:source@ */
+;*---------------------------------------------------------------------*/
+(define-markup (source #!rest
+ opts
+ #!key
+ language
+ (file #f) (start #f) (stop #f)
+ (definition #f) (tab 8))
+ (let ((body (the-body opts)))
+ (cond
+ ((and (not (null? body)) (or file start stop definition))
+ (skribe-error 'source
+ "file, start/stop, and definition are exclusive with body"
+ body))
+ ((and start stop definition)
+ (skribe-error 'source
+ "start/stop are exclusive with a definition"
+ body))
+ ((and (or start stop definition) (not file))
+ (skribe-error 'source
+ "start/stop and definition require a file specification"
+ file))
+ ((and definition (not language))
+ (skribe-error 'source
+ "definition requires a language specification"
+ definition))
+ ((and file (not (string? file)))
+ (skribe-error 'source "Illegal file" file))
+ ((and start (not (or (integer? start) (string? start))))
+ (skribe-error 'source "Illegal start" start))
+ ((and stop (not (or (integer? stop) (string? stop))))
+ (skribe-error 'source "Illegal start" stop))
+ ((and (integer? start) (integer? stop) (> start stop))
+ (skribe-error 'source
+ "start line > stop line"
+ (format #f "~a/~a" start stop)))
+ ((and language (not (language? language)))
+ (skribe-error 'source "illegal language" language))
+ ((and tab (not (integer? tab)))
+ (skribe-error 'source "illegal tab" tab))
+ (file
+ (let ((s (if (not definition)
+ (source-read-lines file start stop tab)
+ (source-read-definition file definition tab language))))
+ (if language
+ (source-fontify s language)
+ s)))
+ (language
+ (source-fontify body language))
+ (else
+ body))))
+
+;*---------------------------------------------------------------------*/
+;* language ... */
+;* ------------------------------------------------------------- */
+;* doc: */
+;* @ref ../../doc/user/prgm.skb:language@ */
+;*---------------------------------------------------------------------*/
+(define-markup (language #!key name (fontifier #f) (extractor #f))
+ (if (not (string? name))
+ (skribe-type-error 'language "illegal name" name "string")
+ (new language
+ (name name)
+ (fontifier fontifier)
+ (extractor extractor))))
+
+;*---------------------------------------------------------------------*/
+;* figure ... */
+;* ------------------------------------------------------------- */
+;* doc: */
+;* @ref ../../doc/user/figure.skb:figure@ */
+;* writer: */
+;* html: @ref ../../skr/html.skr:figure@ */
+;*---------------------------------------------------------------------*/
+(define-markup (figure #!rest
+ opts
+ #!key
+ (ident #f) (class "figure")
+ (legend #f) (number #t) (multicolumns #f))
+ (new container
+ (markup 'figure)
+ (ident (or ident
+ (let ((s (ast->string legend)))
+ (if (not (string=? s ""))
+ s
+ (symbol->string (gensym "figure"))))))
+ (class class)
+ (required-options '(:legend :number :multicolumns))
+ (options `((:number
+ ,(new unresolved
+ (proc (lambda (n e env)
+ (resolve-counter n env 'figure number)))))
+ ,@(the-options opts :ident :class)))
+ (body (the-body opts))))
+
+;*---------------------------------------------------------------------*/
+;* parse-list-of ... */
+;* ------------------------------------------------------------- */
+;* The function table accepts two different prototypes. It */
+;* may receive its N elements in a list of N elements or in */
+;* a list of one element which is a list of N elements. This */
+;* gets rid of APPLY when calling container markup such as ITEMIZE */
+;* or TABLE. */
+;*---------------------------------------------------------------------*/
+(define (parse-list-of for markup lst)
+ (cond
+ ((null? lst)
+ '())
+ ((and (pair? lst)
+ (or (pair? (car lst)) (null? (car lst)))
+ (null? (cdr lst)))
+ (parse-list-of for markup (car lst)))
+ (else
+ (let loop ((lst lst)
+ (result '()))
+ (cond
+ ((null? lst)
+ (reverse! result))
+ ((pair? (car lst))
+ (loop (car lst) result))
+ (else
+ (let ((r (car lst)))
+ (if (not (is-markup? r markup))
+ (skribe-warning 2
+ for
+ (format #f "illegal `~a' element, `~a' expected"
+ (if (markup? r)
+ (markup-markup r)
+ (type-name r))
+ markup)))
+ (loop (cdr lst) (cons r result)))))))))
+
+;*---------------------------------------------------------------------*/
+;* itemize ... */
+;*---------------------------------------------------------------------*/
+(define-markup (itemize #!rest opts #!key (ident #f) (class "itemize") symbol)
+ (new container
+ (markup 'itemize)
+ (ident (or ident (symbol->string (gensym "itemize"))))
+ (class class)
+ (required-options '(:symbol))
+ (options `((:symbol ,symbol) ,@(the-options opts :ident :class)))
+ (body (parse-list-of 'itemize 'item (the-body opts)))))
+
+;*---------------------------------------------------------------------*/
+;* enumerate ... */
+;*---------------------------------------------------------------------*/
+(define-markup (enumerate #!rest opts #!key (ident #f) (class "enumerate") symbol)
+ (new container
+ (markup 'enumerate)
+ (ident (or ident (symbol->string (gensym "enumerate"))))
+ (class class)
+ (required-options '(:symbol))
+ (options `((:symbol ,symbol) ,@(the-options opts :ident :class)))
+ (body (parse-list-of 'enumerate 'item (the-body opts)))))
+
+;*---------------------------------------------------------------------*/
+;* description ... */
+;*---------------------------------------------------------------------*/
+(define-markup (description #!rest opts #!key (ident #f) (class "description") symbol)
+ (new container
+ (markup 'description)
+ (ident (or ident (symbol->string (gensym "description"))))
+ (class class)
+ (required-options '(:symbol))
+ (options `((:symbol ,symbol) ,@(the-options opts :ident :class)))
+ (body (parse-list-of 'description 'item (the-body opts)))))
+
+;*---------------------------------------------------------------------*/
+;* item ... */
+;*---------------------------------------------------------------------*/
+(define-markup (item #!rest opts #!key (ident #f) (class #f) key)
+ (if (and key (not (or (string? key)
+ (number? key)
+ (markup? key)
+ (pair? key))))
+ (skribe-type-error 'item "Illegal key:" key "node")
+ (new container
+ (markup 'item)
+ (ident (or ident (symbol->string (gensym "item"))))
+ (class class)
+ (required-options '(:key))
+ (options `((:key ,key) ,@(the-options opts :ident :class :key)))
+ (body (the-body opts)))))
+
+;*---------------------------------------------------------------------*/
+;* table */
+;*---------------------------------------------------------------------*/
+(define-markup (table #!rest
+ opts
+ #!key
+ (ident #f) (class #f)
+ (border #f) (width #f)
+ (frame 'none) (rules 'none)
+ (cellstyle 'collapse) (cellpadding #f) (cellspacing #f))
+ (let ((frame (cond
+ ((string? frame)
+ (string->symbol frame))
+ ((not frame)
+ #f)
+ (else
+ frame)))
+ (rules (cond
+ ((string? rules)
+ (string->symbol rules))
+ ((not rules)
+ #f)
+ (else
+ rules)))
+ (frame-vals '(none above below hsides vsides lhs rhs box border))
+ (rules-vals '(none rows cols all header))
+ (cells-vals '(collapse separate)))
+ (cond
+ ((and frame (not (memq frame frame-vals)))
+ (skribe-error 'table
+ (format #f "frame should be one of \"~a\"" frame-vals)
+ frame))
+ ((and rules (not (memq rules rules-vals)))
+ (skribe-error 'table
+ (format #f "rules should be one of \"~a\"" rules-vals)
+ rules))
+ ((not (or (memq cellstyle cells-vals)
+ (string? cellstyle)
+ (number? cellstyle)))
+ (skribe-error 'table
+ (format #f "cellstyle should be one of \"~a\", or a number, or a string" cells-vals)
+ cellstyle))
+ (else
+ (new container
+ (markup 'table)
+ (ident (or ident (symbol->string (gensym "table"))))
+ (class class)
+ (required-options '(:width :frame :rules))
+ (options `((:frame ,frame)
+ (:rules ,rules)
+ (:cellstyle ,cellstyle)
+ ,@(the-options opts :ident :class)))
+ (body (parse-list-of 'table 'tr (the-body opts))))))))
+
+;*---------------------------------------------------------------------*/
+;* tr ... */
+;*---------------------------------------------------------------------*/
+(define-markup (tr #!rest opts #!key (ident #f) (class #f) (bg #f))
+ (new container
+ (markup 'tr)
+ (ident (or ident (symbol->string (gensym "tr"))))
+ (class class)
+ (required-options '())
+ (options `(,@(if bg `((:bg ,(if bg (skribe-use-color! bg) bg))) '())
+ ,@(the-options opts :ident :class :bg)))
+ (body (parse-list-of 'tr 'tc (the-body opts)))))
+
+;*---------------------------------------------------------------------*/
+;* tc... */
+;*---------------------------------------------------------------------*/
+(define-markup (tc m
+ #!rest
+ opts
+ #!key
+ (ident #f) (class #f)
+ (width #f) (align 'center) (valign #f)
+ (colspan 1) (rowspan 1) (bg #f))
+ (let ((align (if (string? align)
+ (string->symbol align)
+ align))
+ (valign (if (string? valign)
+ (string->symbol valign)
+ valign)))
+ (cond
+ ((not (integer? colspan))
+ (skribe-type-error 'tc "Illegal colspan, " colspan "integer"))
+ ((not (symbol? align))
+ (skribe-type-error 'tc "Illegal align, " align "align"))
+ ((not (memq align '(#f center left right)))
+ (skribe-error
+ 'tc
+ "align should be one of 'left', `center', or `right'"
+ align))
+ ((not (memq valign '(#f top middle center bottom)))
+ (skribe-error
+ 'tc
+ "valign should be one of 'top', `middle', `center', or `bottom'"
+ valign))
+ (else
+ (new container
+ (markup 'tc)
+ (ident (or ident (symbol->string (gensym "tc"))))
+ (class class)
+ (required-options '(:width :align :valign :colspan))
+ (options `((markup ,m)
+ (:align ,align)
+ (:valign ,valign)
+ (:colspan ,colspan)
+ ,@(if bg
+ `((:bg ,(if bg (skribe-use-color! bg) bg)))
+ '())
+ ,@(the-options opts :ident :class :bg :align :valign)))
+ (body (the-body opts)))))))
+
+;*---------------------------------------------------------------------*/
+;* th ... */
+;*---------------------------------------------------------------------*/
+(define-markup (th #!rest
+ opts
+ #!key
+ (ident #f) (class #f)
+ (width #f) (align 'center) (valign #f)
+ (colspan 1) (rowspan 1) (bg #f))
+ (apply tc 'th opts))
+
+;*---------------------------------------------------------------------*/
+;* td ... */
+;*---------------------------------------------------------------------*/
+(define-markup (td #!rest
+ opts
+ #!key
+ (ident #f) (class #f)
+ (width #f) (align 'center) (valign #f)
+ (colspan 1) (rowspan 1) (bg #f))
+ (apply tc 'td opts))
+
+;*---------------------------------------------------------------------*/
+;* image ... */
+;* ------------------------------------------------------------- */
+;* doc: */
+;* @ref ../../doc/user/image.skb:image@ */
+;* writer: */
+;* html: @ref ../../skr/html.skr:image@ */
+;* latex: @ref ../../skr/latex.skr:image@ */
+;*---------------------------------------------------------------------*/
+(define-markup (image #!rest
+ opts
+ #!key
+ (ident #f) (class #f)
+ file (url #f) (width #f) (height #f) (zoom #f))
+ (cond
+ ((not (or (string? file) (string? url)))
+ (skribe-error 'image "No file or url provided" file))
+ ((and (string? file) (string? url))
+ (skribe-error 'image "Both file and url provided" (list file url)))
+ (else
+ (new markup
+ (markup 'image)
+ (ident (or ident (symbol->string (gensym "image"))))
+ (class class)
+ (required-options '(:file :url :width :height))
+ (options (the-options opts :ident :class))
+ (body (the-body opts))))))
+
+;*---------------------------------------------------------------------*/
+;* blockquote */
+;*---------------------------------------------------------------------*/
+(define-simple-markup blockquote)
+
+;*---------------------------------------------------------------------*/
+;* Ornaments ... */
+;*---------------------------------------------------------------------*/
+(define-simple-markup roman)
+(define-simple-markup bold)
+(define-simple-markup underline)
+(define-simple-markup strike)
+(define-simple-markup emph)
+(define-simple-markup kbd)
+(define-simple-markup it)
+(define-simple-markup tt)
+(define-simple-markup code)
+(define-simple-markup var)
+(define-simple-markup samp)
+(define-simple-markup sf)
+(define-simple-markup sc)
+(define-simple-markup sub)
+(define-simple-markup sup)
+
+;*---------------------------------------------------------------------*/
+;* char ... */
+;*---------------------------------------------------------------------*/
+(define-markup (char char)
+ (cond
+ ((char? char)
+ (string char))
+ ((integer? char)
+ (string (integer->char char)))
+ ((and (string? char) (= (string-length char) 1))
+ char)
+ (else
+ (skribe-error 'char "Illegal char" char))))
+
+;*---------------------------------------------------------------------*/
+;* symbol ... */
+;*---------------------------------------------------------------------*/
+(define-markup (symbol symbol)
+ (let ((v (cond
+ ((symbol? symbol)
+ (symbol->string symbol))
+ ((string? symbol)
+ symbol)
+ (else
+ (skribe-error 'symbol
+ "Illegal argument (symbol expected)"
+ symbol)))))
+ (new markup
+ (markup 'symbol)
+ (body v))))
+
+;*---------------------------------------------------------------------*/
+;* ! ... */
+;*---------------------------------------------------------------------*/
+(define-markup (! format #!rest node)
+ (if (not (string? format))
+ (skribe-type-error '! "Illegal format:" format "string")
+ (new command
+ (fmt format)
+ (body node))))
+
+;*---------------------------------------------------------------------*/
+;* processor ... */
+;*---------------------------------------------------------------------*/
+(define-markup (processor #!rest opts
+ #!key (combinator #f) (engine #f) (procedure #f))
+ (cond
+ ((and combinator (not (procedure? combinator)))
+ (skribe-error 'processor "Combinator not a procedure" combinator))
+ ((and engine (not (engine? engine)))
+ (skribe-error 'processor "Illegal engine" engine))
+ ((and procedure
+ (or (not (procedure? procedure))
+ (not (let ((a (procedure-property procedure 'arity)))
+ (and (pair? a)
+ (let ((compulsory (car a))
+ (optional (cadr a))
+ (rest? (caddr a)))
+ (or rest?
+ (>= (+ compulsory optional) 2))))))))
+ (skribe-error 'processor "Illegal procedure" procedure))
+ (else
+ (new processor
+ (combinator combinator)
+ (engine engine)
+ (procedure (or procedure (lambda (n e) n)))
+ (body (the-body opts))))))
+
+;*---------------------------------------------------------------------*/
+;* Processors ... */
+;*---------------------------------------------------------------------*/
+(define-processor-markup html-processor)
+(define-processor-markup tex-processor)
+
+;*---------------------------------------------------------------------*/
+;* handle ... */
+;*---------------------------------------------------------------------*/
+(define-markup (handle #!rest opts
+ #!key (ident #f) (class "handle") value section)
+ (let ((body (the-body opts)))
+ (cond
+ (section
+ (error 'handle "Illegal handle `section' option" section)
+ (new unresolved
+ (proc (lambda (n e env)
+ (let ((s (resolve-ident section 'section n env)))
+ (new handle
+ (ast s)))))))
+ ((and (pair? body)
+ (null? (cdr body))
+ (markup? (car body)))
+ (new handle
+ (ast (car body))))
+ (else
+ (skribe-error 'handle "Illegal handle" opts)))))
+
+;*---------------------------------------------------------------------*/
+;* mailto ... */
+;* ------------------------------------------------------------- */
+;* doc: */
+;* @ref ../../doc/user/links.skb:mailto@ */
+;* writer: */
+;* html: @ref ../../skr/html.skr:mailto@ */
+;*---------------------------------------------------------------------*/
+(define-markup (mailto #!rest opts #!key (ident #f) (class "mailto") text)
+ (new markup
+ (markup 'mailto)
+ (ident (or ident (symbol->string (gensym "ident"))))
+ (class class)
+ (required-options '(:text))
+ (options (the-options opts :ident :class))
+ (body (the-body opts))))
+
+;*---------------------------------------------------------------------*/
+;* *mark-table* ... */
+;*---------------------------------------------------------------------*/
+(define *mark-table* (make-hash-table))
+
+;*---------------------------------------------------------------------*/
+;* mark ... */
+;* ------------------------------------------------------------- */
+;* doc: */
+;* @ref ../../doc/user/links.skb:mark@ */
+;* writer: */
+;* html: @ref ../../skr/html.skr:mark@ */
+;*---------------------------------------------------------------------*/
+(define-markup (mark #!rest opts #!key (ident #f) (class "mark") (text #f))
+ (let ((bd (the-body opts)))
+ (cond
+ ((and (pair? bd) (not (null? (cdr bd))))
+ (skribe-error 'mark "Too many argument provided" bd))
+ ((null? bd)
+ (skribe-error 'mark "Missing argument" '()))
+ ((not (string? (car bd)))
+ (skribe-type-error 'mark "Illegal ident:" (car bd) "string"))
+ (ident
+ (skribe-error 'mark "Illegal `ident:' option" ident))
+ (else
+ (let* ((bs (ast->string bd))
+ (n (new markup
+ (markup 'mark)
+ (ident (symbol->string (gensym bs)))
+ (class class)
+ (options (the-options opts :ident :class :text))
+ (body text))))
+ (hash-set! *mark-table* bs n)
+ n)))))
+
+;*---------------------------------------------------------------------*/
+;* ref ... */
+;* ------------------------------------------------------------- */
+;* doc: */
+;* @ref ../../doc/user/links.skb:ref@ */
+;* writer: */
+;* html: @ref ../../skr/html.skr:ref@ */
+;* latex: @ref ../../skr/latex.skr:ref@ */
+;*---------------------------------------------------------------------*/
+(define-markup (ref #!rest
+ opts
+ #!key
+ (class #f)
+ (ident #f)
+ (text #f)
+ (chapter #f)
+ (section #f)
+ (subsection #f)
+ (subsubsection #f)
+ (bib #f)
+ (bib-table (default-bib-table))
+ (url #f)
+ (figure #f)
+ (mark #f)
+ (handle #f)
+ (line #f)
+ (skribe #f)
+ (page #f))
+ (define (unref ast text kind)
+ (let ((msg (format #f "can't find `~a': " kind)))
+ (if (ast? ast)
+ (begin
+ (skribe-warning/ast 1 ast 'ref msg text)
+ (new markup
+ (markup 'unref)
+ (ident (symbol->string (gensym "unref")))
+ (class class)
+ (required-options '(:text))
+ (options `((kind ,kind) ,@(the-options opts :ident :class)))
+ (body (list text ": " (ast->file-location ast)))))
+ (begin
+ (skribe-warning 1 'ref msg text)
+ (new markup
+ (markup 'unref)
+ (ident (symbol->string (gensym "unref")))
+ (class class)
+ (required-options '(:text))
+ (options `((kind ,kind) ,@(the-options opts :ident :class)))
+ (body text))))))
+ (define (skribe-ref skribe)
+ (let ((path (find-file/path skribe (skribe-path))))
+ (if (not path)
+ (unref #f skribe 'sui-file)
+ (let* ((sui (load-sui path))
+ (os (the-options opts :skribe :class :text))
+ (u (sui-ref->url (dirname path) sui ident os)))
+ (if (not u)
+ (unref #f os 'sui-ref)
+ (ref :url u :text text :ident ident :class class))))))
+ (define (handle-ref text)
+ (new markup
+ (markup 'ref)
+ (ident (symbol->string (gensym "handle-ref")))
+ (class class)
+ (required-options '(:text))
+ (options `((kind handle) ,@(the-options opts :ident :class)))
+ (body text)))
+ (define (do-title-ref title kind)
+ (if (not (string? title))
+ (skribe-type-error 'ref "illegal reference" title "string")
+ (new unresolved
+ (proc (lambda (n e env)
+ (let* ((doc (ast-document n))
+ (s (find1-down
+ (lambda (n)
+ (and (is-markup? n kind)
+ (equal? (markup-option n :title)
+ title)))
+ doc)))
+ (if s
+ (new markup
+ (markup 'ref)
+ (ident (symbol->string (gensym "title-ref")))
+ (class class)
+ (required-options '(:text))
+ (options `((kind ,kind)
+ (mark ,title)
+ ,@(the-options opts :ident :class)))
+ (body (new handle
+ (ast s))))
+ (unref n title (or kind 'title)))))))))
+ (define (do-ident-ref text kind)
+ (if (not (string? text))
+ (skribe-type-error 'ref "Illegal reference" text "string")
+ (new unresolved
+ (proc (lambda (n e env)
+ (let ((s (resolve-ident text kind n env)))
+ (if s
+ (new markup
+ (markup 'ref)
+ (ident (symbol->string (gensym "ident-ref")))
+ (class class)
+ (required-options '(:text))
+ (options `((kind ,kind)
+ (mark ,text)
+ ,@(the-options opts :ident :class)))
+ (body (new handle
+ (ast s))))
+ (unref n text (or kind 'ident)))))))))
+ (define (mark-ref mark)
+ (if (not (string? mark))
+ (skribe-type-error 'mark "Illegal mark, " mark "string")
+ (new unresolved
+ (proc (lambda (n e env)
+ (let ((s (hash-ref *mark-table* mark)))
+ (if s
+ (new markup
+ (markup 'ref)
+ (ident (symbol->string (gensym "mark-ref")))
+ (class class)
+ (required-options '(:text))
+ (options `((kind mark)
+ (mark ,mark)
+ ,@(the-options opts :ident :class)))
+ (body (new handle
+ (ast s))))
+ (unref n mark 'mark))))))))
+ (define (make-bib-ref v)
+ (let ((s (resolve-bib bib-table v)))
+ (if s
+ (let* ((n (new markup
+ (markup 'bib-ref)
+ (ident (symbol->string (gensym "bib-ref")))
+ (class class)
+ (required-options '(:text))
+ (options (the-options opts :ident :class))
+ (body (new handle
+ (ast s)))))
+ (h (new handle (ast n)))
+ (o (markup-option s 'used)))
+ (markup-option-add! s 'used (if (pair? o) (cons h o) (list h)))
+ n)
+ (unref #f v 'bib)))) ; FIXME: This prevents source location
+ ; info to be provided in the warning msg
+ (define (bib-ref text)
+ (if (pair? text)
+ (new markup
+ (markup 'bib-ref+)
+ (ident (symbol->string (gensym "bib-ref+")))
+ (class class)
+ (options (the-options opts :ident :class))
+ (body (map make-bib-ref text)))
+ (make-bib-ref text)))
+ (define (url-ref)
+ (new markup
+ (markup 'url-ref)
+ (ident (symbol->string (gensym "url-ref")))
+ (class class)
+ (required-options '(:url :text))
+ (options (the-options opts :ident :class))))
+ (define (line-ref line)
+ (new unresolved
+ (proc (lambda (n e env)
+ (let ((l (resolve-line line)))
+ (if (pair? l)
+ (new markup
+ (markup 'line-ref)
+ (ident (symbol->string (gensym "line-ref")))
+ (class class)
+ (options `((:text ,(markup-ident (car l)))
+ ,@(the-options opts :ident :class)))
+ (body (new handle
+ (ast (car l)))))
+ (unref n line 'line)))))))
+ (let ((b (the-body opts)))
+ (if (not (null? b))
+ (skribe-warning 1 'ref "Arguments ignored " b))
+ (cond
+ (skribe (skribe-ref skribe))
+ (handle (handle-ref handle))
+ (ident (do-ident-ref ident #f))
+ (chapter (do-title-ref chapter 'chapter))
+ (section (do-title-ref section 'section))
+ (subsection (do-title-ref subsection 'subsection))
+ (subsubsection (do-title-ref subsubsection 'subsubsection))
+ (figure (do-ident-ref figure 'figure))
+ (mark (mark-ref mark))
+ (bib (bib-ref bib))
+ (url (url-ref))
+ (line (line-ref line))
+ (else (skribe-error 'ref "illegal reference" opts)))))
+
+;*---------------------------------------------------------------------*/
+;* resolve ... */
+;*---------------------------------------------------------------------*/
+(define-markup (resolve fun)
+ (new unresolved
+ (proc fun)))
+
+;*---------------------------------------------------------------------*/
+;* bibliography ... */
+;* ------------------------------------------------------------- */
+;* doc: */
+;* @ref ../../doc/user/bib.skb:bibliography@ */
+;*---------------------------------------------------------------------*/
+(define-markup (bibliography #!rest files
+ #!key
+ (command #f) (bib-table (default-bib-table)))
+ (for-each (lambda (f)
+ (cond
+ ((string? f)
+ (bib-load! bib-table f command))
+ ((pair? f)
+ (bib-add! bib-table f))
+ (else
+ (skribe-error "bibliography" "Illegal entry" f))))
+ (the-body files)))
+
+;*---------------------------------------------------------------------*/
+;* the-bibliography ... */
+;* ------------------------------------------------------------- */
+;* doc: */
+;* @ref ../../doc/user/bib.skb:the-bibliography@ */
+;* writer: */
+;* base: @ref ../../skr/base.skr:the-bibliography@ */
+;*---------------------------------------------------------------------*/
+(define-markup (the-bibliography #!rest opts
+ #!key
+ pred
+ (bib-table (default-bib-table))
+ (sort bib-sort/authors)
+ (count 'partial))
+ (if (not (memq count '(partial full)))
+ (skribe-error 'the-bibliography
+ "Cound must be either `partial' or `full'"
+ count)
+ (new unresolved
+ (proc (lambda (n e env)
+ (resolve-the-bib bib-table
+ (new handle (ast n))
+ sort
+ pred
+ count
+ (the-options opts)))))))
+
+;*---------------------------------------------------------------------*/
+;* make-index ... */
+;* ------------------------------------------------------------- */
+;* doc: */
+;* @ref ../../doc/user/index.skb:make-index@ */
+;*---------------------------------------------------------------------*/
+(define-markup (make-index ident)
+ (make-index-table ident))
+
+;*---------------------------------------------------------------------*/
+;* index ... */
+;* ------------------------------------------------------------- */
+;* doc: */
+;* @ref ../../doc/user/index.skb:index@ */
+;*---------------------------------------------------------------------*/
+(define-markup (index #!rest
+ opts
+ #!key
+ (ident #f) (class "index")
+ (note #f) (index #f) (shape #f)
+ (url #f))
+ (let* ((entry-name (the-body opts))
+ (ename (cond
+ ((string? entry-name)
+ entry-name)
+ ((and (pair? entry-name) (every string? entry-name))
+ (apply string-append entry-name))
+ (else
+ (skribe-error
+ 'index
+ "entry-name must be either a string or a list of strings"
+ entry-name))))
+ (table (cond
+ ((not index) (default-index))
+ ((index? index) index)
+ (else (skribe-type-error 'index
+ "Illegal index table, "
+ index
+ "index"))))
+ (m (mark (symbol->string (gensym "mark"))))
+ (h (new handle (ast m)))
+ (new (new markup
+ (markup '&index-entry)
+ (ident (or ident (symbol->string (gensym "index"))))
+ (class class)
+ (options `((name ,ename) ,@(the-options opts :ident :class)))
+ (body (if url
+ (ref :url url :text (or shape ename))
+ (ref :handle h :text (or shape ename)))))))
+ ;; New is bound to a dummy option of the mark in order
+ ;; to make new options verified.
+ (markup-option-add! m 'to-verify new)
+
+ (let ((handle (hash-get-handle table ename)))
+ (if (not handle)
+ (hash-set! table ename (list new))
+ (set-cdr! handle (cons new (cdr handle)))))
+
+ m))
+
+;*---------------------------------------------------------------------*/
+;* the-index ... */
+;* ------------------------------------------------------------- */
+;* doc: */
+;* @ref ../../doc/user/index.skb:the-index@ */
+;* writer: */
+;* base: @ref ../../skr/base.skr:the-index@ */
+;* html: @ref ../../skr/html.skr:the-index-header@ */
+;*---------------------------------------------------------------------*/
+(define-markup (the-index #!rest
+ opts
+ #!key
+ (ident #f)
+ (class "the-index")
+ (split #f)
+ (char-offset 0)
+ (header-limit 50)
+ (column 1))
+ (let ((bd (the-body opts)))
+ (cond
+ ((not (and (integer? char-offset) (>= char-offset 0)))
+ (skribe-error 'the-index "Illegal char offset" char-offset))
+ ((not (integer? column))
+ (skribe-error 'the-index "Illegal column number" column))
+ ((not (every index? bd))
+ (skribe-error 'the-index
+ "Illegal indexes"
+ (filter (lambda (o) (not (index? o))) bd)))
+ (else
+ (new unresolved
+ (proc (lambda (n e env)
+ (resolve-the-index (ast-loc n)
+ ident class
+ bd
+ split
+ char-offset
+ header-limit
+ column))))))))
+
+
+;;; This part comes from the file `skribe.skr' in the original Skribe
+;;; distribution.
+
+;*---------------------------------------------------------------------*/
+;* p ... */
+;*---------------------------------------------------------------------*/
+(define-markup (p #!rest opt #!key ident (class #f) &skribe-eval-location)
+ (paragraph :ident ident :class class :loc &skribe-eval-location
+ (the-body opt)))
+
+;*---------------------------------------------------------------------*/
+;* fg ... */
+;*---------------------------------------------------------------------*/
+(define-public (fg c . body)
+ (color :fg c body))
+
+;*---------------------------------------------------------------------*/
+;* bg ... */
+;*---------------------------------------------------------------------*/
+(define-public (bg c . body)
+ (color :bg c body))
+
+;*---------------------------------------------------------------------*/
+;* counter ... */
+;* ------------------------------------------------------------- */
+;* This produces a kind of "local enumeration" that is: */
+;* (counting "toto," "tutu," "titi.") */
+;* produces: */
+;* i) toto, ii) tutu, iii) titi. */
+;*---------------------------------------------------------------------*/
+(define-markup (counter #!rest opts #!key (numbering 'roman))
+ (define items (if (eq? (car opts) :numbering) (cddr opts) opts))
+ (define vroman #(- "i" "ii" "iii" "iv" "v" "vi" "vii" "viii" "ix" "x"))
+ (define (the-roman-number num)
+ (if (< num (vector-length vroman))
+ (list (list "(" (it (vector-ref vroman num)) ") "))
+ (skribe-error 'counter
+ "too many items for roman numbering"
+ (length items))))
+ (define (the-arabic-number num)
+ (list (list "(" (it (integer->string num)) ") ")))
+ (define (the-alpha-number num)
+ (list (list "(" (it (+ (integer->char #\a) num -1)) ") ")))
+ (let ((the-number (case numbering
+ ((roman) the-roman-number)
+ ((arabic) the-arabic-number)
+ ((alpha) the-alpha-number)
+ (else (skribe-error 'counter
+ "Illegal numbering"
+ numbering)))))
+ (let loop ((num 1)
+ (items items)
+ (res '()))
+ (if (null? items)
+ (reverse! res)
+ (loop (+ num 1)
+ (cdr items)
+ (cons (list (the-number num) (car items)) res))))))
+
+;*---------------------------------------------------------------------*/
+;* q */
+;*---------------------------------------------------------------------*/
+(define-markup (q #!rest opt)
+ (new markup
+ (markup 'q)
+ (options (the-options opt))
+ (body (the-body opt))))
+
diff --git a/src/guile/skribilo/package/eq.scm b/src/guile/skribilo/package/eq.scm
new file mode 100644
index 0000000..4f5020e
--- /dev/null
+++ b/src/guile/skribilo/package/eq.scm
@@ -0,0 +1,439 @@
+;;; eq.scm -- An equation formatting package.
+;;;
+;;; Copyright 2005, 2006 Ludovic Courtès <ludovic.courtes@laas.fr>
+;;;
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;; USA.
+
+(define-module (skribilo package eq)
+ :autoload (skribilo ast) (markup?)
+ :autoload (skribilo output) (output)
+ :use-module (skribilo writer)
+ :use-module (skribilo engine)
+ :use-module (skribilo lib)
+ :use-module (skribilo utils syntax)
+ :use-module (skribilo module)
+ :use-module (skribilo utils keywords) ;; `the-options', etc.
+ :autoload (skribilo package base) (it symbol sub sup)
+ :autoload (skribilo engine lout) (lout-illustration)
+ :use-module (ice-9 optargs))
+
+;;; Author: Ludovic Courtès
+;;;
+;;; Commentary:
+;;;
+;;; This package defines a set of markups for formatting equations. The user
+;;; may either use the standard Scheme prefix notation to represent
+;;; equations, or directly use the specific markups (which looks more
+;;; verbose).
+;;;
+;;; FIXME: This is incomplete.
+;;;
+;;; Code:
+
+(fluid-set! current-reader %skribilo-module-reader)
+
+
+
+;;;
+;;; Utilities.
+;;;
+
+(define %operators
+ '(/ * + - = != ~= < > <= >= sqrt expt sum product script
+ in notin apply))
+
+(define %symbols
+ ;; A set of symbols that are automatically recognized within an `eq' quoted
+ ;; list.
+ '(;; lower-case Greek
+ alpha beta gamma delta epsilon zeta eta theta iota kappa
+ lambda mu nu xi omicron pi rho sigma tau upsilon phi chi omega
+
+ ;; upper-case Greek
+ Alpha Beta Gamma Delta Epsilon Zeta Eta Theta Iota Kappa
+ Lambda Mu Nu Xi Omicron Pi Rho Sigma Tau Upsilon Phi Chi Omega
+
+ ;; Hebrew
+ alef
+
+ ;; mathematics
+ ellipsis weierp image real forall partial exists
+ emptyset infinity in notin nabla nipropto angle and or cap cup
+ sim cong approx neq equiv le ge subset supset subseteq supseteq
+ oplus otimes perp mid lceil rceil lfloor rfloor langle rangle))
+
+
+(define (make-fast-member-predicate lst)
+ (let ((h (make-hash-table)))
+ ;; initialize a hash table equivalent to LST
+ (for-each (lambda (s) (hashq-set! h s #t)) lst)
+
+ ;; the run-time, fast, definition
+ (lambda (sym)
+ (hashq-ref h sym #f))))
+
+(define-public known-operator? (make-fast-member-predicate %operators))
+(define-public known-symbol? (make-fast-member-predicate %symbols))
+
+(define-public equation-markup-name?
+ (make-fast-member-predicate (map (lambda (s)
+ (symbol-append 'eq: s))
+ %operators)))
+
+(define-public (equation-markup? m)
+ "Return true if @var{m} is an instance of one of the equation sub-markups."
+ (and (markup? m)
+ (equation-markup-name? (markup-markup m))))
+
+(define-public (equation-markup-name->operator m)
+ "Given symbol @var{m} (an equation markup name, e.g., @code{eq:+}), return
+a symbol representing the mathematical operator denoted by @var{m} (e.g.,
+@code{+})."
+ (if (equation-markup-name? m)
+ (string->symbol (let ((str (symbol->string m)))
+ (substring str
+ (+ 1 (string-index str #\:))
+ (string-length str))))
+ #f))
+
+
+;;;
+;;; Operator precedence.
+;;;
+
+(define %operator-precedence
+ ;; FIXME: This needs to be augmented.
+ '((+ . 1)
+ (- . 1)
+ (* . 2)
+ (/ . 2)
+ (sum . 3)
+ (product . 3)
+ (= . 0)
+ (< . 0)
+ (> . 0)
+ (<= . 0)
+ (>= . 0)))
+
+(define-public (operator-precedence op)
+ (let ((p (assq op %operator-precedence)))
+ (if (pair? p) (cdr p) 0)))
+
+
+
+;;;
+;;; Turning an S-exp into an `eq' markup.
+;;;
+
+(define %rebindings
+ (map (lambda (sym)
+ (list sym (symbol-append 'eq: sym)))
+ %operators))
+
+(define (eq:symbols->strings equation)
+ "Turn symbols located in non-@code{car} positions into strings."
+ (cond ((list? equation)
+ (if (or (null? equation) (null? (cdr equation)))
+ equation
+ (cons (car equation) ;; XXX: not tail-recursive
+ (map eq:symbols->strings (cdr equation)))))
+ ((symbol? equation)
+ (if (known-symbol? equation)
+ `(symbol ,(symbol->string equation))
+ (symbol->string equation)))
+ (else equation)))
+
+(define-public (eq-evaluate equation)
+ "Evaluate @var{equation}, an sexp (list) representing an equation, e.g.
+@code{'(+ a (/ b 3))}."
+ (eval `(let ,%rebindings ,(eq:symbols->strings equation))
+ (current-module)))
+
+
+
+;;;
+;;; Markup.
+;;;
+
+(define-markup (eq :rest opts :key (ident #f) (inline? #f)
+ (renderer #f) (class "eq"))
+ (new markup
+ (markup 'eq)
+ (ident (or ident (symbol->string (gensym "eq"))))
+ (options (the-options opts))
+ (body (let loop ((body (the-body opts))
+ (result '()))
+ (if (null? body)
+ result
+ (loop (cdr body)
+ (if (markup? (car body))
+ (car body) ;; the `eq:*' markups were used
+ ;; directly
+ (eq-evaluate (car body))) ;; a quoted list was
+ ;; passed
+ ))))))
+
+(define-simple-markup eq:/)
+(define-simple-markup eq:*)
+(define-simple-markup eq:+)
+(define-simple-markup eq:-)
+
+(define-simple-markup eq:=)
+(define-simple-markup eq:!=)
+(define-simple-markup eq:~=)
+(define-simple-markup eq:<)
+(define-simple-markup eq:>)
+(define-simple-markup eq:>=)
+(define-simple-markup eq:<=)
+
+(define-simple-markup eq:sqrt)
+(define-simple-markup eq:expt)
+
+(define-markup (eq:sum :rest opts :key (ident #f) (class "eq:sum")
+ (from #f) (to #f))
+ (new markup
+ (markup 'eq:sum)
+ (ident (or ident (symbol->string (gensym "eq:sum"))))
+ (options (the-options opts))
+ (body (the-body opts))))
+
+(define-markup (eq:product :rest opts :key (ident #f) (class "eq:product")
+ (from #f) (to #f))
+ (new markup
+ (markup 'eq:product)
+ (ident (or ident (symbol->string (gensym "eq:product"))))
+ (options (the-options opts))
+ (body (the-body opts))))
+
+(define-markup (eq:script :rest opts :key (ident #f) (class "eq:script")
+ (sub #f) (sup #f))
+ (new markup
+ (markup 'eq:script)
+ (ident (or ident (symbol->string (gensym "eq:script"))))
+ (options (the-options opts))
+ (body (the-body opts))))
+
+(define-simple-markup eq:in)
+(define-simple-markup eq:notin)
+
+(define-markup (eq:apply :rest opts :key (ident #f) (class "eq:apply"))
+ ;; This markup may receive either a list of arguments or arguments
+ ;; compatible with the real `apply'. Note: the real `apply' can take N
+ ;; non-list arguments but the last one has to be a list.
+ (new markup
+ (markup 'eq:apply)
+ (ident (or ident (symbol->string (gensym "eq:apply"))))
+ (options (the-options opts))
+ (body (let loop ((body (the-body opts))
+ (result '()))
+ (if (null? body)
+ (reverse! result)
+ (let ((first (car body)))
+ (if (list? first)
+ (if (null? (cdr body))
+ (append (reverse! result) first)
+ (skribe-error 'eq:apply
+ "wrong argument type"
+ body))
+ (loop (cdr body) (cons first result)))))))))
+
+
+
+;;;
+;;; Text-based rendering.
+;;;
+
+
+(markup-writer 'eq (find-engine 'base)
+ :action (lambda (node engine)
+ ;; The `:renderer' option should be a symbol (naming an engine
+ ;; class) or an engine or engine class. This allows the use of
+ ;; another engine to render equations. For instance, equations
+ ;; may be rendered using the Lout engine within an HTML
+ ;; document.
+ (let ((renderer (markup-option node :renderer)))
+ (cond ((not renderer) ;; default: use the current engine
+ (output (it (markup-body node)) engine))
+ ((symbol? renderer)
+ (case renderer
+ ;; FIXME: We should have an `embed' slot for each
+ ;; engine class similar to `lout-illustration'.
+ ((lout)
+ (let ((lout-code
+ (with-output-to-string
+ (lambda ()
+ (output node (find-engine 'lout))))))
+ (output (lout-illustration
+ :ident (markup-ident node)
+ lout-code)
+ engine)))
+ (else
+ (skribe-error 'eq "invalid renderer" renderer))))
+ ;; FIXME: `engine?' and `engine-class?'
+ (else
+ (skribe-error 'eq "`:renderer' -- wrong argument type"
+ renderer))))))
+
+(define-macro (simple-markup-writer op . obj)
+ ;; Note: The text-only rendering is less ambiguous if we parenthesize
+ ;; without taking operator precedence into account.
+ (let ((precedence (operator-precedence op)))
+ `(markup-writer ',(symbol-append 'eq: op) (find-engine 'base)
+ :action (lambda (node engine)
+ (let loop ((operands (markup-body node)))
+ (if (null? operands)
+ #t
+ (let* ((o (car operands))
+ (nested-eq? (equation-markup? o))
+ (need-paren?
+ (and nested-eq?
+; (< (operator-precedence
+; (equation-markup-name->operator
+; (markup-markup o)))
+; ,precedence)
+ )
+ ))
+
+ (display (if need-paren? "(" ""))
+ (output o engine)
+ (display (if need-paren? ")" ""))
+ (if (pair? (cdr operands))
+ (begin
+ (display " ")
+ (output ,(if (null? obj)
+ (symbol->string op)
+ (car obj))
+ engine)
+ (display " ")))
+ (loop (cdr operands)))))))))
+
+(simple-markup-writer +)
+(simple-markup-writer -)
+(simple-markup-writer /)
+(simple-markup-writer * (symbol "times"))
+
+(simple-markup-writer =)
+(simple-markup-writer != (symbol "neq"))
+(simple-markup-writer ~= (symbol "approx"))
+(simple-markup-writer <)
+(simple-markup-writer >)
+(simple-markup-writer >= (symbol "ge"))
+(simple-markup-writer <= (symbol "le"))
+
+(markup-writer 'eq:sqrt (find-engine 'base)
+ :action (lambda (node engine)
+ (display "sqrt(")
+ (output (markup-body node) engine)
+ (display ")")))
+
+(define-macro (simple-binary-markup-writer op obj)
+ `(markup-writer ',(symbol-append 'eq: op) (find-engine 'base)
+ :action (lambda (node engine)
+ (let ((body (markup-body node)))
+ (if (= (length body) 2)
+ (let ((first (car body))
+ (second (cadr body)))
+ (display (if (equation-markup? first) "(" " "))
+ (output first engine)
+ (display (if (equation-markup? first) ")" " "))
+ (output ,obj engine)
+ (display (if (equation-markup? second) "(" ""))
+ (output second engine)
+ (display (if (equation-markup? second) ")" "")))
+ (skribe-error ',(symbol-append 'eq: op)
+ "wrong argument type"
+ body))))))
+
+(markup-writer 'eq:expt (find-engine 'base)
+ :action (lambda (node engine)
+ (let ((body (markup-body node)))
+ (if (= (length body) 2)
+ (let ((first (car body))
+ (second (cadr body)))
+ (display (if (equation-markup? first) "(" ""))
+ (output first engine)
+ (display (if (equation-markup? first) ")" ""))
+ (output (sup second) engine))))))
+
+(simple-binary-markup-writer in (symbol "in"))
+(simple-binary-markup-writer notin (symbol "notin"))
+
+(markup-writer 'eq:apply (find-engine 'base)
+ :action (lambda (node engine)
+ (let ((func (car (markup-body node))))
+ (output func engine)
+ (display "(")
+ (let loop ((operands (cdr (markup-body node))))
+ (if (null? operands)
+ #t
+ (begin
+ (output (car operands) engine)
+ (if (not (null? (cdr operands)))
+ (display ", "))
+ (loop (cdr operands)))))
+ (display ")"))))
+
+(markup-writer 'eq:sum (find-engine 'base)
+ :action (lambda (node engine)
+ (let ((from (markup-option node :from))
+ (to (markup-option node :to)))
+ (output (symbol "Sigma") engine)
+ (display "(")
+ (output from engine)
+ (display ", ")
+ (output to engine)
+ (display ", ")
+ (output (markup-body node) engine)
+ (display ")"))))
+
+(markup-writer 'eq:prod (find-engine 'base)
+ :action (lambda (node engine)
+ (let ((from (markup-option node :from))
+ (to (markup-option node :to)))
+ (output (symbol "Pi") engine)
+ (display "(")
+ (output from engine)
+ (display ", ")
+ (output to engine)
+ (display ", ")
+ (output (markup-body node) engine)
+ (display ")"))))
+
+(markup-writer 'eq:script (find-engine 'base)
+ :action (lambda (node engine)
+ (let ((body (markup-body node))
+ (sup* (markup-option node :sup))
+ (sub* (markup-option node :sub)))
+ (output body engine)
+ (output (sup sup*) engine)
+ (output (sub sub*) engine))))
+
+
+
+
+;;;
+;;; Initialization.
+;;;
+
+(when-engine-is-loaded 'lout
+ (lambda ()
+ (resolve-module '(skribilo package eq lout))))
+
+
+;;; arch-tag: 58764650-2684-47a6-8cc7-6288f2b474da
+
+;;; eq.scm ends here
diff --git a/src/guile/skribilo/package/eq/Makefile.am b/src/guile/skribilo/package/eq/Makefile.am
new file mode 100644
index 0000000..c7b4f93
--- /dev/null
+++ b/src/guile/skribilo/package/eq/Makefile.am
@@ -0,0 +1,4 @@
+guilemoduledir = $(GUILE_SITE)/skribilo/package/eq
+dist_guilemodule_DATA = lout.scm
+
+## arch-tag: 3e816c9a-7989-4baa-b38b-a095a5428ba1
diff --git a/src/guile/skribilo/package/eq/lout.scm b/src/guile/skribilo/package/eq/lout.scm
new file mode 100644
index 0000000..c487b85
--- /dev/null
+++ b/src/guile/skribilo/package/eq/lout.scm
@@ -0,0 +1,217 @@
+;;; lout.scm -- Lout implementation of the `eq' package.
+;;;
+;;; Copyright 2005, 2006 Ludovic Courtès <ludovic.courtes@laas.fr>
+;;;
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;; USA.
+
+(define-module (skribilo package eq lout)
+ :use-module (skribilo package eq)
+ :use-module (skribilo ast)
+ :autoload (skribilo output) (output)
+ :use-module (skribilo writer)
+ :use-module (skribilo engine)
+ :use-module (skribilo lib)
+ :use-module (skribilo utils syntax)
+ :use-module (skribilo utils keywords) ;; `the-options', etc.
+ :use-module (ice-9 optargs))
+
+(fluid-set! current-reader %skribilo-module-reader)
+
+
+
+;;;
+;;; Initialization.
+;;;
+
+(let ((lout (find-engine 'lout)))
+ (if (not lout)
+ (skribe-error 'eq "Lout engine not found" lout)
+ (let ((includes (engine-custom lout 'includes)))
+ ;; Append the `eq' include file
+ (engine-custom-set! lout 'includes
+ (string-append includes "\n"
+ "@SysInclude { eq }\n")))))
+
+
+;;;
+;;; Simple markup writers.
+;;;
+
+
+(markup-writer 'eq (find-engine 'lout)
+ :options '(:inline?)
+ :before "{ "
+ :action (lambda (node engine)
+ (display (if (markup-option node :inline?)
+ "@E { "
+ "@Eq { "))
+ (let ((eq (markup-body node)))
+ ;;(fprint (current-error-port) "eq=" eq)
+ (output eq engine)))
+ :after " } }")
+
+
+
+(define-macro (simple-lout-markup-writer sym . args)
+ (let* ((lout-name (if (null? args)
+ (symbol->string sym)
+ (car args)))
+ (parentheses? (if (or (null? args) (null? (cdr args)))
+ #t
+ (cadr args)))
+ (precedence (operator-precedence sym))
+
+ ;; Note: We could use `pmatrix' here but it precludes line-breaking
+ ;; within equations.
+ (open-par `(if need-paren? "{ @VScale ( }" ""))
+ (close-par `(if need-paren? "{ @VScale ) }" "")))
+
+ `(markup-writer ',(symbol-append 'eq: sym)
+ (find-engine 'lout)
+ :action (lambda (node engine)
+ (let loop ((operands (markup-body node)))
+ (if (null? operands)
+ #t
+ (let* ((op (car operands))
+ (eq-op? (equation-markup? op))
+ (need-paren?
+ (and eq-op?
+ (< (operator-precedence
+ (equation-markup-name->operator
+ (markup-markup op)))
+ ,precedence)))
+ (column (port-column
+ (current-output-port))))
+
+ ;; Work around Lout's limitations...
+ (if (> column 1000) (display "\n"))
+
+ (display (string-append " { "
+ ,(if parentheses?
+ open-par
+ "")))
+ (output op engine)
+ (display (string-append ,(if parentheses?
+ close-par
+ "")
+ " }"))
+ (if (pair? (cdr operands))
+ (display ,(string-append " "
+ lout-name
+ " ")))
+ (loop (cdr operands)))))))))
+
+
+;; `+' and `*' have higher precedence than `-', `/', `=', etc., so their
+;; operands do not need to be enclosed in parentheses. OTOH, since we use a
+;; horizontal bar of `/', we don't need to parenthesize its arguments.
+
+
+(simple-lout-markup-writer +)
+(simple-lout-markup-writer * "times")
+(simple-lout-markup-writer - "-")
+(simple-lout-markup-writer / "over" #f)
+(simple-lout-markup-writer =)
+(simple-lout-markup-writer <)
+(simple-lout-markup-writer >)
+(simple-lout-markup-writer <=)
+(simple-lout-markup-writer >=)
+
+(define-macro (binary-lout-markup-writer sym lout-name)
+ `(markup-writer ',(symbol-append 'eq: sym) (find-engine 'lout)
+ :action (lambda (node engine)
+ (let ((body (markup-body node)))
+ (if (= (length body) 2)
+ (let* ((first (car body))
+ (second (cadr body))
+ (parentheses? (equation-markup? first)))
+ (display " { { ")
+ (if parentheses? (display "("))
+ (output first engine)
+ (if parentheses? (display ")"))
+ (display ,(string-append " } " lout-name " { "))
+ (output second engine)
+ (display " } } "))
+ (skribe-error ,(symbol-append 'eq: sym)
+ "wrong number of arguments"
+ body))))))
+
+(binary-lout-markup-writer expt "sup")
+(binary-lout-markup-writer in "element")
+(binary-lout-markup-writer notin "notelement")
+
+(markup-writer 'eq:apply (find-engine 'lout)
+ :action (lambda (node engine)
+ (let ((func (car (markup-body node))))
+ (output func engine)
+ (display "(")
+ (let loop ((operands (cdr (markup-body node))))
+ (if (null? operands)
+ #t
+ (begin
+ (output (car operands) engine)
+ (if (not (null? (cdr operands)))
+ (display ", "))
+ (loop (cdr operands)))))
+ (display ")"))))
+
+
+
+;;;
+;;; Sums, products, integrals, etc.
+;;;
+
+(define-macro (range-lout-markup-writer sym lout-name)
+ `(markup-writer ',(symbol-append 'eq: sym) (find-engine 'lout)
+ :action (lambda (node engine)
+ (let ((from (markup-option node :from))
+ (to (markup-option node :to))
+ (body (markup-body node)))
+ (display ,(string-append " { big " lout-name
+ " from { "))
+ (output from engine)
+ (display " } to { ")
+ (output to engine)
+ (display " } { ")
+ (output body engine)
+ (display " } } ")))))
+
+(range-lout-markup-writer sum "sum")
+(range-lout-markup-writer product "prod")
+
+(markup-writer 'eq:script (find-engine 'lout)
+ :action (lambda (node engine)
+ (let ((body (markup-body node))
+ (sup (markup-option node :sup))
+ (sub (markup-option node :sub)))
+ (display " { { ")
+ (output body engine)
+ (display " } ")
+ (if sup
+ (begin
+ (display (if sub " supp { " " sup { "))
+ (output sup engine)
+ (display " } ")))
+ (if sub
+ (begin
+ (display " on { ")
+ (output sub engine)
+ (display " } ")))
+ (display " } "))))
+
+
+;;; arch-tag: 2a1410e5-977e-4600-b781-3d57f4409b35
diff --git a/src/guile/skribilo/package/french.scm b/src/guile/skribilo/package/french.scm
new file mode 100644
index 0000000..a23d1da
--- /dev/null
+++ b/src/guile/skribilo/package/french.scm
@@ -0,0 +1,30 @@
+;;; french.scm -- French Skribe style
+;;;
+;;; Copyright 2003, 2004 Manuel Serrano
+;;;
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;; USA.
+
+(define-skribe-module (skribilo package french))
+
+;*---------------------------------------------------------------------*/
+;* LaTeX configuration */
+;*---------------------------------------------------------------------*/
+(let ((le (find-engine 'latex)))
+ (engine-custom-set! le 'usepackage
+ (string-append (engine-custom le 'usepackage)
+ "\\usepackage[french]{babel}
+\\usepackage{a4}")))
diff --git a/src/guile/skribilo/package/jfp.scm b/src/guile/skribilo/package/jfp.scm
new file mode 100644
index 0000000..913b3e3
--- /dev/null
+++ b/src/guile/skribilo/package/jfp.scm
@@ -0,0 +1,328 @@
+;;; jfp.scm -- The Skribe style for JFP articles.
+;;;
+;;; Copyright 2003, 2004 Manuel Serrano
+;;;
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;; USA.
+
+(define-skribe-module (skribilo package jfp))
+
+;*---------------------------------------------------------------------*/
+;* LaTeX global customizations */
+;*---------------------------------------------------------------------*/
+(let ((le (find-engine 'latex)))
+ (engine-custom-set! le 'documentclass "\\documentclass{jfp}")
+ (engine-custom-set! le 'hyperref #f)
+ ;; &latex-author
+ (markup-writer '&latex-author le
+ :action (lambda (n e)
+ (define (&latex-subauthor)
+ (let* ((d (ast-document n))
+ (sa (and (is-markup? d 'document)
+ (markup-option d :head-author))))
+ (if sa
+ (begin
+ (display "[")
+ (output sa e)
+ (display "]")))))
+ (define (&latex-author-1 n)
+ (display "\\author")
+ (&latex-subauthor)
+ (display "{\n")
+ (output n e)
+ (display "}\n"))
+ (define (&latex-author-n n)
+ (display "\\author")
+ (&latex-subauthor)
+ (display "{\n")
+ (output (car n) e)
+ (for-each (lambda (a)
+ (display "\\and ")
+ (output a e))
+ (cdr n))
+ (display "}\n"))
+ (let ((body (markup-body n)))
+ (cond
+ ((is-markup? body 'author)
+ (&latex-author-1 body))
+ ((and (list? body)
+ (every? (lambda (b) (is-markup? b 'author))
+ body))
+ (&latex-author-n body))
+ (else
+ (skribe-error 'author
+ "Illegal `jfp' author"
+ body))))))
+ ;; title
+ (markup-writer '&latex-title le
+ :before (lambda (n e)
+ (let* ((d (ast-document n))
+ (st (and (is-markup? d 'document)
+ (markup-option d :head-title))))
+ (if st
+ (begin
+ (display "\\title[")
+ (output st e)
+ (display "]{"))
+ (display "\\title{"))))
+ :after "}\n")
+ ;; author
+ (let ((old-author (markup-writer-get 'author le)))
+ (markup-writer 'author le
+ :options (writer-options old-author)
+ :action (lambda (n e)
+ (let ((name (markup-option n :name))
+ (aff (markup-option n :affiliation))
+ (addr (markup-option n :address))
+ (email (markup-option n :email)))
+ (if name
+ (begin
+ (output name e)
+ (display "\\\\\n")))
+ (if aff
+ (begin
+ (output aff e)
+ (display "\\\\\n")))
+ (if addr
+ (begin
+ (if (pair? addr)
+ (for-each (lambda (a)
+ (output a e)
+ (display "\\\\\n"))
+ addr)
+ (begin
+ (output addr e)
+ (display "\\\\\n")))))
+ (if email
+ (begin
+ (display "\\email{")
+ (output email e)
+ (display "}\\\\\n")))))))
+ ;; bib-ref
+ (markup-writer 'bib-ref le
+ :options '(:bib :text :key)
+ :before "("
+ :action (lambda (n e)
+ (let ((be (handle-ast (markup-body n))))
+ (if (is-markup? be '&bib-entry)
+ (let ((a (markup-option be 'author))
+ (y (markup-option be 'year)))
+ (cond
+ ((and (is-markup? a '&bib-entry-author)
+ (is-markup? y '&bib-entry-year))
+ (let ((ba (markup-body a)))
+ (if (not (string? ba))
+ (output ba e)
+ (let* ((s1 (pregexp-replace* " and "
+ ba
+ " \\& "))
+ (s2 (pregexp-replace* ", [^ ]+"
+ s1
+ "")))
+ (output s2 e)
+ (display ", ")
+ (output y e)))))
+ ((is-markup? y '&bib-entry-year)
+ (skribe-error 'bib-ref
+ "Missing `name' entry"
+ (markup-ident be)))
+ (else
+ (let ((ba (markup-body a)))
+ (if (not (string? ba))
+ (output ba e)
+ (let* ((s1 (pregexp-replace* " and "
+ ba
+ " \\& "))
+ (s2 (pregexp-replace* ", [^ ]+"
+ s1
+ "")))
+ (output s2 e)))))))
+ (skribe-error 'bib-ref
+ "Illegal bib-ref"
+ (markup-ident be)))))
+ :after ")")
+ ;; bib-ref/text
+ (markup-writer 'bib-ref le
+ :options '(:bib :text :key)
+ :predicate (lambda (n e)
+ (markup-option n :key))
+ :action (lambda (n e)
+ (output (markup-option n :key) e)))
+ ;; &the-bibliography
+ (markup-writer '&the-bibliography le
+ :before (lambda (n e)
+ (display "{%
+\\sloppy
+\\sfcode`\\.=1000\\relax
+\\newdimen\\bibindent
+\\bibindent=0em
+\\begin{list}{}{%
+ \\settowidth\\labelwidth{[]}%
+ \\leftmargin\\labelwidth
+ \\advance\\leftmargin\\labelsep
+ \\advance\\leftmargin\\bibindent
+ \\itemindent -\\bibindent
+ \\listparindent \\itemindent
+ }%\n"))
+ :after (lambda (n e)
+ (display "\n\\end{list}}\n")))
+ ;; bib-entry
+ (markup-writer '&bib-entry le
+ :options '(:title)
+ :action (lambda (n e)
+ (output n e (markup-writer-get '&bib-entry-body e)))
+ :after "\n")
+ ;; %bib-entry-title
+ (markup-writer '&bib-entry-title le
+ :action (lambda (n e)
+ (output (markup-body n) e)))
+ ;; %bib-entry-body
+ (markup-writer '&bib-entry-body le
+ :action (lambda (n e)
+ (define (output-fields descr)
+ (display "\\item[")
+ (let loop ((descr descr)
+ (pending #f)
+ (armed #f)
+ (first #t))
+ (cond
+ ((null? descr)
+ 'done)
+ ((pair? (car descr))
+ (if (eq? (caar descr) 'or)
+ (let ((o1 (cadr (car descr))))
+ (if (markup-option n o1)
+ (loop (cons o1 (cdr descr))
+ pending
+ #t
+ #f)
+ (let ((o2 (caddr (car descr))))
+ (loop (cons o2 (cdr descr))
+ pending
+ armed
+ #f))))
+ (let ((o (markup-option n (cadr (car descr)))))
+ (if o
+ (begin
+ (if (and pending armed)
+ (output pending e))
+ (output (caar descr) e)
+ (output o e)
+ (if (pair? (cddr (car descr)))
+ (output (caddr (car descr)) e))
+ (loop (cdr descr) #f #t #f))
+ (loop (cdr descr) pending armed #f)))))
+ ((symbol? (car descr))
+ (let ((o (markup-option n (car descr))))
+ (if o
+ (begin
+ (if (and armed pending)
+ (output pending e))
+ (output o e)
+ (if first
+ (display "]"))
+ (loop (cdr descr) #f #t #f))
+ (loop (cdr descr) pending armed #f))))
+ ((null? (cdr descr))
+ (output (car descr) e))
+ ((string? (car descr))
+ (loop (cdr descr)
+ (if pending pending (car descr))
+ armed
+ #f))
+ (else
+ (skribe-error 'output-bib-fields
+ "Illegal description"
+ (car descr))))))
+ (output-fields
+ (case (markup-option n 'kind)
+ ((techreport)
+ `(author (" (" year ")") " " (or title url) ". "
+ number ", " institution ", "
+ address ", " month ", "
+ ("pp. " pages) "."))
+ ((article)
+ `(author (" (" year ")") " " (or title url) ". "
+ journal ", " volume ", " ("(" number ")") ", "
+ address ", " month ", "
+ ("pp. " pages) "."))
+ ((inproceedings)
+ `(author (" (" year ")") " " (or title url) ". "
+ book(or title url) ", " series ", " ("(" number ")") ", "
+ address ", " month ", "
+ ("pp. " pages) "."))
+ ((book)
+ '(author (" (" year ")") " " (or title url) ". "
+ publisher ", " address
+ ", " month ", " ("pp. " pages) "."))
+ ((phdthesis)
+ '(author (" (" year ")") " " (or title url) ". " type ", "
+ school ", " address
+ ", " month "."))
+ ((misc)
+ '(author (" (" year ")") " " (or title url) ". "
+ publisher ", " address
+ ", " month "."))
+ (else
+ '(author (" (" year ")") " " (or title url) ". "
+ publisher ", " address
+ ", " month ", " ("pp. " pages) "."))))))
+ ;; abstract
+ (markup-writer 'jfp-abstract le
+ :options '(postscript)
+ :before "\\begin{abstract}\n"
+ :after "\\end{abstract}\n"))
+
+;*---------------------------------------------------------------------*/
+;* HTML global customizations */
+;*---------------------------------------------------------------------*/
+(let ((he (find-engine 'html)))
+ (markup-writer '&html-jfp-abstract he
+ :action (lambda (n e)
+ (let* ((bg (engine-custom e 'abstract-background))
+ (exp (p (if bg
+ (center (color :bg bg :width 90.
+ (it (markup-body n))))
+ (it (markup-body n))))))
+ (skribe-eval exp e)))))
+
+;*---------------------------------------------------------------------*/
+;* abstract ... */
+;*---------------------------------------------------------------------*/
+(define-markup (abstract #!rest opt #!key postscript)
+ (if (engine-format? "latex")
+ (new markup
+ (markup 'jfp-abstract)
+ (body (p (the-body opt))))
+ (let ((a (new markup
+ (markup '&html-jfp-abstract)
+ (body (the-body opt)))))
+ (list (if postscript
+ (section :number #f :toc #f :title "Postscript download"
+ postscript))
+ (section :number #f :toc #f :title "Abstract" a)
+ (section :number #f :toc #f :title "Table of contents"
+ (toc :subsection #t))))))
+
+;*---------------------------------------------------------------------*/
+;* references ... */
+;*---------------------------------------------------------------------*/
+(define (references)
+ (list "\n\n"
+ (section :title "References" :class "references"
+ :number (not (engine-format? "latex"))
+ (font :size -1 (the-bibliography)))))
+
diff --git a/src/guile/skribilo/package/letter.scm b/src/guile/skribilo/package/letter.scm
new file mode 100644
index 0000000..91d45be
--- /dev/null
+++ b/src/guile/skribilo/package/letter.scm
@@ -0,0 +1,157 @@
+;;; letter.scm -- Skribe style for letters
+;;;
+;;; Copyright 2003, 2004 Manuel Serrano
+;;;
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;; USA.
+
+(define-skribe-module (skribilo package letter))
+
+;*---------------------------------------------------------------------*/
+;* document */
+;*---------------------------------------------------------------------*/
+(define %letter-document document)
+
+(define-markup (document #!rest opt
+ #!key (ident #f) (class "letter")
+ where date author
+ &skribe-eval-location)
+ (let* ((ubody (the-body opt))
+ (body (list (new markup
+ (markup '&letter-where)
+ (loc &skribe-eval-location)
+ (options `((:where ,where)
+ (:date ,date)
+ (:author ,author))))
+ ubody)))
+ (apply %letter-document
+ :author #f :title #f
+ (append (apply append
+ (the-options opt :where :date :author :title))
+ body))))
+
+;*---------------------------------------------------------------------*/
+;* LaTeX configuration */
+;*---------------------------------------------------------------------*/
+(let ((le (find-engine 'latex)))
+ (engine-custom-set! le 'documentclass "\\documentclass[12pt]{letter}\n")
+ (engine-custom-set! le 'maketitle #f)
+ ;; &letter-where
+ (markup-writer '&letter-where le
+ :before "\\begin{raggedright}\n"
+ :action (lambda (n e)
+ (let* ((w (markup-option n :where))
+ (d (markup-option n :date))
+ (a (markup-option n :author))
+ (hd (if (and w d)
+ (list w ", " d)
+ (or w d)))
+ (ne (copy-engine 'author e)))
+ ;; author
+ (markup-writer 'author ne
+ :options '(:name :title :affiliation :email :url :address :phone :photo :align :header)
+ :action (lambda (n e)
+ (let ((name (markup-option n :name))
+ (title (markup-option n :title))
+ (affiliation (markup-option n :affiliation))
+ (email (markup-option n :email))
+ (url (markup-option n :url))
+ (address (markup-option n :address))
+ (phone (markup-option n :phone)))
+ (define (row n)
+ (output n e)
+ (when hd
+ (display "\\hfill ")
+ (output hd e)
+ (set! hd #f))
+ (display "\\\\\n"))
+ ;; name
+ (if name (row name))
+ ;; title
+ (if title (row title))
+ ;; affiliation
+ (if affiliation (row affiliation))
+ ;; address
+ (if (pair? address)
+ (for-each row address))
+ ;; telephone
+ (if phone (row phone))
+ ;; email
+ (if email (row email))
+ ;; url
+ (if url (row url)))))
+ ;; emit the author
+ (if a
+ (output a ne)
+ (output hd e))))
+ :after "\\end{raggedright}\n\\vspace{1cm}\n\n"))
+
+;*---------------------------------------------------------------------*/
+;* HTML configuration */
+;*---------------------------------------------------------------------*/
+(let ((he (find-engine 'html)))
+ ;; &letter-where
+ (markup-writer '&letter-where he
+ :before "<table width=\"100%\">\n"
+ :action (lambda (n e)
+ (let* ((w (markup-option n :where))
+ (d (markup-option n :date))
+ (a (markup-option n :author))
+ (hd (if (and w d)
+ (list w ", " d)
+ (or w d)))
+ (ne (copy-engine 'author e)))
+ ;; author
+ (markup-writer 'author ne
+ :options '(:name :title :affiliation :email :url :address :phone :photo :align :header)
+ :action (lambda (n e)
+ (let ((name (markup-option n :name))
+ (title (markup-option n :title))
+ (affiliation (markup-option n :affiliation))
+ (email (markup-option n :email))
+ (url (markup-option n :url))
+ (address (markup-option n :address))
+ (phone (markup-option n :phone)))
+ (define (row n)
+ (display "<tr><td align='left'>")
+ (output n e)
+ (when hd
+ (display "</td><td align='right'>")
+ (output hd e)
+ (set! hd #f))
+ (display "</td></tr>\n"))
+ ;; name
+ (if name (row name))
+ ;; title
+ (if title (row title))
+ ;; affiliation
+ (if affiliation (row affiliation))
+ ;; address
+ (if (pair? address)
+ (for-each row address))
+ ;; telephone
+ (if phone (row phone))
+ ;; email
+ (if email (row email))
+ ;; url
+ (if url (row url)))))
+ ;; emit the author
+ (if a
+ (output a ne)
+ (output hd e))))
+ :after "</table>\n<hr>\n\n"))
+
+
diff --git a/src/guile/skribilo/package/lncs.scm b/src/guile/skribilo/package/lncs.scm
new file mode 100644
index 0000000..8ffa7da
--- /dev/null
+++ b/src/guile/skribilo/package/lncs.scm
@@ -0,0 +1,158 @@
+;;; lncs.scm -- The Skribe style for LNCS articles.
+;;;
+;;; Copyright 2003, 2004 Manuel Serrano
+;;;
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;; USA.
+
+(define-skribe-module (skribilo package lncs))
+
+;*---------------------------------------------------------------------*/
+;* LaTeX global customizations */
+;*---------------------------------------------------------------------*/
+(let ((le (find-engine 'latex)))
+ (engine-custom-set! le 'documentclass "\\documentclass{llncs}")
+ ;; &latex-author
+ (markup-writer '&latex-author le
+ :action (lambda (n e)
+ (define (&latex-inst-body n)
+ (let ((affiliation (markup-option n :affiliation))
+ (address (markup-option n :address)))
+ (when affiliation (output affiliation e) (display ", "))
+ (when address
+ (for-each (lambda (a) (output a e) (display " "))
+ address)
+ (newline))))
+ (define (&latex-inst-n i)
+ (display "\\institute{\n")
+ (&latex-inst-body (car i))
+ (for-each (lambda (n)
+ (display "\\and\n")
+ (&latex-inst-body n))
+ (cdr i))
+ (display "}\n"))
+ (define (&latex-author-1 n)
+ (display "\\author{\n")
+ (output n e)
+ (display "}\n"))
+ (define (&latex-author-n n)
+ (display "\\author{\n")
+ (output (car n) e)
+ (for-each (lambda (a)
+ (display " and ")
+ (output a e))
+ (cdr n))
+ (display "}\n"))
+ (let ((body (markup-body n)))
+ (cond
+ ((is-markup? body 'author)
+ (markup-option-add! n 'inst 1)
+ (&latex-author-1 body)
+ (&latex-inst-n (list body)))
+ ((and (list? body)
+ (every? (lambda (b) (is-markup? b 'author))
+ body))
+ (define (institute=? n1 n2)
+ (let ((aff1 (markup-option n1 :affiliation))
+ (add1 (markup-option n1 :address))
+ (aff2 (markup-option n2 :affiliation))
+ (add2 (markup-option n2 :address)))
+ (and (equal? aff1 aff2) (equal? add1 add2))))
+ (define (search-institute n i j)
+ (cond
+ ((null? i)
+ #f)
+ ((institute=? n (car i))
+ j)
+ (else
+ (search-institute n (cdr i) (- j 1)))))
+ (if (null? (cdr body))
+ (begin
+ (markup-option-add! (car body) 'inst 1)
+ (&latex-author-1 (car body))
+ (&latex-inst-n body))
+ ;; collect the institutes
+ (let loop ((ns body)
+ (is '())
+ (j 1))
+ (if (null? ns)
+ (begin
+ (&latex-author-n body)
+ (&latex-inst-n (reverse! is)))
+ (let* ((n (car ns))
+ (si (search-institute n is (- j 1))))
+ (if (integer? si)
+ (begin
+ (markup-option-add! n 'inst si)
+ (loop (cdr ns) is j))
+ (begin
+ (markup-option-add! n 'inst j)
+ (loop (cdr ns)
+ (cons n is)
+ (+ 1 j)))))))))
+ (else
+ (skribe-error 'author
+ "Illegal `lncs' author"
+ body))))))
+ ;; author
+ (let ((old-author (markup-writer-get 'author le)))
+ (markup-writer 'author le
+ :options (writer-options old-author)
+ :action (lambda (n e)
+ (let ((name (markup-option n :name))
+ (title (markup-option n :title))
+ (inst (markup-option n 'inst)))
+ (if name (output name e))
+ (if title (output title e))
+ (if inst (printf "\\inst{~a}\n" inst)))))))
+
+;*---------------------------------------------------------------------*/
+;* HTML global customizations */
+;*---------------------------------------------------------------------*/
+(let ((he (find-engine 'html)))
+ (markup-writer '&html-lncs-abstract he
+ :action (lambda (n e)
+ (let* ((bg (or (engine-custom e 'abstract-background)
+ "#cccccc"))
+ (exp (p (center (color :bg bg :width 90.
+ (markup-body n))))))
+ (skribe-eval exp e)))))
+
+;*---------------------------------------------------------------------*/
+;* abstract ... */
+;*---------------------------------------------------------------------*/
+(define-markup (abstract #!rest opt #!key postscript)
+ (if (engine-format? "latex")
+ (section :number #f :title "ABSTRACT" (p (the-body opt)))
+ (let ((a (new markup
+ (markup '&html-lncs-abstract)
+ (body (the-body opt)))))
+ (list (if postscript
+ (section :number #f :toc #f :title "Postscript download"
+ postscript))
+ (section :number #f :toc #f :title "Abstract" a)
+ (section :number #f :toc #f :title "Table of contents"
+ (toc :subsection #t))))))
+
+;*---------------------------------------------------------------------*/
+;* references ... */
+;*---------------------------------------------------------------------*/
+(define (references)
+ (list "\n\n"
+ (if (engine-format? "latex")
+ (font :size -1 (flush :side 'left (the-bibliography)))
+ (section :title "References"
+ (font :size -1 (the-bibliography))))))
diff --git a/src/guile/skribilo/package/pie.scm b/src/guile/skribilo/package/pie.scm
new file mode 100644
index 0000000..8ccf858
--- /dev/null
+++ b/src/guile/skribilo/package/pie.scm
@@ -0,0 +1,314 @@
+;;; pie.scm -- An pie-chart formatting package.
+;;;
+;;; Copyright 2005, 2006 Ludovic Courtès <ludovic.courtes@laas.fr>
+;;;
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;; USA.
+
+(define-module (skribilo package pie)
+ :autoload (skribilo ast) (markup? markup-ident ast-parent)
+ :autoload (skribilo output) (output)
+ :use-module (skribilo writer)
+ :use-module (skribilo engine)
+ :use-module (skribilo lib) ;; `skribe-error' et al.
+ :use-module (skribilo utils syntax)
+ :use-module (skribilo utils keywords) ;; `the-options', etc.
+ :use-module (skribilo utils strings) ;; `make-string-replace'
+ :use-module (skribilo module)
+ :autoload (skribilo color) (skribe-color->rgb)
+ :autoload (skribilo package base) (bold)
+ :autoload (skribilo engine lout) (lout-illustration)
+ :autoload (ice-9 popen) (open-output-pipe)
+ :use-module (ice-9 optargs)
+ :export (%ploticus-program %ploticus-debug?
+ pie-sliceweight-value pie-remove-markup))
+
+(fluid-set! current-reader %skribilo-module-reader)
+
+
+
+;;;
+;;; Markup.
+;;;
+
+(define-markup (pie :rest opts
+ :key (ident #f) (title "Pie Chart")
+ (initial-angle 0) (total #f) (radius 3)
+ (fingers? #t) (labels 'outside)
+ (class "pie"))
+ (new container
+ (markup 'pie)
+ (ident (or ident (symbol->string (gensym "pie"))))
+ (options (the-options opts))
+ (body (the-body opts))))
+
+(define-markup (slice :rest opts
+ :key (ident #f) (weight 1) (color "white") (detach? #f))
+ (new container
+ (markup 'slice)
+ (ident (or ident (symbol->string (gensym "slice"))))
+ (weight weight)
+ (color color)
+ (detach? detach?)
+ (options (the-options opts))
+ (body (the-body opts))))
+
+(define-markup (sliceweight :rest opts
+ :key (ident #f) (percentage? #f))
+ (new markup
+ (markup 'sliceweight)
+ (ident (or ident (symbol->string (gensym "sliceweight"))))
+ (percentage? percentage?)
+ (options (the-options opts))
+ (body '())))
+
+
+
+;;;
+;;; Helper functions.
+;;;
+
+(define (make-rounder pow10)
+ ;; Return a procedure that round to 10 to the -POW10.
+ (let ((times (expt 10.0 pow10)))
+ (lambda (x)
+ (/ (round (* x times)) times))))
+
+(define (pie-sliceweight-value sw-node pct?)
+ "Return the value that should be displayed by `sw-node', a
+ `sliceweight' markup node. If `pct?' is true, then this value
+ should be a percentage."
+ (let* ((the-slice (ast-parent sw-node))
+ (weight (and the-slice (markup-option the-slice :weight))))
+ (if (not the-slice)
+ (skribe-error 'lout
+ "`sliceweight' node not within a `slice' body"
+ sw-node)
+ (if pct?
+ (let* ((the-pie (ast-parent the-slice))
+ (total (and the-pie
+ (markup-option the-pie
+ '&total-weight))))
+ (if (not the-pie)
+ (skribe-error 'lout
+ "`slice' not within a `pie' body"
+ the-slice)
+ (* 100.0 (/ weight total)))) ;; flonum (FIXME: precision)
+
+ weight))))
+
+(define (pie-remove-markup node)
+ "Remove markup from `node', ie. turn something like `(it \"hello\")' into
+the string \"hello\". Implement `sliceweight' markups too."
+ (define percentage-round (make-rounder 2))
+
+ (if (markup? node)
+ (if (and node (is-markup? node 'sliceweight))
+ (let* ((pct? (markup-option node :percentage?))
+ (value (pie-sliceweight-value node pct?)))
+ (number->string (percentage-round value)))
+ (pie-remove-markup (markup-body node)))
+ (if (list? node)
+ (apply string-append (map pie-remove-markup node))
+ node)))
+
+(define strip-newlines (make-string-replace '((#\newline " "))))
+
+(define (select-output-format engine)
+ ;; Choose an ouptut format suitable for ENGINE.
+ (define %supported-formats '("png" "ps" "eps" "svg" "svgz"))
+ (define %default-format "png")
+
+ (let ((fmt (engine-custom engine 'image-format)))
+ (cond ((string? fmt) fmt)
+ ((and (list? fmt) (not (null? fmt)))
+ (let ((f (car fmt)))
+ (if (member f %supported-formats)
+ f
+ %default-format)))
+ (else %default-format))))
+
+
+;;;
+;;; Default implementation (`base' engine).
+;;;
+
+;; Ploticus-based implementation of pie charts, suitable for most engines.
+;; See http://ploticus.sf.net for info about Ploticus.
+
+(define %ploticus-program "ploticus")
+(define %ploticus-debug? #f)
+
+(define (color-spec->ploticus color-spec)
+ (define round (make-rounder 2))
+
+ (call-with-values (lambda () (skribe-color->rgb color-spec))
+ (lambda (r g b)
+ (format #f "rgb(~a,~a,~a)"
+ (round (/ r 255.0))
+ (round (/ g 255.0))
+ (round (/ b 255.0))))))
+
+(define (ploticus-script pie)
+ (let* ((weights (map (lambda (slice)
+ (markup-option slice :weight))
+ (markup-body pie)))
+ (colors (map (lambda (slice)
+ (let ((c (markup-option slice :color)))
+ (string-append (color-spec->ploticus c)
+ " ")))
+ (markup-body pie)))
+ (total-weight (or (if (number? (markup-option pie
+ :total))
+ (markup-option pie :total)
+ #f)
+ (apply + weights)))
+
+ ;; Attach useful information to the pie and its slices
+ (-/- (markup-option-add! pie '&total-weight total-weight))
+
+ ;; One slice label per line -- so we need to remove
+ ;; newlines from labels.
+ (labels (map (lambda (b)
+ (strip-newlines (pie-remove-markup b)))
+ (markup-body pie)))
+
+; (flat-title (map pie-remove-markup
+; (markup-option pie :title)))
+ (detached (map (lambda (slice)
+ (let ((d (markup-option slice
+ :detach?)))
+ (cond ((number? d) d)
+ (d 0.5) ;; default
+ (#t 0))))
+ (markup-body pie)))
+
+ (initial-angle (or (markup-option pie :initial-angle)
+ 0))
+ (radius (or ;;FIXME
+ (markup-option pie :radius) 3))
+ (max-radius (+ radius (apply max detached)))
+
+ ;; center coordinates must take into account (i) the
+ ;; maxium radius when detached slices are considered and
+ ;; (ii) the fact that labels may get displayed to the
+ ;; left of the pie.
+ ;; FIXME: labels to the left (ii) end up being truncated
+ ;; when the radius is e.g. < 2.
+ (center `(,(+ max-radius
+ (* max-radius max-radius)) .
+ ,(* max-radius max-radius))))
+
+ (apply string-append
+ (append (list "#proc getdata\n" "data: ")
+ (map (lambda (weight)
+ (string-append (number->string weight)
+ "\n"))
+ weights)
+ `("\n"
+; "#proc page\n"
+; "title " ,@flat-title
+; "\n"
+ "#proc pie\n"
+ "total: "
+ ,(number->string total-weight)
+ "\n"
+ "datafield: " "1" "\n")
+ `("firstslice: " ,(number->string initial-angle) "\n")
+ `("radius: " ,(number->string radius) "\n")
+ `("center: " ,(number->string (car center))
+ " " ,(number->string (cdr center)) "\n")
+ `("labelmode: "
+ ,(case (markup-option
+ pie :labels)
+ ((outside) "line+label")
+ ((inside) "labelonly")
+ ((legend) "legend")
+ (else "legend"))
+ "\n"
+ "labels: " ,@(map (lambda (label)
+ (string-append label "\n"))
+ labels)
+ "\n")
+ `("explode: "
+ ,@(map (lambda (number)
+ (string-append (number->string number)
+ " "))
+ detached)
+ "\n")
+ `("colors: " ,@colors "\n")))))
+
+(markup-writer 'pie (find-engine 'base)
+ :action (lambda (node engine)
+ (let* ((fmt (select-output-format engine))
+ (pie-file (string-append (markup-ident node) "."
+ fmt))
+ (port (open-output-pipe
+ (string-append %ploticus-program
+ " -o " pie-file
+ " -cm -" fmt " -stdin")))
+ (script (ploticus-script node)))
+
+
+ (if %ploticus-debug?
+ (format (current-error-port) "** Ploticus script: ~a"
+ script))
+
+ (display script port)
+
+ (let ((exit-val (status:exit-val (close-pipe port))))
+ (if (not (eqv? 0 exit-val))
+ (skribe-error 'pie/ploticus
+ "ploticus exited with error code"
+ exit-val)))
+
+ (if (not (file-exists? pie-file))
+ (skribe-error 'ploticus
+ "Ploticus did not create the image file"
+ script))
+
+ (if (markup-option node :title)
+ (output (list (bold (markup-option node :title))
+ (linebreak))
+ engine))
+
+ (output (image :file pie-file
+ :class (markup-option node :class)
+ (or (markup-option node :title)
+ "A Pie Chart"))
+ engine))))
+
+(markup-writer 'slice (find-engine 'base)
+ :action (lambda (node engine)
+ ;; Nothing to do here
+ (error "slice: this writer should never be invoked")))
+
+(markup-writer 'sliceweight (find-engine 'base)
+ :action (lambda (node engine)
+ ;; Nothing to do here.
+ (error "sliceweight: this writer should never be invoked")))
+
+
+;;;
+;;; Initialization.
+;;;
+
+(when-engine-is-loaded 'lout
+ (lambda ()
+ (resolve-module '(skribilo package pie lout))))
+
+
+;;; arch-tag: 8095d8f6-b810-4619-9fdb-23fb94a77ee3
diff --git a/src/guile/skribilo/package/pie/Makefile.am b/src/guile/skribilo/package/pie/Makefile.am
new file mode 100644
index 0000000..3b4fafd
--- /dev/null
+++ b/src/guile/skribilo/package/pie/Makefile.am
@@ -0,0 +1,4 @@
+guilemoduledir = $(GUILE_SITE)/skribilo/package/pie
+dist_guilemodule_DATA = lout.scm
+
+## arch-tag: e6a03451-14c9-4331-8b96-71bde92ac142
diff --git a/src/guile/skribilo/package/pie/lout.scm b/src/guile/skribilo/package/pie/lout.scm
new file mode 100644
index 0000000..61dbcb7
--- /dev/null
+++ b/src/guile/skribilo/package/pie/lout.scm
@@ -0,0 +1,132 @@
+;;; lout.scm -- Lout implementation of the `pie' package.
+;;;
+;;; Copyright 2005, 2006 Ludovic Courtès <ludovic.courtes@laas.fr>
+;;;
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;; USA.
+
+(define-module (skribilo package pie lout)
+ :use-module (skribilo package pie)
+ :use-module (skribilo ast)
+ :autoload (skribilo output) (output)
+ :use-module (skribilo writer)
+ :use-module (skribilo engine)
+ :use-module (skribilo lib)
+ :use-module (skribilo utils syntax)
+ :use-module (skribilo utils keywords) ;; `the-options', etc.
+ :autoload (skribilo engine lout) (lout-color-specification)
+ :use-module (ice-9 optargs))
+
+(fluid-set! current-reader %skribilo-module-reader)
+
+
+
+;;;
+;;; Helper functions.
+;;;
+
+(let ((lout (find-engine 'lout)))
+ (if lout
+ (engine-custom-set! lout 'includes
+ (string-append (engine-custom lout 'includes)
+ "\n@SysInclude { pie } # Pie Charts\n"))))
+
+
+
+;;;
+;;; Writers.
+;;;
+
+(markup-writer 'pie (find-engine 'lout)
+ :before (lambda (node engine)
+ (let* ((weights (map (lambda (slice)
+ (markup-option slice :weight))
+ (markup-body node)))
+ (total-weight (or (if (number? (markup-option node
+ :total))
+ (markup-option node :total)
+ #f)
+ (apply + weights))))
+
+ (if (= 0 total-weight)
+ (skribe-error 'lout
+ "Slices weight sum should not be zero"
+ total-weight))
+
+ ;; Attach useful information to the pie and its slices
+ (markup-option-add! node '&total-weight total-weight)
+
+ (display "\n@Pie\n")
+ (display " abovecaption { ")
+ (if (markup-option node :title)
+ (output (markup-option node :title) engine))
+ (display " }\n")
+ (format #t " totalweight { ~a }\n" total-weight)
+ (format #t " initialangle { ~a }\n"
+ (or (markup-option node :initial-angle) 0))
+ (format #t " finger { ~a }\n"
+ (case (markup-option node :labels)
+ ((outside) (if (markup-option node :fingers?)
+ "yes" "no"))
+ (else "no")))
+
+ ;; We assume `:radius' to be centimeters
+ (if (markup-option node :radius)
+ (format #t " radius { ~ac }\n"
+ (markup-option node :radius)))
+
+ (format #t " labelradius { ~a }\n"
+ (case (markup-option node :labels)
+ ((outside #f) "external") ; FIXME: options are
+ ; not availble within
+ ; :before? (hence the #f)
+
+ ((inside) "internal")
+ (else
+ (skribe-error 'lout
+ "`:labels' should be one of 'inside or 'outside."
+ (markup-option node :labels)))))
+ (display "{\n")))
+ :after "\n} # @Pie\n")
+
+(markup-writer 'slice (find-engine 'lout)
+ :options '(:weight :detach? :color)
+ :action (lambda (node engine)
+ (display " @Slice\n")
+ (format #t " detach { ~a }\n"
+ (if (markup-option node :detach?)
+ "yes"
+ "no"))
+ (format #t " paint { ~a }\n"
+ (lout-color-specification (markup-option node
+ :color)))
+ (format #t " weight { ~a }\n"
+ (markup-option node :weight))
+
+ (display " label { ")
+ (output (markup-body node) engine)
+ (display " }\n")))
+
+(markup-writer 'sliceweight (find-engine 'base)
+ ;; This writer should work for every engine, provided the `pie' markup has
+ ;; a proper `&total-weight' option.
+ :action (lambda (node engine)
+ (let ((pct? (markup-option node :percentage?)))
+ (output (number->string
+ (pie-sliceweight-value node pct?))
+ engine))))
+
+;;; arch-tag: b5221e30-f80e-4b72-a281-83ce19ddb755
diff --git a/src/guile/skribilo/package/scribe.scm b/src/guile/skribilo/package/scribe.scm
new file mode 100644
index 0000000..902cdb5
--- /dev/null
+++ b/src/guile/skribilo/package/scribe.scm
@@ -0,0 +1,240 @@
+;;; scribe.scm -- Scribe Compatibility kit
+;;;
+;;; Copyright 2003, 2004 Manuel Serrano
+;;;
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;; USA.
+
+(define-skribe-module (skribilo package scribe))
+
+;*---------------------------------------------------------------------*/
+;* style ... */
+;*---------------------------------------------------------------------*/
+(define (style . styles)
+ (define (load-style style)
+ (let ((name (cond
+ ((string? style)
+ style)
+ ((symbol? style)
+ (string-append (symbol->string style) ".scr")))))
+ (skribe-load name :engine *skribe-engine*)))
+ (for-each load-style styles))
+
+;*---------------------------------------------------------------------*/
+;* chapter ... */
+;*---------------------------------------------------------------------*/
+(define skribe-chapter chapter)
+
+(define-markup (chapter #!rest opt #!key title subtitle split number toc file)
+ (apply skribe-chapter
+ :title (or title subtitle)
+ :number number
+ :toc toc
+ :file file
+ (the-body opt)))
+
+;*---------------------------------------------------------------------*/
+;* table-of-contents ... */
+;*---------------------------------------------------------------------*/
+(define-markup (table-of-contents #!rest opts #!key chapter section subsection)
+ (apply toc opts))
+
+;*---------------------------------------------------------------------*/
+;* frame ... */
+;*---------------------------------------------------------------------*/
+(define skribe-frame frame)
+
+(define-markup (frame #!rest opt #!key width margin)
+ (apply skribe-frame
+ :width (if (real? width) (* 100 width) width)
+ :margin margin
+ (the-body opt)))
+
+;*---------------------------------------------------------------------*/
+;* copyright ... */
+;*---------------------------------------------------------------------*/
+(define (copyright)
+ (symbol 'copyright))
+
+;*---------------------------------------------------------------------*/
+;* sect ... */
+;*---------------------------------------------------------------------*/
+(define (sect)
+ (symbol 'section))
+
+;*---------------------------------------------------------------------*/
+;* euro ... */
+;*---------------------------------------------------------------------*/
+(define (euro)
+ (symbol 'euro))
+
+;*---------------------------------------------------------------------*/
+;* tab ... */
+;*---------------------------------------------------------------------*/
+(define (tab)
+ (char #\tab))
+
+;*---------------------------------------------------------------------*/
+;* space ... */
+;*---------------------------------------------------------------------*/
+(define (space)
+ (char #\space))
+
+;*---------------------------------------------------------------------*/
+;* print-bibliography ... */
+;*---------------------------------------------------------------------*/
+(define-markup (print-bibliography #!rest opts
+ #!key all (sort bib-sort/authors))
+ (the-bibliography all sort))
+
+;*---------------------------------------------------------------------*/
+;* linebreak ... */
+;*---------------------------------------------------------------------*/
+(define skribe-linebreak linebreak)
+
+(define-markup (linebreak . lnum)
+ (cond
+ ((null? lnum)
+ (skribe-linebreak))
+ ((string? (car lnum))
+ (skribe-linebreak (string->number (car lnum))))
+ (else
+ (skribe-linebreak (car lnum)))))
+
+;*---------------------------------------------------------------------*/
+;* ref ... */
+;*---------------------------------------------------------------------*/
+(define skribe-ref ref)
+
+(define-markup (ref #!rest opts
+ #!key scribe url id page figure mark
+ chapter section subsection subsubsection subsubsection
+ bib bib+ number)
+ (let ((bd (the-body opts))
+ (args (apply append (the-options opts :id))))
+ (if id (set! args (cons* :mark id args)))
+ (if (pair? bd) (set! args (cons* :text bd args)))
+ (apply skribe-ref args)))
+
+;*---------------------------------------------------------------------*/
+;* indexes ... */
+;*---------------------------------------------------------------------*/
+(define *scribe-indexes*
+ (list (cons "theindex" (make-index "theindex"))))
+
+(define skribe-index index)
+(define skribe-make-index make-index)
+
+(define-markup (make-index index)
+ (let ((i (skribe-make-index index)))
+ (set! *scribe-indexes* (cons (cons index i) *scribe-indexes*))
+ i))
+
+(define-markup (index #!rest opts #!key note index shape)
+ (let ((i (if (not index)
+ "theindex"
+ (let ((i (assoc index *scribe-indexes*)))
+ (if (pair? i)
+ (cdr i)
+ (make-index index))))))
+ (apply skribe-index :note note :index i :shape shape (the-body opts))))
+
+(define-markup (print-index #!rest opts
+ #!key split (char-offset 0) (header-limit 100))
+ (apply the-index
+ :split split
+ :char-offset char-offset
+ :header-limit header-limit
+ (map (lambda (i)
+ (let ((c (assoc i *scribe-indexes*)))
+ (if (pair? c)
+ (cdr c)
+ (skribe-error 'the-index "Unknown index" i))))
+ (the-body opts))))
+
+;*---------------------------------------------------------------------*/
+;* format? */
+;*---------------------------------------------------------------------*/
+(define (scribe-format? fmt) #f)
+
+;*---------------------------------------------------------------------*/
+;* scribe-url ... */
+;*---------------------------------------------------------------------*/
+(define (scribe-url) (skribe-url))
+
+;*---------------------------------------------------------------------*/
+;* Various configurations */
+;*---------------------------------------------------------------------*/
+(define *scribe-background* #f)
+(define *scribe-foreground* #f)
+(define *scribe-tbackground* #f)
+(define *scribe-tforeground* #f)
+(define *scribe-title-font* #f)
+(define *scribe-author-font* #f)
+(define *scribe-chapter-numbering* #f)
+(define *scribe-footer* #f)
+(define *scribe-prgm-color* #f)
+
+;*---------------------------------------------------------------------*/
+;* prgm ... */
+;*---------------------------------------------------------------------*/
+(define-markup (prgm #!rest opts
+ #!key lnum lnumwidth language bg frame (width 1.)
+ colors (monospace #t))
+ (let* ((w (cond
+ ((real? width) (* width 100.))
+ ((number? width) width)
+ (else 100.)))
+ (body (if language
+ (source :language language (the-body opts))
+ (the-body opts)))
+ (body (if monospace
+ (prog :line lnum body)
+ body))
+ (body (if bg
+ (color :width 100. :bg bg body)
+ body)))
+ (skribe-frame :width w
+ :border (if frame 1 #f)
+ body)))
+
+;*---------------------------------------------------------------------*/
+;* latex configuration */
+;*---------------------------------------------------------------------*/
+(define *scribe-tex-predocument* #f)
+
+;*---------------------------------------------------------------------*/
+;* latex-prelude ... */
+;*---------------------------------------------------------------------*/
+(define (latex-prelude e)
+ (if (engine-format? "latex" e)
+ (begin
+ (if *scribe-tex-predocument*
+ (engine-custom-set! e 'predocument *scribe-tex-predocument*)))))
+
+;*---------------------------------------------------------------------*/
+;* html-prelude ... */
+;*---------------------------------------------------------------------*/
+(define (html-prelude e)
+ (if (engine-format? "html" e)
+ (begin
+ #f)))
+
+;*---------------------------------------------------------------------*/
+;* prelude */
+;*---------------------------------------------------------------------*/
+(let ((p (user-prelude)))
+ (user-prelude-set! (lambda (e) (p e) (latex-prelude e))))
diff --git a/src/guile/skribilo/package/sigplan.scm b/src/guile/skribilo/package/sigplan.scm
new file mode 100644
index 0000000..28d4e83
--- /dev/null
+++ b/src/guile/skribilo/package/sigplan.scm
@@ -0,0 +1,166 @@
+;;; sigplan.scm -- The Skribe style for ACMPROC articles.
+;;;
+;;; Copyright 2003, 2004 Manuel Serrano
+;;;
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;; USA.
+
+(define-skribe-module (skribilo package sigplan))
+
+;*---------------------------------------------------------------------*/
+;* LaTeX global customizations */
+;*---------------------------------------------------------------------*/
+(let ((le (find-engine 'latex)))
+ (engine-custom-set! le
+ 'documentclass
+ "\\documentclass[twocolumns]{sigplanconf}")
+ ;; &latex-author
+ (markup-writer '&latex-author le
+ :before (lambda (n e)
+ (let ((body (markup-body n)))
+ (printf "\\authorinfo{\n"
+ (if (pair? body) (length body) 1))))
+ :action (lambda (n e)
+ (let ((body (markup-body n)))
+ (for-each (lambda (a)
+ (display "}\n\\authorinfo{")
+ (output a e))
+ (if (pair? body) body (list body)))))
+ :after "}\n")
+ ;; author
+ (let ((old-author (markup-writer-get 'author le)))
+ (markup-writer 'author le
+ :options (writer-options old-author)
+ :action (writer-action old-author)))
+ ;; ACM category, terms, and keywords
+ (markup-writer '&acm-category le
+ :options '(:index :section :subsection)
+ :before (lambda (n e)
+ (display "\\category{")
+ (display (markup-option n :index))
+ (display "}")
+ (display "{")
+ (display (markup-option n :section))
+ (display "}")
+ (display "{")
+ (display (markup-option n :subsection))
+ (display "}\n["))
+ :after "]\n")
+ (markup-writer '&acm-terms le
+ :before "\\terms{"
+ :after "}")
+ (markup-writer '&acm-keywords le
+ :before "\\keywords{"
+ :after "}")
+ (markup-writer '&acm-copyright le
+ :action (lambda (n e)
+ (display "\\conferenceinfo{")
+ (output (markup-option n :conference) e)
+ (display ",} {")
+ (output (markup-option n :location) e)
+ (display "}\n")
+ (display "\\copyrightyear{")
+ (output (markup-option n :year) e)
+ (display "}\n")
+ (display "\\copyrightdata{")
+ (output (markup-option n :crdata) e)
+ (display "}\n"))))
+
+;*---------------------------------------------------------------------*/
+;* HTML global customizations */
+;*---------------------------------------------------------------------*/
+(let ((he (find-engine 'html)))
+ (markup-writer '&html-acmproc-abstract he
+ :action (lambda (n e)
+ (let* ((ebg (engine-custom e 'abstract-background))
+ (bg (or (and (string? ebg)
+ (> (string-length ebg) 0))
+ ebg
+ "#cccccc"))
+ (exp (p (center (color :bg bg :width 90.
+ (markup-body n))))))
+ (skribe-eval exp e))))
+ ;; ACM category, terms, and keywords
+ (markup-writer '&acm-category :action #f)
+ (markup-writer '&acm-terms :action #f)
+ (markup-writer '&acm-keywords :action #f)
+ (markup-writer '&acm-copyright :action #f))
+
+;*---------------------------------------------------------------------*/
+;* abstract ... */
+;*---------------------------------------------------------------------*/
+(define-markup (abstract #!rest opt #!key postscript)
+ (if (engine-format? "latex")
+ (section :number #f :title "ABSTRACT" (p (the-body opt)))
+ (let ((a (new markup
+ (markup '&html-acmproc-abstract)
+ (body (the-body opt)))))
+ (list (if postscript
+ (section :number #f :toc #f :title "Postscript download"
+ postscript))
+ (section :number #f :toc #f :title "Abstract" a)
+ (section :number #f :toc #f :title "Table of contents"
+ (toc :subsection #t))))))
+
+;*---------------------------------------------------------------------*/
+;* acm-category ... */
+;*---------------------------------------------------------------------*/
+(define-markup (acm-category #!rest opt #!key index section subsection)
+ (new markup
+ (markup '&acm-category)
+ (options (the-options opt))
+ (body (the-body opt))))
+
+;*---------------------------------------------------------------------*/
+;* acm-terms ... */
+;*---------------------------------------------------------------------*/
+(define-markup (acm-terms #!rest opt)
+ (new markup
+ (markup '&acm-terms)
+ (options (the-options opt))
+ (body (the-body opt))))
+
+;*---------------------------------------------------------------------*/
+;* acm-keywords ... */
+;*---------------------------------------------------------------------*/
+(define-markup (acm-keywords #!rest opt)
+ (new markup
+ (markup '&acm-keywords)
+ (options (the-options opt))
+ (body (the-body opt))))
+
+;*---------------------------------------------------------------------*/
+;* acm-copyright ... */
+;*---------------------------------------------------------------------*/
+(define-markup (acm-copyright #!rest opt #!key conference location year crdata)
+ (let* ((le (find-engine 'latex))
+ (cop (format "\\conferenceinfo{~a,} {~a}
+\\CopyrightYear{~a}
+\\crdata{~a}\n" conference location year crdata))
+ (old (engine-custom le 'predocument)))
+ (if (string? old)
+ (engine-custom-set! le 'predocument (string-append cop old))
+ (engine-custom-set! le 'predocument cop))))
+
+;*---------------------------------------------------------------------*/
+;* references ... */
+;*---------------------------------------------------------------------*/
+(define (references)
+ (list "\n\n"
+ (if (engine-format? "latex")
+ (font :size -1 (flush :side 'left (the-bibliography)))
+ (section :title "References"
+ (font :size -1 (the-bibliography))))))
diff --git a/src/guile/skribilo/package/skribe.scm b/src/guile/skribilo/package/skribe.scm
new file mode 100644
index 0000000..86969aa
--- /dev/null
+++ b/src/guile/skribilo/package/skribe.scm
@@ -0,0 +1,85 @@
+;;; skribe.scm -- The standard Skribe style (always loaded).
+;;;
+;;; Copyright 2003, 2004 Manuel Serrano
+;;;
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;; USA.
+
+;*---------------------------------------------------------------------*/
+;* p ... */
+;*---------------------------------------------------------------------*/
+(define-markup (p #!rest opt #!key ident (class #f) &skribe-eval-location)
+ (paragraph :ident ident :class class :loc &skribe-eval-location
+ (the-body opt)))
+
+;*---------------------------------------------------------------------*/
+;* fg ... */
+;*---------------------------------------------------------------------*/
+(define (fg c . body)
+ (color :fg c body))
+
+;*---------------------------------------------------------------------*/
+;* bg ... */
+;*---------------------------------------------------------------------*/
+(define (bg c . body)
+ (color :bg c body))
+
+;*---------------------------------------------------------------------*/
+;* counter ... */
+;* ------------------------------------------------------------- */
+;* This produces a kind of "local enumeration" that is: */
+;* (counting "toto," "tutu," "titi.") */
+;* produces: */
+;* i) toto, ii) tutu, iii) titi. */
+;*---------------------------------------------------------------------*/
+(define-markup (counter #!rest opts #!key (numbering 'roman))
+ (define items (if (eq? (car opts) :numbering) (cddr opts) opts))
+ (define vroman '#(- "i" "ii" "iii" "iv" "v" "vi" "vii" "viii" "ix" "x"))
+ (define (the-roman-number num)
+ (if (< num (vector-length vroman))
+ (list (list "(" (it (vector-ref vroman num)) ") "))
+ (skribe-error 'counter
+ "too many items for roman numbering"
+ (length items))))
+ (define (the-arabic-number num)
+ (list (list "(" (it (integer->string num)) ") ")))
+ (define (the-alpha-number num)
+ (list (list "(" (it (+ (integer->char #\a) num -1)) ") ")))
+ (let ((the-number (case numbering
+ ((roman) the-roman-number)
+ ((arabic) the-arabic-number)
+ ((alpha) the-alpha-number)
+ (else (skribe-error 'counter
+ "Illegal numbering"
+ numbering)))))
+ (let loop ((num 1)
+ (items items)
+ (res '()))
+ (if (null? items)
+ (reverse! res)
+ (loop (+ num 1)
+ (cdr items)
+ (cons (list (the-number num) (car items)) res))))))
+
+;*---------------------------------------------------------------------*/
+;* q */
+;*---------------------------------------------------------------------*/
+(define-markup (q #!rest opt)
+ (new markup
+ (markup 'q)
+ (options (the-options opt))
+ (body (the-body opt))))
+
diff --git a/src/guile/skribilo/package/slide.scm b/src/guile/skribilo/package/slide.scm
new file mode 100644
index 0000000..7f731e3
--- /dev/null
+++ b/src/guile/skribilo/package/slide.scm
@@ -0,0 +1,274 @@
+;;; slide.scm -- Overhead transparencies.
+;;;
+;;; Copyright 2003, 2004 Manuel Serrano
+;;; Copyright 2006 Ludovic Courtès <ludovic.courtes@laas.fr>
+;;;
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;; USA.
+
+
+(define-skribe-module (skribilo package slide))
+
+
+;*---------------------------------------------------------------------*/
+;* slide-options */
+;*---------------------------------------------------------------------*/
+(define-public &slide-load-options (skribe-load-options))
+
+
+;*---------------------------------------------------------------------*/
+;* %slide-the-slides ... */
+;*---------------------------------------------------------------------*/
+(define %slide-the-slides '())
+(define %slide-the-counter 0)
+
+;*---------------------------------------------------------------------*/
+;* slide ... */
+;*---------------------------------------------------------------------*/
+(define-markup (slide #!rest opt
+ #!key
+ (ident #f) (class #f)
+ (toc #t)
+ title (number #t)
+ (vspace #f) (vfill #f)
+ (transition #f)
+ (bg #f) (image #f))
+ (let ((s (new container
+ (markup 'slide)
+ (ident (if (not ident)
+ (symbol->string (gensym 'slide))
+ ident))
+ (class class)
+ (required-options '(:title :number :toc))
+ (options `((:number
+ ,(cond
+ ((number? number)
+ (set! %slide-the-counter number)
+ number)
+ (number
+ (set! %slide-the-counter
+ (+ 1 %slide-the-counter))
+ %slide-the-counter)
+ (else
+ #f)))
+ (:toc ,toc)
+ ,@(the-options opt :ident :class :vspace :toc)))
+ (body (if vspace
+ (list (slide-vspace vspace) (the-body opt))
+ (the-body opt))))))
+ (set! %slide-the-slides (cons s %slide-the-slides))
+ s))
+
+;*---------------------------------------------------------------------*/
+;* ref ... */
+;*---------------------------------------------------------------------*/
+(define %slide-old-ref ref)
+
+;; Extend the definition of `ref'.
+;; FIXME: This technique breaks `ref' for some reason.
+; (set! ref
+; (lambda args
+; ;; Filter out ARGS and look for a `:slide' keyword argument.
+; (let loop ((slide #f)
+; (opt '())
+; (args args))
+; (if (null? args)
+; (set! opt (reverse! opt))
+; (let ((s? (eq? (car args) :slide)))
+; (loop (if s? (cadr args) #f)
+; (if s? opt (cons (car args) opt))
+; (if s? (cddr args) (cdr args)))))
+
+; (format (current-error-port)
+; "slide.scm:ref: slide=~a opt=~a~%" slide opt)
+
+; (if (not slide)
+; (apply %slide-old-ref opt)
+; (new unresolved
+; (proc (lambda (n e env)
+; (cond
+; ((eq? slide 'next)
+; (let ((c (assq n %slide-the-slides)))
+; (if (pair? c)
+; (handle (cadr c))
+; #f)))
+; ((eq? slide 'prev)
+; (let ((c (assq n (reverse %slide-the-slides))))
+; (if (pair? c)
+; (handle (cadr c))
+; #f)))
+; ((number? slide)
+; (let loop ((s %slide-the-slides))
+; (cond
+; ((null? s)
+; #f)
+; ((= slide (markup-option
+; (car s) :number))
+; (handle (car s)))
+; (else
+; (loop (cdr s))))))
+; (else
+; #f)))))))))
+
+
+;*---------------------------------------------------------------------*/
+;* slide-pause ... */
+;*---------------------------------------------------------------------*/
+(define-markup (slide-pause)
+ (new markup
+ (markup 'slide-pause)))
+
+;*---------------------------------------------------------------------*/
+;* slide-vspace ... */
+;*---------------------------------------------------------------------*/
+(define-markup (slide-vspace #!rest opt #!key (unit 'cm))
+ (new markup
+ (markup 'slide-vspace)
+ (options `((:unit ,unit) ,@(the-options opt :unit)))
+ (body (the-body opt))))
+
+;*---------------------------------------------------------------------*/
+;* slide-embed ... */
+;*---------------------------------------------------------------------*/
+(define-markup (slide-embed #!rest opt
+ #!key
+ command
+ (geometry-opt "-geometry")
+ (geometry #f) (rgeometry #f)
+ (transient #f) (transient-opt #f)
+ (alt #f)
+ &skribe-eval-location)
+ (if (not (string? command))
+ (skribe-error 'slide-embed
+ "No command provided"
+ command)
+ (new markup
+ (markup 'slide-embed)
+ (loc &skribe-eval-location)
+ (required-options '(:alt))
+ (options `((:geometry-opt ,geometry-opt)
+ (:alt ,alt)
+ ,@(the-options opt :geometry-opt :alt)))
+ (body (the-body opt)))))
+
+;*---------------------------------------------------------------------*/
+;* slide-record ... */
+;*---------------------------------------------------------------------*/
+(define-markup (slide-record #!rest opt #!key ident class tag (play #t))
+ (if (not tag)
+ (skribe-error 'slide-record "Tag missing" tag)
+ (new markup
+ (markup 'slide-record)
+ (ident ident)
+ (class class)
+ (options `((:play ,play) ,@(the-options opt)))
+ (body (the-body opt)))))
+
+;*---------------------------------------------------------------------*/
+;* slide-play ... */
+;*---------------------------------------------------------------------*/
+(define-markup (slide-play #!rest opt #!key ident class tag color)
+ (if (not tag)
+ (skribe-error 'slide-play "Tag missing" tag)
+ (new markup
+ (markup 'slide-play)
+ (ident ident)
+ (class class)
+ (options `((:color ,(if color (skribe-use-color! color) #f))
+ ,@(the-options opt :color)))
+ (body (the-body opt)))))
+
+;*---------------------------------------------------------------------*/
+;* slide-play* ... */
+;*---------------------------------------------------------------------*/
+(define-markup (slide-play* #!rest opt
+ #!key ident class color (scolor "#000000"))
+ (let ((body (the-body opt)))
+ (for-each (lambda (lbl)
+ (match-case lbl
+ ((?id ?col)
+ (skribe-use-color! col))))
+ body)
+ (new markup
+ (markup 'slide-play*)
+ (ident ident)
+ (class class)
+ (options `((:color ,(if color (skribe-use-color! color) #f))
+ (:scolor ,(if color (skribe-use-color! scolor) #f))
+ ,@(the-options opt :color :scolor)))
+ (body body))))
+
+
+
+;*---------------------------------------------------------------------*/
+;* slide-number ... */
+;*---------------------------------------------------------------------*/
+(define-public (slide-number)
+ (length (filter (lambda (n)
+ (and (is-markup? n 'slide)
+ (markup-option n :number)))
+ %slide-the-slides)))
+
+;*---------------------------------------------------------------------*/
+;* slide-topic ... */
+;*---------------------------------------------------------------------*/
+(define-markup (slide-topic #!rest opt
+ #!key title (outline? #t)
+ (ident #f) (class "slide-topic"))
+ (new container
+ (markup 'slide-topic)
+ (required-options '(:title :outline?))
+ (ident (or ident (symbol->string (gensym 'slide-topic))))
+ (options `((:outline? ,outline?)
+ ,@(the-options opt :outline?)))
+ (body (the-body opt))))
+
+;*---------------------------------------------------------------------*/
+;* slide-subtopic ... */
+;*---------------------------------------------------------------------*/
+(define-markup (slide-subtopic #!rest opt
+ #!key title (outline? #f)
+ (ident #f) (class "slide-subtopic"))
+ (new container
+ (markup 'slide-subtopic)
+ (required-options '(:title :outline?))
+ (ident (or ident (symbol->string (gensym 'slide-subtopic))))
+ (options `((:outline? ,outline?)
+ ,@(the-options opt :outline?)))
+ (body (the-body opt))))
+
+
+
+;;;
+;;; Initialization.
+;;;
+
+(format (current-error-port) "Slides initializing...~%")
+
+;; Register specific implementations for lazy loading.
+(when-engine-is-loaded 'base
+ (lambda ()
+ (resolve-module '(skribilo package slide base))))
+(when-engine-is-loaded 'latex
+ (lambda ()
+ (resolve-module '(skribilo package slide latex))))
+(when-engine-is-loaded 'html
+ (lambda ()
+ (resolve-module '(skribilo package slide html))))
+(when-engine-is-loaded 'lout
+ (lambda ()
+ (resolve-module '(skribilo package slide lout))))
+
diff --git a/src/guile/skribilo/package/slide/Makefile.am b/src/guile/skribilo/package/slide/Makefile.am
new file mode 100644
index 0000000..53320fa
--- /dev/null
+++ b/src/guile/skribilo/package/slide/Makefile.am
@@ -0,0 +1,4 @@
+guilemoduledir = $(GUILE_SITE)/skribilo/package/slide
+dist_guilemodule_DATA = base.scm latex.scm html.scm lout.scm
+
+## arch-tag: 56b5fa5c-bb6a-4692-b929-74bdd032431c
diff --git a/src/guile/skribilo/package/slide/base.scm b/src/guile/skribilo/package/slide/base.scm
new file mode 100644
index 0000000..c8e652c
--- /dev/null
+++ b/src/guile/skribilo/package/slide/base.scm
@@ -0,0 +1,185 @@
+;;; base.scm -- Overhead transparencies, `base' engine.
+;;;
+;;; Copyright 2003, 2004 Manuel Serrano
+;;; Copyright 2006 Ludovic Courtès <ludovic.courtes@laas.fr>
+;;;
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;; USA.
+
+(define-module (skribilo package slide base)
+ :use-module (skribilo utils syntax)
+
+ :use-module (skribilo package slide)
+ :use-module (skribilo writer)
+ :use-module (skribilo engine)
+ :use-module (skribilo ast)
+ :autoload (skribilo output) (output)
+ :autoload (skribilo package base) (symbol color itemize item)
+
+ :use-module (srfi srfi-1)
+
+ :export (%slide-outline-title %slide-outline-itemize-symbols))
+
+(fluid-set! current-reader %skribilo-module-reader)
+
+
+
+;;;
+;;; Simple markups.
+;;;
+(let ((be (find-engine 'base)))
+
+ ;; slide-pause
+ (markup-writer 'slide-pause be
+ :action #f)
+ ;; slide-vspace
+ (markup-writer 'slide-vspace be
+ :options '()
+ :action #f)
+ ;; slide-embed
+ (markup-writer 'slide-embed be
+ :options '(:alt :geometry-opt)
+ :action (lambda (n e)
+ (output (markup-option n :alt) e)))
+ ;; slide-record
+ (markup-writer 'slide-record be
+ :options '(:tag :play)
+ :action (lambda (n e)
+ (output (markup-body n) e)))
+ ;; slide-play
+ (markup-writer 'slide-play be
+ :options '(:tag :color)
+ :action (lambda (n e)
+ (output (markup-option n :alt) e)))
+ ;; slide-play*
+ (markup-writer 'slide-play* be
+ :options '(:tag :color :scolor)
+ :action (lambda (n e)
+ (output (markup-option n :alt) e))))
+
+
+;;;
+;;; Helper functions for the default topic/subtopic handling.
+;;;
+
+(define (make-subtopic-list node recurse?-proc make-entry-proc
+ itemize-symbols)
+ ;; Make a list of the subtopic of `node'. Go recursive if `recurse?-proc'
+ ;; returns true. `make-entry-proc' is passed a node and returns an entry
+ ;; (a markup) for this node. `itemize-symbols' is a (circular) list
+ ;; containing the symbols to be passed to `itemize'.
+ (let* ((subtopic? (lambda (n)
+ (or (is-markup? n 'slide-subtopic)
+ (is-markup? n 'slide))))
+ (subtopic-types (if (is-markup? node 'slide-topic)
+ '(slide-subtopic slide)
+ '(slide-topic))))
+ (if (subtopic? node)
+ '()
+ (apply itemize
+ `(,@(if (is-markup? (car itemize-symbols) 'symbol)
+ `(:symbol ,(car itemize-symbols))
+ '())
+ ,@(map (lambda (t)
+ (item
+ (make-entry-proc t)
+ (if (recurse?-proc t)
+ (make-subtopic-list t recurse?-proc
+ make-entry-proc
+ (cdr itemize-symbols))
+ '())))
+ (filter (lambda (n)
+ (and (markup? n)
+ (member (markup-markup n)
+ subtopic-types)))
+ (markup-body node))))))))
+
+(define (make-topic-list current-topic recurse? make-entry-proc)
+ ;; Make a full topic list of the document which contains
+ ;; `current-topic'. Here, `make-entry-proc' takes a topic node and
+ ;; the current topic node as its arguments.
+ (let ((doc (ast-document current-topic)))
+ (make-subtopic-list doc
+ (lambda (t)
+ (and recurse? (eq? t current-topic)))
+ (lambda (t)
+ (make-entry-proc t current-topic))
+ %slide-outline-itemize-symbols)))
+
+(define (make-topic-entry topic current-topic)
+ ;; Produce an entry for `topic'. Colorize it based on the fact
+ ;; that the current topic is `current-topic' (it may need to be
+ ;; hightlighted).
+ (let ((title (markup-option topic :title))
+ (current? (eq? topic current-topic)))
+ (color :fg (if current? "#000000" "#666666")
+ (apply (if current? bold (lambda (x) x))
+ (list (markup-option topic :title))))))
+
+
+;;;
+;;; Default topic/subtopic handling.
+;;;
+
+;; Title for the automatically-generated outline slide.
+(define %slide-outline-title "")
+
+;; Circular list of symbols to be passed to `itemize' in outlines.
+(define %slide-outline-itemize-symbols
+ (let loop ((names '(#t "-" "bullet" "->" "middot")))
+ (if (null? names)
+ '()
+ (cons (if (string? (car names))
+ (symbol (car names))
+ (car names))
+ (loop (cdr names))))))
+
+
+(define (make-outline-slide topic engine)
+ (let ((parent-topic (if (is-markup? topic 'slide-topic)
+ topic
+ (find1-up (lambda (n)
+ (is-markup? n 'slide-topic))
+ topic))))
+ (output (slide :title %slide-outline-title :toc #f
+ :class (markup-option topic :class)
+ ;; The mark below is needed for cross-referencing by PDF
+ ;; bookmarks.
+ (if (markup-ident topic) (mark (markup-ident topic)) "")
+ (p (make-topic-list parent-topic #t
+ make-topic-entry)))
+ engine)))
+
+
+(markup-writer 'slide-topic (find-engine 'base)
+ :options '(:title :outline? :class :ident)
+ :action (lambda (n e)
+ (if (markup-option n :outline?)
+ (make-outline-slide n e))
+
+ (output (markup-body n) e)))
+
+(markup-writer 'slide-subtopic (find-engine 'base)
+ ;; FIXME: Largely untested.
+ :options '(:title :outline? :class :ident)
+ :action (lambda (n e)
+ (if (markup-option n :outline?)
+ (make-outline-slide n e))
+
+ (output (markup-body n) e)))
+
+
+;;; arch-tag: 1187ce0c-3ffc-4248-b68b-a7c77d6598b9
diff --git a/src/guile/skribilo/package/slide/html.scm b/src/guile/skribilo/package/slide/html.scm
new file mode 100644
index 0000000..d47ef82
--- /dev/null
+++ b/src/guile/skribilo/package/slide/html.scm
@@ -0,0 +1,144 @@
+;;; html.scm -- HTML implementation of the `slide' package.
+;;;
+;;; Copyright 2003, 2004 Manuel Serrano
+;;;
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;; USA.
+
+(define-skribe-module (skribilo package slide html)
+ :use-module (skribilo package slide))
+
+
+(define-public (%slide-html-initialize!)
+ (let ((he (find-engine 'html)))
+ (skribe-message "HTML slides setup...\n")
+ ;; &html-page-title
+ (markup-writer '&html-document-title he
+ ;;:predicate (lambda (n e) %slide-initialized)
+ :action html-slide-title)
+ ;; slide
+ (markup-writer 'slide he
+ :options '(:title :number :transition :toc :bg)
+ :before (lambda (n e)
+ (printf "<a name=\"~a\">" (markup-ident n))
+ (display "<br>\n"))
+ :action (lambda (n e)
+ (let ((nb (markup-option n :number))
+ (t (markup-option n :title)))
+ (skribe-eval
+ (center
+ (color :width (slide-body-width e)
+ :bg (or (markup-option n :bg) "#ffffff")
+ (table :width 100.
+ (tr (th :align 'left
+ (list
+ (if nb
+ (format #f "~a / ~a -- " nb
+ (slide-number)))
+ t)))
+ (tr (td (hrule)))
+ (tr (td :width 100. :align 'left
+ (markup-body n))))
+ (linebreak)))
+ e)))
+ :after "<br>")
+ ;; slide-vspace
+ (markup-writer 'slide-vspace he
+ :action (lambda (n e) (display "<br>")))))
+
+
+;*---------------------------------------------------------------------*/
+;* slide-body-width ... */
+;*---------------------------------------------------------------------*/
+(define (slide-body-width e)
+ (let ((w (engine-custom e 'body-width)))
+ (if (or (number? w) (string? w)) w 95.)))
+
+;*---------------------------------------------------------------------*/
+;* html-slide-title ... */
+;*---------------------------------------------------------------------*/
+(define (html-slide-title n e)
+ (let* ((title (markup-body n))
+ (authors (markup-option n 'author))
+ (tbg (engine-custom e 'title-background))
+ (tfg (engine-custom e 'title-foreground))
+ (tfont (engine-custom e 'title-font)))
+ (printf "<center><table cellspacing='0' cellpadding='0' width=\"~a\" class=\"skribetitle\"><tbody>\n<tr>"
+ (html-width (slide-body-width e)))
+ (if (string? tbg)
+ (printf "<td bgcolor=\"~a\">" tbg)
+ (display "<td>"))
+ (if (string? tfg)
+ (printf "<font color=\"~a\">" tfg))
+ (if title
+ (begin
+ (display "<center>")
+ (if (string? tfont)
+ (begin
+ (printf "<font ~a><strong>" tfont)
+ (output title e)
+ (display "</strong></font>"))
+ (begin
+ (printf "<div class=\"skribetitle\"><strong><big><big><big>")
+ (output title e)
+ (display "</big></big></big></strong</div>")))
+ (display "</center>\n")))
+ (if (not authors)
+ (display "\n")
+ (html-title-authors authors e))
+ (if (string? tfg)
+ (display "</font>"))
+ (display "</td></tr></tbody></table></center>\n")))
+
+
+
+;;;
+;;; Slide topics/subtopics.
+;;;
+
+(markup-writer 'slide-topic (find-engine 'html)
+ :options '(:title :outline? :class :ident)
+ :action (lambda (n e)
+ (let ((title (markup-option n :title))
+ (body (markup-body n)))
+ (display "\n<h2 class=\"slide-topic:title\">")
+ (if (markup-ident n)
+ (printf "<a name=\"~a\"></a>" (markup-ident n)))
+ (output title e)
+ (display "</h2> <br>\n")
+ (display "\n<div class=\"slide-topic:slide-list\">")
+ (for-each (lambda (s)
+ (output (markup-option s :title) e)
+ (display "&nbsp;--&nbsp;"))
+ (filter (lambda (n)
+ (or (is-markup? n 'slide-subtopic)
+ (is-markup? n 'slide)))
+ (markup-body n)))
+ (display "\n</div> <!-- slide-topic:slide-list -->")
+ (display "\n<hr><br>\n")
+
+ ;; the slides
+ (output (markup-body n) e))))
+
+
+;;;
+;;; Initialization.
+;;;
+
+(%slide-html-initialize!)
+
+
+;;; arch-tag: 8be0cdf2-b755-4baa-baf6-739cdd00e193
diff --git a/src/guile/skribilo/package/slide/latex.scm b/src/guile/skribilo/package/slide/latex.scm
new file mode 100644
index 0000000..e187d3c
--- /dev/null
+++ b/src/guile/skribilo/package/slide/latex.scm
@@ -0,0 +1,394 @@
+;;; latex.scm -- LaTeX implementation of the `slide' package.
+;;;
+;;; Copyright 2003, 2004 Manuel Serrano
+;;;
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;; USA.
+
+(define-skribe-module (skribilo package slide latex)
+ :use-module (skribilo package slide))
+
+
+(define-public %slide-latex-mode 'seminar)
+
+(define-public (%slide-latex-initialize!)
+ (skribe-message "LaTeX slides setup...\n")
+ (case %slide-latex-mode
+ ((seminar)
+ (%slide-seminar-setup!))
+ ((advi)
+ (%slide-advi-setup!))
+ ((prosper)
+ (%slide-prosper-setup!))
+ (else
+ (skribe-error 'slide "Illegal latex mode" %slide-latex-mode))))
+
+
+;*---------------------------------------------------------------------*/
+;* &slide-seminar-predocument ... */
+;*---------------------------------------------------------------------*/
+(define &slide-seminar-predocument
+ "\\special{landscape}
+ \\slideframe{none}
+ \\centerslidesfalse
+ \\raggedslides[0pt]
+ \\renewcommand{\\slideleftmargin}{0.2in}
+ \\renewcommand{\\slidetopmargin}{0.3in}
+ \\newdimen\\slidewidth \\slidewidth 9in")
+
+;*---------------------------------------------------------------------*/
+;* &slide-seminar-maketitle ... */
+;*---------------------------------------------------------------------*/
+(define &slide-seminar-maketitle
+ "\\def\\labelitemi{$\\bullet$}
+ \\def\\labelitemii{$\\circ$}
+ \\def\\labelitemiii{$\\diamond$}
+ \\def\\labelitemiv{$\\cdot$}
+ \\pagestyle{empty}
+ \\slideframe{none}
+ \\centerslidestrue
+ \\begin{slide}
+ \\date{}
+ \\maketitle
+ \\end{slide}
+ \\slideframe{none}
+ \\centerslidesfalse")
+
+;*---------------------------------------------------------------------*/
+;* &slide-prosper-predocument ... */
+;*---------------------------------------------------------------------*/
+(define &slide-prosper-predocument
+ "\\slideCaption{}\n")
+
+;*---------------------------------------------------------------------*/
+;* latex */
+;*---------------------------------------------------------------------*/
+(define &latex-slide #f)
+(define &latex-pause #f)
+(define &latex-embed #f)
+(define &latex-record #f)
+(define &latex-play #f)
+(define &latex-play* #f)
+
+;;; FIXME: We shouldn't load `latex.scm' from here. Instead, we should
+;;; register a hook on its load.
+(let ((le (find-engine 'latex)))
+ ;; slide-vspace
+ (markup-writer 'slide-vspace le
+ :options '(:unit)
+ :action (lambda (n e)
+ (display "\n\\vspace{")
+ (output (markup-body n) e)
+ (printf " ~a}\n\n" (markup-option n :unit))))
+ ;; slide-slide
+ (markup-writer 'slide le
+ :options '(:title :number :transition :vfill :toc :vspace :image)
+ :action (lambda (n e)
+ (if (procedure? &latex-slide)
+ (&latex-slide n e))))
+ ;; slide-pause
+ (markup-writer 'slide-pause le
+ :options '()
+ :action (lambda (n e)
+ (if (procedure? &latex-pause)
+ (&latex-pause n e))))
+ ;; slide-embed
+ (markup-writer 'slide-embed le
+ :options '(:alt :command :geometry-opt :geometry
+ :rgeometry :transient :transient-opt)
+ :action (lambda (n e)
+ (if (procedure? &latex-embed)
+ (&latex-embed n e))))
+ ;; slide-record
+ (markup-writer 'slide-record le
+ :options '(:tag :play)
+ :action (lambda (n e)
+ (if (procedure? &latex-record)
+ (&latex-record n e))))
+ ;; slide-play
+ (markup-writer 'slide-play le
+ :options '(:tag :color)
+ :action (lambda (n e)
+ (if (procedure? &latex-play)
+ (&latex-play n e))))
+ ;; slide-play*
+ (markup-writer 'slide-play* le
+ :options '(:tag :color :scolor)
+ :action (lambda (n e)
+ (if (procedure? &latex-play*)
+ (&latex-play* n e)))))
+
+;*---------------------------------------------------------------------*/
+;* %slide-seminar-setup! ... */
+;*---------------------------------------------------------------------*/
+(define (%slide-seminar-setup!)
+ (skribe-message "Seminar slides setup...\n")
+ (let ((le (find-engine 'latex))
+ (be (find-engine 'base)))
+ ;; latex configuration
+ (define (seminar-slide n e)
+ (let ((nb (markup-option n :number))
+ (t (markup-option n :title)))
+ (display "\\begin{slide}\n")
+ (if nb (printf "~a/~a -- " nb (slide-number)))
+ (output t e)
+ (display "\\hrule\n"))
+ (output (markup-body n) e)
+ (if (markup-option n :vill) (display "\\vfill\n"))
+ (display "\\end{slide}\n"))
+ (engine-custom-set! le 'documentclass
+ "\\documentclass[landscape]{seminar}\n")
+ (let ((o (engine-custom le 'predocument)))
+ (engine-custom-set! le 'predocument
+ (if (string? o)
+ (string-append &slide-seminar-predocument o)
+ &slide-seminar-predocument)))
+ (engine-custom-set! le 'maketitle
+ &slide-seminar-maketitle)
+ (engine-custom-set! le 'hyperref-usepackage
+ "\\usepackage[setpagesize=false]{hyperref}\n")
+ ;; slide-slide
+ (set! &latex-slide seminar-slide)))
+
+;*---------------------------------------------------------------------*/
+;* %slide-advi-setup! ... */
+;*---------------------------------------------------------------------*/
+(define (%slide-advi-setup!)
+ (skribe-message "Generating `Advi Seminar' slides...\n")
+ (let ((le (find-engine 'latex))
+ (be (find-engine 'base)))
+ (define (advi-geometry geo)
+ (let ((r (pregexp-match "([0-9]+)x([0-9]+)" geo)))
+ (if (pair? r)
+ (let* ((w (cadr r))
+ (w' (string->integer w))
+ (w'' (number->string (/ w' *skribe-slide-advi-scale*)))
+ (h (caddr r))
+ (h' (string->integer h))
+ (h'' (number->string (/ h' *skribe-slide-advi-scale*))))
+ (values "" (string-append w "x" h "+!x+!y")))
+ (let ((r (pregexp-match "([0-9]+)x([0-9]+)[+](-?[0-9]+)[+](-?[0-9]+)" geo)))
+ (if (pair? r)
+ (let ((w (number->string (/ (string->integer (cadr r))
+ *skribe-slide-advi-scale*)))
+ (h (number->string (/ (string->integer (caddr r))
+ *skribe-slide-advi-scale*)))
+ (x (cadddr r))
+ (y (car (cddddr r))))
+ (values (string-append "width=" w "cm,height=" h "cm")
+ "!g"))
+ (values "" geo))))))
+ (define (advi-transition trans)
+ (cond
+ ((string? trans)
+ (printf "\\advitransition{~s}" trans))
+ ((and (symbol? trans)
+ (memq trans '(wipe block slide)))
+ (printf "\\advitransition{~s}" trans))
+ (else
+ #f)))
+ ;; latex configuration
+ (define (advi-slide n e)
+ (let ((i (markup-option n :image))
+ (n (markup-option n :number))
+ (t (markup-option n :title))
+ (lt (markup-option n :transition))
+ (gt (engine-custom e 'transition)))
+ (if (and i (engine-custom e 'advi))
+ (printf "\\advibg[global]{image=~a}\n"
+ (if (and (pair? i)
+ (null? (cdr i))
+ (string? (car i)))
+ (car i)
+ i)))
+ (display "\\begin{slide}\n")
+ (advi-transition (or lt gt))
+ (if n (printf "~a/~a -- " n (slide-number)))
+ (output t e)
+ (display "\\hrule\n"))
+ (output (markup-body n) e)
+ (if (markup-option n :vill) (display "\\vfill\n"))
+ (display "\\end{slide}\n\n\n"))
+ ;; advi record
+ (define (advi-record n e)
+ (display "\\advirecord")
+ (when (markup-option n :play) (display "[play]"))
+ (printf "{~a}{" (markup-option n :tag))
+ (output (markup-body n) e)
+ (display "}"))
+ ;; advi play
+ (define (advi-play n e)
+ (display "\\adviplay")
+ (let ((c (markup-option n :color)))
+ (when c
+ (display "[")
+ (display (skribe-get-latex-color c))
+ (display "]")))
+ (printf "{~a}" (markup-option n :tag)))
+ ;; advi play*
+ (define (advi-play* n e)
+ (let ((c (skribe-get-latex-color (markup-option n :color)))
+ (d (skribe-get-latex-color (markup-option n :scolor))))
+ (let loop ((lbls (markup-body n))
+ (last #f))
+ (when last
+ (display "\\adviplay[")
+ (display d)
+ (printf "]{~a}" last))
+ (when (pair? lbls)
+ (let ((lbl (car lbls)))
+ (match-case lbl
+ ((?id ?col)
+ (display "\\adviplay[")
+ (display (skribe-get-latex-color col))
+ (printf "]{" ~a "}" id)
+ (skribe-eval (slide-pause) e)
+ (loop (cdr lbls) id))
+ (else
+ (display "\\adviplay[")
+ (display c)
+ (printf "]{~a}" lbl)
+ (skribe-eval (slide-pause) e)
+ (loop (cdr lbls) lbl))))))))
+ (engine-custom-set! le 'documentclass
+ "\\documentclass{seminar}\n")
+ (let ((o (engine-custom le 'predocument)))
+ (engine-custom-set! le 'predocument
+ (if (string? o)
+ (string-append &slide-seminar-predocument o)
+ &slide-seminar-predocument)))
+ (engine-custom-set! le 'maketitle
+ &slide-seminar-maketitle)
+ (engine-custom-set! le 'usepackage
+ (string-append "\\usepackage{advi}\n"
+ (engine-custom le 'usepackage)))
+ ;; slide
+ (set! &latex-slide advi-slide)
+ (set! &latex-pause
+ (lambda (n e) (display "\\adviwait\n")))
+ (set! &latex-embed
+ (lambda (n e)
+ (let ((geometry-opt (markup-option n :geometry-opt))
+ (geometry (markup-option n :geometry))
+ (rgeometry (markup-option n :rgeometry))
+ (transient (markup-option n :transient))
+ (transient-opt (markup-option n :transient-opt))
+ (cmd (markup-option n :command)))
+ (let* ((a (string-append "ephemeral="
+ (symbol->string (gensym))))
+ (c (cond
+ (geometry
+ (string-append cmd " "
+ geometry-opt " "
+ geometry))
+ (rgeometry
+ (multiple-value-bind (aopt dopt)
+ (advi-geometry rgeometry)
+ (set! a (string-append a "," aopt))
+ (string-append cmd " "
+ geometry-opt " "
+ dopt)))
+ (else
+ cmd)))
+ (c (if (and transient transient-opt)
+ (string-append c " " transient-opt " !p")
+ c)))
+ (printf "\\adviembed[~a]{~a}\n" a c)))))
+ (set! &latex-record advi-record)
+ (set! &latex-play advi-play)
+ (set! &latex-play* advi-play*)))
+
+;*---------------------------------------------------------------------*/
+;* %slide-prosper-setup! ... */
+;*---------------------------------------------------------------------*/
+(define (%slide-prosper-setup!)
+ (skribe-message "Generating `Prosper' slides...\n")
+ (let ((le (find-engine 'latex))
+ (be (find-engine 'base))
+ (overlay-count 0))
+ ;; transitions
+ (define (prosper-transition trans)
+ (cond
+ ((string? trans)
+ (printf "[~s]" trans))
+ ((eq? trans 'slide)
+ (printf "[Blinds]"))
+ ((and (symbol? trans)
+ (memq trans '(split blinds box wipe dissolve glitter)))
+ (printf "[~s]"
+ (string-upcase (symbol->string trans))))
+ (else
+ #f)))
+ ;; latex configuration
+ (define (prosper-slide n e)
+ (let* ((i (markup-option n :image))
+ (t (markup-option n :title))
+ (lt (markup-option n :transition))
+ (gt (engine-custom e 'transition))
+ (pa (search-down (lambda (x) (is-markup? x 'slide-pause)) n))
+ (lpa (length pa)))
+ (set! overlay-count 1)
+ (if (>= lpa 1) (printf "\\overlays{~a}{%\n" (+ 1 lpa)))
+ (display "\\begin{slide}")
+ (prosper-transition (or lt gt))
+ (display "{")
+ (output t e)
+ (display "}\n")
+ (output (markup-body n) e)
+ (display "\\end{slide}\n")
+ (if (>= lpa 1) (display "}\n"))
+ (newline)
+ (newline)))
+ (engine-custom-set! le 'documentclass "\\documentclass[pdf,skribe,slideColor,nototal]{prosper}\n")
+ (let* ((cap (engine-custom le 'slide-caption))
+ (o (engine-custom le 'predocument))
+ (n (if (string? cap)
+ (format #f "~a\\slideCaption{~a}\n"
+ &slide-prosper-predocument
+ cap)
+ &slide-prosper-predocument)))
+ (engine-custom-set! le 'predocument
+ (if (string? o) (string-append n o) n)))
+ (engine-custom-set! le 'hyperref-usepackage "\\usepackage{hyperref}\n")
+ ;; writers
+ (set! &latex-slide prosper-slide)
+ (set! &latex-pause
+ (lambda (n e)
+ (set! overlay-count (+ 1 overlay-count))
+ (printf "\\FromSlide{~s}%\n" overlay-count)))))
+
+;*---------------------------------------------------------------------*/
+;* Setup ... */
+;*---------------------------------------------------------------------*/
+(let* ((opt &slide-load-options)
+ (p (memq :prosper opt)))
+ (if (and (pair? p) (pair? (cdr p)) (cadr p))
+ ;; prosper
+ (set! %slide-latex-mode 'prosper)
+ (let ((a (memq :advi opt)))
+ (if (and (pair? a) (pair? (cdr a)) (cadr a))
+ ;; advi
+ (set! %slide-latex-mode 'advi)))))
+
+
+
+;;;
+;;; Initialization.
+;;;
+
+(%slide-latex-initialize!)
+
+;;; arch-tag: b99e2c65-55f7-462c-8482-f47c7e223538
diff --git a/src/guile/skribilo/package/slide/lout.scm b/src/guile/skribilo/package/slide/lout.scm
new file mode 100644
index 0000000..d53cff1
--- /dev/null
+++ b/src/guile/skribilo/package/slide/lout.scm
@@ -0,0 +1,151 @@
+;;; lout.scm -- Lout implementation of the `slide' package.
+;;;
+;;; Copyright 2005, 2006 Ludovic Courtès <ludovic.courtes@laas.fr>
+;;;
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;; USA.
+
+(define-skribe-module (skribilo package slide lout)
+ :use-module (skribilo utils syntax)
+
+ ;; XXX: If changing the following `autoload' to `use-module' doesn't work,
+ ;; then you need to fix your Guile. See this thread about
+ ;; `make-autoload-interface':
+ ;;
+ ;; http://article.gmane.org/gmane.lisp.guile.devel/5748
+ ;; http://lists.gnu.org/archive/html/guile-devel/2006-03/msg00004.html .
+
+ :autoload (skribilo engine lout) (lout-tagify lout-output-pdf-meta-info
+ lout-verbatim-encoding))
+
+
+(fluid-set! current-reader %skribilo-module-reader)
+
+;;; TODO:
+;;;
+;;; Make some more PS/PDF trickery.
+
+(format (current-error-port) "Lout slides setup...~%")
+
+(let ((le (find-engine 'lout)))
+
+ ;; FIXME: Automatically switching to `slides' is problematic, e.g., for the
+ ;; user manual which embeds slides.
+; ;; Automatically switch to the `slides' document type.
+; (engine-custom-set! le 'document-type 'slides))
+
+ (markup-writer 'slide le
+ :options '(:title :number :toc :ident) ;; '(:bg :vspace :image)
+
+ :validate (lambda (n e)
+ (eq? (engine-custom e 'document-type) 'slides))
+
+ :before (lambda (n e)
+ (display "\n@Overhead\n")
+ (display " @Title { ")
+ (output (markup-option n :title) e)
+ (display " }\n")
+ (if (markup-ident n)
+ (begin
+ (display " @Tag { ")
+ (display (lout-tagify (markup-ident n)))
+ (display " }\n")))
+ (if (markup-option n :number)
+ (begin
+ (display " @BypassNumber { ")
+ (output (markup-option n :number) e)
+ (display " }\n")))
+ (display "@Begin\n")
+
+ ;; `doc' documents produce their PDF outline right after
+ ;; `@Text @Begin'; other types of documents must produce it
+ ;; as part of their first chapter.
+ (lout-output-pdf-meta-info (ast-document n) e))
+
+ :after "@End @Overhead\n")
+
+ (markup-writer 'slide-vspace le
+ :options '(:unit)
+ :validate (lambda (n e)
+ (and (pair? (markup-body n))
+ (number? (car (markup-body n)))))
+ :action (lambda (n e)
+ (printf "\n//~a~a # slide-vspace\n"
+ (car (markup-body n))
+ (case (markup-option n :unit)
+ ((cm) "c")
+ ((point points pt) "p")
+ ((inch inches) "i")
+ (else
+ (skribe-error 'lout
+ "Unknown vspace unit"
+ (markup-option n :unit)))))))
+
+ (markup-writer 'slide-pause le
+ ;; FIXME: Use a `pdfmark' custom action and a PDF transition action.
+ ;; << /Type /Action
+ ;; << /S /Trans
+ ;; entry in the trans dict
+ ;; << /Type /Trans /S /Dissolve >>
+ :action (lambda (n e)
+ (let ((filter (make-string-replace lout-verbatim-encoding))
+ (pdfmark "
+[ {ThisPage} << /Trans << /S /Wipe /Dm /V /D 3 /M /O >> >> /PUT pdfmark"))
+ (display (lout-embedded-postscript-code
+ (filter pdfmark))))))
+
+ ;; For movies, see
+ ;; http://www.tug.org/tex-archive/macros/latex/contrib/movie15/movie15.sty .
+ (markup-writer 'slide-embed le
+ :options '(:alt :geometry :rgeometry :geometry-opt :command)
+ ;; FIXME: `pdfmark'.
+ ;; << /Type /Action /S /Launch
+ :action (lambda (n e)
+ (let ((command (markup-option n :command))
+ (filter (make-string-replace lout-verbatim-encoding))
+ (pdfmark "[ /Rect [ 0 ysize xsize 0 ]
+/Name /Comment
+/Contents (This is an embedded application)
+/ANN pdfmark
+
+[ /Type /Action
+/S /Launch
+/F (~a)
+/OBJ pdfmark"))
+ (display (string-append
+ "4c @Wide 3c @High "
+ (lout-embedded-postscript-code
+ (filter (format #f pdfmark command)))))))))
+
+
+
+;;;
+;;; Customs for a nice handling of topics/subtopics.
+;;;
+
+(let ((lout (find-engine 'lout)))
+ (if lout
+ (begin
+ (engine-custom-set! lout 'pdf-bookmark-node-pred
+ (lambda (n e)
+ (or (is-markup? n 'slide)
+ (is-markup? n 'slide-topic)
+ (is-markup? n 'slide-subtopic))))
+ (engine-custom-set! lout 'pdf-bookmark-closed-pred
+ (lambda (n e) #f)))))
+
+
+;;; arch-tag: 0c717553-5cbb-46ed-937a-f844b6aeb145
diff --git a/src/guile/skribilo/package/web-article.scm b/src/guile/skribilo/package/web-article.scm
new file mode 100644
index 0000000..6d1b7a5
--- /dev/null
+++ b/src/guile/skribilo/package/web-article.scm
@@ -0,0 +1,241 @@
+;;; web-article.scm -- A Skribe style for producing web articles
+;;;
+;;; Copyright 2003, 2004 Manuel Serrano
+;;;
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;; USA.
+
+(define-skribe-module (skribilo package web-article))
+
+;*---------------------------------------------------------------------*/
+;* &web-article-load-options ... */
+;*---------------------------------------------------------------------*/
+(define &web-article-load-options (skribe-load-options))
+
+;*---------------------------------------------------------------------*/
+;* web-article-body-width ... */
+;*---------------------------------------------------------------------*/
+(define (web-article-body-width e)
+ (let ((w (engine-custom e 'body-width)))
+ (if (or (number? w) (string? w)) w 98.)))
+
+;*---------------------------------------------------------------------*/
+;* html-document-title-web ... */
+;*---------------------------------------------------------------------*/
+(define (html-document-title-web n e)
+ (let* ((title (markup-body n))
+ (authors (markup-option n 'author))
+ (tbg (engine-custom e 'title-background))
+ (tfg (engine-custom e 'title-foreground))
+ (tfont (engine-custom e 'title-font)))
+ (printf "<center><table cellspacing='0' cellpadding='0' width=\"~a\" class=\"skribetitle\"><tbody>\n<tr>"
+ (html-width (web-article-body-width e)))
+ (if (string? tbg)
+ (printf "<td bgcolor=\"~a\">" tbg)
+ (display "<td>"))
+ (if (string? tfg)
+ (printf "<font color=\"~a\">" tfg))
+ (if title
+ (begin
+ (display "<center>")
+ (if (string? tfont)
+ (begin
+ (printf "<font ~a><b>" tfont)
+ (output title e)
+ (display "</b></font>"))
+ (begin
+ (printf "<h1>")
+ (output title e)
+ (display "</h1>")))
+ (display "</center>\n")))
+ (if (not authors)
+ (display "\n")
+ (html-title-authors authors e))
+ (if (string? tfg)
+ (display "</font>"))
+ (display "</td></tr></tbody></table></center>\n")))
+
+;*---------------------------------------------------------------------*/
+;* web-article-css-document-title ... */
+;*---------------------------------------------------------------------*/
+(define (web-article-css-document-title n e)
+ (let* ((title (markup-body n))
+ (authors (markup-option n 'author))
+ (id (markup-ident n)))
+ ;; the title
+ (printf "<div id=\"~a\" class=\"document-title-title\">\n"
+ (string-canonicalize id))
+ (output title e)
+ (display "</div>\n")
+ ;; the authors
+ (printf "<div id=\"~a\" class=\"document-title-authors\">\n"
+ (string-canonicalize id))
+ (for-each (lambda (a) (output a e))
+ (cond
+ ((is-markup? authors 'author)
+ (list authors))
+ ((list? authors)
+ authors)
+ (else
+ '())))
+ (display "</div>\n")))
+
+;*---------------------------------------------------------------------*/
+;* web-article-css-author ... */
+;*---------------------------------------------------------------------*/
+(define (web-article-css-author n e)
+ (let ((name (markup-option n :name))
+ (title (markup-option n :title))
+ (affiliation (markup-option n :affiliation))
+ (email (markup-option n :email))
+ (url (markup-option n :url))
+ (address (markup-option n :address))
+ (phone (markup-option n :phone))
+ (nfn (engine-custom e 'author-font))
+ (align (markup-option n :align)))
+ (when name
+ (printf "<span class=\"document-author-name\" id=\"~a\">"
+ (string-canonicalize (markup-ident n)))
+ (output name e)
+ (display "</span>\n"))
+ (when title
+ (printf "<span class=\"document-author-title\" id=\"~a\">"
+ (string-canonicalize (markup-ident n)))
+ (output title e)
+ (display "</span>\n"))
+ (when affiliation
+ (printf "<span class=\"document-author-affiliation\" id=\"~a\">"
+ (string-canonicalize (markup-ident n)))
+ (output affiliation e)
+ (display "</span>\n"))
+ (when (pair? address)
+ (printf "<span class=\"document-author-address\" id=\"~a\">"
+ (string-canonicalize (markup-ident n)))
+ (for-each (lambda (a)
+ (output a e)
+ (newline))
+ address)
+ (display "</span>\n"))
+ (when phone
+ (printf "<span class=\"document-author-phone\" id=\"~a\">"
+ (string-canonicalize (markup-ident n)))
+ (output phone e)
+ (display "</span>\n"))
+ (when email
+ (printf "<span class=\"document-author-email\" id=\"~a\">"
+ (string-canonicalize (markup-ident n)))
+ (output email e)
+ (display "</span>\n"))
+ (when url
+ (printf "<span class=\"document-author-url\" id=\"~a\">"
+ (string-canonicalize (markup-ident n)))
+ (output url e)
+ (display "</span>\n"))))
+
+;*---------------------------------------------------------------------*/
+;* HTML settings */
+;*---------------------------------------------------------------------*/
+(define (web-article-modern-setup he)
+ (let ((sec (markup-writer-get 'section he))
+ (ft (markup-writer-get '&html-footnotes he)))
+ ;; &html-document-title
+ (markup-writer '&html-document-title he
+ :action html-document-title-web)
+ ;; section
+ (markup-writer 'section he
+ :options 'all
+ :before "<br>"
+ :action (lambda (n e)
+ (let ((e1 (make-engine 'html-web :delegate e))
+ (bg (engine-custom he 'section-background)))
+ (markup-writer 'section e1
+ :options 'all
+ :action (lambda (n e2) (output n e sec)))
+ (skribe-eval
+ (center (color :width (web-article-body-width e)
+ :margin 5 :bg bg n))
+ e1))))
+ ;; &html-footnotes
+ (markup-writer '&html-footnotes he
+ :options 'all
+ :before "<br>"
+ :action (lambda (n e)
+ (let ((e1 (make-engine 'html-web :delegate e))
+ (bg (engine-custom he 'section-background))
+ (fg (engine-custom he 'subsection-title-foreground)))
+ (markup-writer '&html-footnotes e1
+ :options 'all
+ :action (lambda (n e2)
+ (invoke (writer-action ft) n e)))
+ (skribe-eval
+ (center (color :width (web-article-body-width e)
+ :margin 5 :bg bg :fg fg n))
+ e1))))))
+
+;*---------------------------------------------------------------------*/
+;* web-article-css-setup ... */
+;*---------------------------------------------------------------------*/
+(define (web-article-css-setup he)
+ (let ((sec (markup-writer-get 'section he))
+ (ft (markup-writer-get '&html-footnotes he)))
+ ;; &html-document-title
+ (markup-writer '&html-document-title he
+ :before (lambda (n e)
+ (printf "<div id=\"~a\" class=\"document-title\">\n"
+ (string-canonicalize (markup-ident n))))
+ :action web-article-css-document-title
+ :after "</div>\n")
+ ;; author
+ (markup-writer 'author he
+ :options '(:name :title :affiliation :email :url :address :phone :photo :align)
+ :before (lambda (n e)
+ (printf "<span id=\"~a\" class=\"document-author\">\n"
+ (string-canonicalize (markup-ident n))))
+ :action web-article-css-author
+ :after "</span\n")
+ ;; section
+ (markup-writer 'section he
+ :options 'all
+ :before (lambda (n e)
+ (printf "<div class=\"section\" id=\"~a\">"
+ (string-canonicalize (markup-ident n))))
+ :action (lambda (n e) (output n e sec))
+ :after "</div>\n")
+ ;; &html-footnotes
+ (markup-writer '&html-footnotes he
+ :options 'all
+ :before (lambda (n e)
+ (printf "<div class=\"footnotes\" id=\"~a\">"
+ (string-canonicalize (markup-ident n))))
+ :action (lambda (n e)
+ (output n e ft))
+ :after "</div>\n")))
+
+;*---------------------------------------------------------------------*/
+;* Setup ... */
+;*---------------------------------------------------------------------*/
+(let* ((opt &web-article-load-options)
+ (p (memq :style opt))
+ (css (memq :css opt))
+ (he (find-engine 'html)))
+ (cond
+ ((and (pair? p) (pair? (cdr p)) (eq? (cadr p) 'css))
+ (web-article-css-setup he))
+ ((and (pair? css) (pair? (cdr css)) (string? (cadr css)))
+ (engine-custom-set! he 'css (cadr css))
+ (web-article-css-setup he))
+ (else
+ (web-article-modern-setup he))))
diff --git a/src/guile/skribilo/package/web-book.scm b/src/guile/skribilo/package/web-book.scm
new file mode 100644
index 0000000..49197f1
--- /dev/null
+++ b/src/guile/skribilo/package/web-book.scm
@@ -0,0 +1,121 @@
+;;; web-book.scm -- The Skribe web book style.
+;;;
+;;; Copyright 2003, 2004 Manuel Serrano
+;;;
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;; USA.
+
+(define-skribe-module (skribilo package web-book))
+
+;*---------------------------------------------------------------------*/
+;* html customization */
+;*---------------------------------------------------------------------*/
+(define he (find-engine 'html))
+(engine-custom-set! he 'main-browsing-extra #f)
+(engine-custom-set! he 'chapter-file #t)
+
+;*---------------------------------------------------------------------*/
+;* main-browsing ... */
+;*---------------------------------------------------------------------*/
+(define main-browsing
+ (lambda (n e)
+ ;; search the document
+ (let ((p (ast-document n)))
+ (cond
+ ((document? p)
+ ;; got it
+ (let* ((mt (markup-option p :margin-title))
+ (r (ref :handle (handle p)
+ :text (or mt (markup-option p :title))))
+ (fx (engine-custom e 'web-book-main-browsing-extra)))
+ (center
+ (table :width 97. :border 1 :frame 'box
+ :cellpadding 0 :cellspacing 0
+ (tr :bg (engine-custom e 'title-background)
+ (th (let ((text (bold "main page"))
+ (bg (engine-custom e 'background)))
+ (if bg (color :fg bg text) text))))
+ (tr :bg (engine-custom e 'background)
+ (td (apply table :width 100. :border 0
+ (tr (td :align 'left
+ :valign 'top
+ (bold "top:"))
+ (td :align 'right
+ :valign 'top r))
+ (if (procedure? fx)
+ (list (tr (td :width 100.
+ :colspan 2
+ (fx n e))))
+ '()))))))))
+ ((not p)
+ ;; no document!!!
+ #f)))))
+
+;*---------------------------------------------------------------------*/
+;* chapter-browsing ... */
+;*---------------------------------------------------------------------*/
+(define chapter-browsing
+ (lambda (n e)
+ (center
+ (table :width 97. :border 1 :frame 'box
+ :cellpadding 0 :cellspacing 0
+ (tr :bg (engine-custom e 'title-background)
+ (th (let ((title (bold (markup-option n :title)))
+ (bg (engine-custom e 'background)))
+ (if bg (color :fg title) title))))
+ (tr :bg (engine-custom e 'background)
+ (td (toc (handle n) :chapter #t :section #t :subsection #t)))))))
+
+;*---------------------------------------------------------------------*/
+;* document-browsing ... */
+;*---------------------------------------------------------------------*/
+(define document-browsing
+ (lambda (n e)
+ (let ((chap (find1-down (lambda (n)
+ (is-markup? n 'chapter))
+ n)))
+ (center
+ (table :width 97. :border 1 :frame 'box
+ :cellpadding 0 :cellspacing 0
+ (tr :bg (engine-custom e 'title-background)
+ (th (let ((text (bold (if chap "Chapters" "Sections")))
+ (bg (engine-custom e 'background)))
+ (if bg (color :fg bg text) text))))
+ (tr :bg (engine-custom e 'background)
+ (td (if chap
+ (toc (handle n) :chapter #t :section #f)
+ (toc (handle n) :section #t :subsection #t)))))))))
+
+;*---------------------------------------------------------------------*/
+;* left margin ... */
+;*---------------------------------------------------------------------*/
+(engine-custom-set! he 'left-margin-size 20.)
+
+(engine-custom-set! he 'left-margin
+ (lambda (n e)
+ (let ((d (ast-document n))
+ (c (ast-chapter n)))
+ (list (linebreak 1)
+ (main-browsing n e)
+ (if (is-markup? c 'chapter)
+ (list (linebreak 2)
+ (chapter-browsing c e))
+ #f)
+ (if (document? d)
+ (list (linebreak 2)
+ (document-browsing d e))
+ #f)))))
+