From f5fb6bf60e3806f2150430ee5d9d1023ca068f73 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 23 Jan 2013 19:02:03 -0500 Subject: [PATCH] scriblib/figure: overhaul Clean up the use of styles for alignment and the generated instances of style names. In the process, remove some padding for HTML output, and make the rendering more configurable (especially for Latex, based on suggestions by Keven Tew). The way that nested flows are generated can be different than before, so these changes risk breaking some existing uses of `scriblib/figure'. The changes especially likely break uses of `scriblib/figure' with output configured through overiding .css/.tex definitions. But the old pile of styles/macros was inconsistent and broken in various ways, so hopefully the changes are an improvement overall. original commit: 8862a44f149e9a8fb975f63147730cb19a4a7931 --- collects/scriblib/figure.css | 33 +++++---- collects/scriblib/figure.rkt | 79 ++++++++++++---------- collects/scriblib/figure.tex | 26 ++++--- collects/scriblib/private/counter.rkt | 78 +++++++++++++-------- collects/scriblib/scribblings/figure.scrbl | 64 +++++++++++++++--- 5 files changed, 179 insertions(+), 101 deletions(-) diff --git a/collects/scriblib/figure.css b/collects/scriblib/figure.css index 92fec05c..905d5b67 100644 --- a/collects/scriblib/figure.css +++ b/collects/scriblib/figure.css @@ -4,31 +4,34 @@ margin: 0 0 0 0; } -.Centerfigure, .CenterfigureMulti, .centerfigureMultiWide, .Herefigure { +.Figure, .FigureMulti, .FigureMultiWide, .Herefigure { + margin: 1em 0 1em 0; + border: 1px solid #1818FF; +} + +.Figure, .FigureMulti, .Herefigure { + width: 100%; +} + +.FigureMultiWide { + width: 125%; +} + +.Centerfigure { text-align: center; margin: 0 0 0 0; } -.Leftfigure, .LeftfigureMulti, .leftfigureMultiWide { +.Leftfigure { text-align: left; margin: 0 0 0 0; } -.Figure { - margin: 1em 0 1em 0; - width: 100%; - border: 1px solid #1818FF; -} - -.CenterfigureMultiWide { - width: 125%; +.Rightfigure { + text-align: right; + margin: 0 0 0 0; } .FigureInside { margin: 1em 1em 1em 1em; } - -.Caption:before { - content: "Figure: "; -} - diff --git a/collects/scriblib/figure.rkt b/collects/scriblib/figure.rkt index d9bbad80..c24b9dcf 100644 --- a/collects/scriblib/figure.rkt +++ b/collects/scriblib/figure.rkt @@ -15,9 +15,10 @@ Figure-target Figure-ref figure-ref - (rename-out [leftfigure-style left] - [leftfiguremulti-style leftfiguremulti] - [leftfiguremultiwide-style leftfiguremultiwide])) + left-figure-style + center-figure-style + right-figure-style + (rename-out [left-figure-style left])) (define figure-style-extras (let ([abs (lambda (s) @@ -26,56 +27,60 @@ (list (make-css-addition (abs "figure.css")) (make-tex-addition (abs "figure.tex"))))) +;; outer layer: (define herefigure-style (make-style "Herefigure" figure-style-extras)) +(define figure-style (make-style "Figure" figure-style-extras)) +(define figuremulti-style (make-style "FigureMulti" figure-style-extras)) +(define figuremultiwide-style (make-style "FigureMultiWide" figure-style-extras)) + +;; middle layer: +(define center-figure-style (make-style "Centerfigure" figure-style-extras)) +(define left-figure-style (make-style "Leftfigure" figure-style-extras)) +(define right-figure-style (make-style "Rightfigure" figure-style-extras)) + +;; inner layer: (define figureinside-style (make-style "FigureInside" figure-style-extras)) + (define legend-style (make-style "Legend" figure-style-extras)) -(define figure-target-style (make-style "FigureTarget" figure-style-extras)) (define centertext-style (make-style "Centertext" figure-style-extras)) -(define figure-style (make-style "Figure" figure-style-extras)) -(define centerfigure-style (make-style "Centerfigure" figure-style-extras)) -(define centerfiguremulti-style (make-style "CenterfigureMulti" figure-style-extras)) -(define centerfiguremultiwide-style (make-style "CenterfigureMultiWide" figure-style-extras)) +(define (make-figure-ref c s) + (element (style "FigureRef" (list* (command-extras (list s)) + figure-style-extras)) + c)) +(define (make-figure-target c s) + (element (style "FigureTarget" (cons (command-extras (list s)) + figure-style-extras)) + c)) -(define leftfigure-style (make-style "Leftfigure" figure-style-extras)) -(define leftfiguremulti-style (make-style "LeftfigureMulti" figure-style-extras)) -(define leftfiguremultiwide-style (make-style "LeftfigureMultiWide" figure-style-extras)) +(define (figure tag caption #:style [style center-figure-style] . content) + (figure-helper figure-style style tag caption content)) -(define (figure tag caption #:style [style centerfigure-style] . content) - (apply figure-helper figure-style style tag caption content)) +(define (figure-here tag caption #:style [style center-figure-style] . content) + (figure-helper herefigure-style style tag caption content)) -(define (figure-here tag caption . content) - (apply figure-helper herefigure-style centerfigure-style tag caption content)) +(define (figure* tag caption #:style [style center-figure-style] . content) + (figure-helper figuremulti-style style tag caption content)) +(define (figure** tag caption #:style [style center-figure-style] . content) + (figure-helper figuremultiwide-style style tag caption content)) -(define (figure-helper figure-style content-style tag caption . content) +(define (figure-helper figure-style content-style tag caption content) (make-nested-flow figure-style - (list - (make-nested-flow content-style (list (make-nested-flow figureinside-style (decode-flow content)))) - (make-paragraph centertext-style (list (make-element legend-style (list (make-element figure-target-style (list (Figure-target tag) ": ")) caption))))))) - -(define (*figure style tag caption content) - (make-nested-flow - style (list (make-nested-flow - figureinside-style - (append - (decode-flow content) - (list - (make-paragraph - plain - (list (make-element legend-style (list (make-element figure-target-style (list (Figure-target tag) ": ")) caption)))))))))) + content-style + (list (make-nested-flow figureinside-style (decode-flow content)))) + (make-paragraph + centertext-style + (list (make-element legend-style (list (Figure-target tag) caption))))))) -(define (figure* tag caption . content) - (*figure centerfiguremulti-style tag caption content)) -(define (figure** tag caption . content) - (*figure centerfiguremultiwide-style tag caption content)) - -(define figures (new-counter "figure")) +(define figures (new-counter "figure" + #:target-wrap make-figure-target + #:ref-wrap make-figure-ref)) (define (Figure-target tag) - (counter-target figures tag "Figure")) + (counter-target figures tag "Figure" ": ")) (define (ref-proc initial) (case-lambda diff --git a/collects/scriblib/figure.tex b/collects/scriblib/figure.tex index 9f58e972..b3da0eae 100644 --- a/collects/scriblib/figure.tex +++ b/collects/scriblib/figure.tex @@ -12,21 +12,25 @@ \vspace{4pt} \legend{#1}} -\newcommand{\FigureTarget}[1]{#1} +\newcommand{\FigureTarget}[2]{#1} +\newcommand{\FigureRef}[2]{#1} \newlength{\FigOrigskip} \FigOrigskip=\parskip \newenvironment{Figure}{\begin{figure}}{\end{figure}} - -\newenvironment{Centerfigure}{\begin{center}}{\end{center}} -\def\Centertext#1{\begin{center}#1\end{center}} - -\newenvironment{Leftfigure}{\begin{flushleft}}{\end{flushleft}} - -\newenvironment{CenterfigureMulti}{\begin{figure*}[t!p]\centering}{\end{figure*}} -\newenvironment{CenterfigureMultiWide}{\begin{CenterfigureMulti}}{\end{CenterfigureMulti}} - +\newenvironment{FigureMulti}{\begin{figure*}[t!p]}{\end{figure*}} +\newenvironment{FigureMultiWide}{\begin{FigureMulti}}{\end{FigureMulti}} \newenvironment{Herefigure}{\begin{figure}[ht!]\centering}{\end{figure}} -\newenvironment{FigureInside}{\begin{list}{}{\leftmargin=0pt\topsep=0pt\parsep=\FigOrigskip\partopsep=0pt}\item}{\end{list}} +\newenvironment{Centerfigure}{\begin{Xfigure}\centering\item}{\end{Xfigure}} +\newenvironment{Leftfigure}{\begin{Xfigure}\item}{\end{Xfigure}} +\newenvironment{Rightfigure}{\begin{Xfigure}\item}{\end{Xfigure}} + +\newenvironment{Xfigure}{\begin{list}{}{\leftmargin=0pt\topsep=0pt\parsep=\FigOrigskip\partopsep=0pt}}{\end{list}} + +\newenvironment{FigureInside}{}{} + +\newcommand{\Centertext}[1]{\begin{center}#1\end{center}} + + diff --git a/collects/scriblib/private/counter.rkt b/collects/scriblib/private/counter.rkt index f650b6e5..a1d646bc 100644 --- a/collects/scriblib/private/counter.rkt +++ b/collects/scriblib/private/counter.rkt @@ -1,5 +1,5 @@ #lang scheme -(require scribble/struct +(require scribble/core scribble/decode) (provide new-counter @@ -7,43 +7,67 @@ counter-ref counter-collect-value) -(define-struct counter ([n #:mutable] name)) +(define-struct counter ([n #:mutable] name target-wrap ref-wrap)) -(define (new-counter name) - (make-counter 0 name)) +(define (new-counter name + #:target-wrap [target-wrap (lambda (c s) c)] + #:ref-wrap [ref-wrap (lambda (c s) c)]) + (make-counter 0 name target-wrap ref-wrap)) (define (counter-target counter tag label . content) (let ([content (decode-content content)]) - (make-target-element - #f - (list - (make-collect-element + (define c + (make-target-element #f (list - (make-delayed-element - (lambda (renderer part ri) - (let ([n (resolve-get part ri `(counter (,(counter-name counter) ,tag "value")))]) - (let ([l (cons (format "~a" n) content)]) - (if label - (list* label 'nbsp l) - l)))) - (lambda () (if label - (list* label 'nbsp "N" content) - (cons "N" content))) - (lambda () (if label - (list* label 'nbsp "N" content) - (cons "N" content))))) - (lambda (ci) - (let ([n (add1 (counter-n counter))]) - (set-counter-n! counter n) - (collect-put! ci `(counter (,(counter-name counter) ,tag "value")) n))))) - `(counter (,(counter-name counter) ,tag))))) + (make-collect-element + #f + (list + (make-delayed-element + (lambda (renderer part ri) + (let ([n (resolve-get part ri `(counter (,(counter-name counter) ,tag "value")))]) + (let ([l (cons (format "~a" n) content)]) + (if label + (list* label 'nbsp l) + l)))) + (lambda () (if label + (list* label 'nbsp "N" content) + (cons "N" content))) + (lambda () (if label + (list* label 'nbsp "N" content) + (cons "N" content))))) + (lambda (ci) + (let ([n (add1 (counter-n counter))]) + (set-counter-n! counter n) + (collect-put! ci `(counter (,(counter-name counter) ,tag "value")) n))))) + `(counter (,(counter-name counter) ,tag)))) + (if (counter-target-wrap counter) + ((counter-target-wrap counter) + c + (format "t:~a" (t-encode (list 'counter (list (counter-name counter) tag))))) + c))) + +(define (t-encode s) + (string-append* + (map (lambda (c) + (cond + [(and (or (char-alphabetic? c) (char-numeric? c)) + ((char->integer c) . < . 128)) + (string c)] + [(char=? c #\space) "_"] + [else (format "x~x" (char->integer c))])) + (string->list (format "~s" s))))) (define (counter-ref counter tag label) (let ([n (make-delayed-element (lambda (renderer part ri) (let ([n (resolve-get part ri `(counter (,(counter-name counter) ,tag "value")))]) - (list (format "~a" n)))) + (if (counter-ref-wrap counter) + (let ([id (format "t:~a" (t-encode (list 'counter (list (counter-name counter) tag))))]) + ((counter-ref-wrap counter) + (format "~a" n) + id)) + (list (format "~a" n))))) (lambda () (if label (list label 'nbsp "N") (list "N"))) diff --git a/collects/scriblib/scribblings/figure.scrbl b/collects/scriblib/scribblings/figure.scrbl index 25e5c443..da2feac6 100644 --- a/collects/scriblib/scribblings/figure.scrbl +++ b/collects/scriblib/scribblings/figure.scrbl @@ -5,6 +5,8 @@ scheme/base scheme/contract)) +@(define-syntax-rule (sn s) @racket[s]) + @title[#:tag "figure"]{Figures} @defmodule[scriblib/figure] @@ -14,7 +16,7 @@ @defproc[(figure* [tag string?] [caption content?] [#:style style style?] [p pre-flow?] ...) block?] @defproc[(figure** [tag string?] [caption content?] [#:style style style?] [p pre-flow?] ...) block?] -@defproc[(figure-here [tag string?] [caption content?] [pre-flow pre-flow?] ...) block?] +@defproc[(figure-here [tag string?] [caption content?] [#:style style style?] [pre-flow pre-flow?] ...) block?] )]{ Creates a figure. The given @racket[tag] is for use with @@ -22,24 +24,30 @@ Creates a figure. The given @racket[tag] is for use with element. The @racket[pre-flow] is decoded as a flow. For HTML output, the @racket[figure] and @racket[figure*] functions -center the figure content, while @racket[figure**] allows the content -to be wider than the document body. -For two-column Latex output, @racket[figure*] and @racket[figure**] -generate a figure that spans columns. +are the same, while @racket[figure**] allows the content to be wider +than the document body. For two-column Latex output, @racket[figure*] +and @racket[figure**] generate a figure that spans columns. For Latex output, @racket[figure-here] generates a figure to be included at the position in the output text where the @racket[figure-here] occurs in the source text. For HTML output, all @racket[figure] variants place the figure where the use appears in the source text. -By default @racket[style] is set so that the content of the figure is centered. -For a figure that demands left-aligned text, use @racket[left]. +By default, @racket[style] is set so that the content of the figure is +centered. Use @racket[left-figure-style], @racket[center-figure-style], +or @racket[right-figure-style] to specify the alignment.} -} +@deftogether[( +@defthing[left-figure-style style?] +@defthing[center-figure-style style?] +@defthing[right-figure-style style?] +@defthing[left style?] +)]{ +Implements figure alignments. + +The @racket[left] binding is a synonym for @racket[left-figure-style], +provided for backward compatibility.} -@defthing[left style?]{ -Implements a style for left-aligned figures. -} @defproc[(figure-ref [tag string?] ...+) element?]{ @@ -55,3 +63,37 @@ Generates a reference to one or more figures, capitalizing the word ``Figure''.} Generates a new figure label. This function is normally not used directly, since it is used by @racket[figure].} + + +@section{Configuring Output} + +Output uses the following style names, which can be adjusted in an +overriding @filepath{.css} or @filepath{.tex} specification: + +@itemize[ + + @item{@sn{Figure}, @sn{FigureMulti}, @sn{FigureMultiWide}, or + @sn{HereFigure} --- used for the outer of three + @racket[nested-flow]s for a figure, depending on whether + @racket[figure], @racket[figure*], @racket[figure**], or + @racket[figure-here] is used to generate the figure.} + + @item{@sn{Leftfigure}, @sn{Centerfigure}, or @sn{Rightfigure} --- + used for the middle of three @racket[nested-flow]s for a + figure, depending on the specified style.} + + @item{@sn{FigureInside} --- used for the inner of three + @racket[nested-flow]s for a figure.} + + @item{@sn{Legend} --- Wraps the caption for a figure.} + + @item{@sn{FigureTarget} --- Wraps the label anchor and text within a + figure's caption. For Latex output, the corresponding command + is given a second argument, which is just the generated label + (used with @tt{\label} in the command's first argument).} + + @item{@sn{FigureRef} --- Wraps a reference to a figure. For Latex + output, the corresponding command is given a second argument, + which is just the target label.} + +]