Scribble support for new acmart.cls. (#85)

Scribble support for new acmart.cls.
This commit is contained in:
David Van Horn 2017-03-10 18:24:27 -05:00 committed by Matthew Flatt
parent 60b0cd100c
commit 049bf4b07a
12 changed files with 2872 additions and 2 deletions

View File

@ -0,0 +1,251 @@
#lang scribble/manual
@(require (except-in "utils.rkt" title author)
(for-label scribble/acmart))
@(define acmart-url
"http://mirrors.concertpass.com/tex-archive/macros/latex/contrib/acmart/acmart.pdf")
@title{ACM Paper Format}
@defmodulelang[scribble/acmart]{The @racketmodname[scribble/acmart]
language is like @racketmodname[scribble/base], but configured with
LaTeX style defaults to use the @hyperlink[acmart-url]{@tt{acmart}}
class for typesetting publications for the Association of Computing
Machinery.}
@deftogether[(
@defidform[manuscript]
@defidform[acmsmall]
@defidform[acmlarge]
@defidform[acmtog]
@defidform[sigconf]
@defidform[siggraph]
@defidform[sigplan]
@defidform[sigchi]
@defidform[sigchi-a]
)]{
Enables the given document format. Use the format only on the same
line as @hash-lang[], with only whitespace (or other options) between
@racketmodname[scribble/acmart] and the format name:
@verbatim[#:indent 2]|{
#lang scribble/acmart @acmsmall
}|
The @racket[manuscript], @racket[acmsmall], @racket[acmlarge],
@racket[acmtog], @racket[sigconf], @racket[siggraph],
@racket[sigplan], @racket[sigchi], and @racket[sigchi-a] formats are
all mutually exclusive.}
@deftogether[(
@defidform[review]
@defidform[screen]
@defidform[natbib]
@defidform[anonymous]
@defidform[authorversion]
)]{
Enables the given document format option. Use the option only on the
same line as @hash-lang[], with only whitespace (or other options)
between @racketmodname[scribble/acmart] and the format option. Any
number of options may be used:
@verbatim[#:indent 2]|{
#lang scribble/acmart @acmsmall @review @anonymous @natbib
}|
}
@defproc[(maketitle) block?]{
Issues the @tt{maketitle} command. This @emph{must} be included in
the document and should occur after the title, authors, and several
other top-matter commands. (See the
@hyperlink[acmart-url]{@tt{acmart}} documentation.)
@codeblock|{
#lang scribble/acmart
@title{Example}
@maketitle{}
}|}
@defproc[(abstract [pre-content pre-content?] ...) block?]{
Generates a @tech{nested flow} for a paper abstract.}
@defform[(include-abstract module-path)]{
Similar to @racket[include-section], but incorporates the document in the
specified module as an abstract. The document must have no title or
sub-parts.}
@defproc[(title [#:short short-title pre-content? #f] [title pre-content?]) content?]{
Specifies the title of the document, optionally with a short version of the title for running heads.}
@defproc[(subtitle [pre-content pre-content?] ...) content?]{
Specifies a subtitle.}
@defproc[(author [pre-content pre-conent?] ...) content?]{
Specifies an author.}
@defproc[(email [pre-content pre-conent?] ...) content?]{
Specifies an author's email address.}
@deftogether[(
@defproc[(acmJournal [journal pre-content?] ...) content?]
@defproc[(acmConference [name pre-content?] [date pre-content?] [venue pre-content?]) content?]
@defproc[(acmVolume [content pre-content?] ...) content?]
@defproc[(acmNumber [content pre-content?] ...) content?]
@defproc[(acmArticle [content pre-content?] ...) content?]
@defproc[(acmYear [content pre-content?] ...) content?]
@defproc[(acmMonth [content pre-content?] ...) content?]
@defproc[(acmArticleSeq [content pre-content?] ...) content?]
@defproc[(acmPrice [content pre-content?] ...) content?]
@defproc[(acmISBN [content pre-content?] ...) content?]
@defproc[(acmDOI [content pre-content?] ...) content?]
)]{
Declares information that is collected into the front-matter region of the paper.}
@deftogether[(
@defproc[(acmBadgeL [#:url url string? #f] [graphics string?]) content?]
@defproc[(acmBadgeR [#:url url string? #f] [graphics string?]) content?]
)]{
Display a special badge, such as an artifact evaluation badge, on the
left or right of the first page. If @racket[url] is provided, the
screen version of the image links to the badge authority.
}
@defproc[(affiliation [content pre-content?] ...) content?]{
Declares information about the affiliation of an author.}
@deftogether[(
@defproc[(position [content pre-content?] ...) content?]
@defproc[(institution [content pre-content?] ...) content?]
@defproc[(department [content pre-content?] ...) content?]
@defproc[(streetaddress [content pre-content?] ...) content?]
@defproc[(city [content pre-content?] ...) content?]
@defproc[(state [content pre-content?] ...) content?]
@defproc[(postcode [content pre-content?] ...) content?]
@defproc[(country [content pre-content?] ...) content?]
)]{
Declares information that is collected for each author. These commands should
only be used within an @racket[affiliation] command.}
@codeblock|{
#lang scribble/acmart
@title{Some Title}
@author{David Van Horn}
@email|{dvanhorn@cs.umd.edu}|
@affiliation{
@department{Department of Computer Science and UMIACS}
@institution{University of Maryland}
@city{College Park}
@state{Maryland}}
@abstract{This is an abstract.}
@maketitle{}
}|
@deftogether[(
@defproc[(terms [content pre-content?] ...) content?]
@defproc[(keywords [content pre-content?] ...) content?]
)]{
Typesets term and keyword information for the paper, which
is normally placed immediately after an @racket[abstract] form.
See also @url["http://www.acm.org/about/class/how-to-use"].
For @racket[terms], each general term should be in titlecase. Terms
are usually drawn from a fixed list, and they are usually optional.
For @racket[keywords], capitalize only the first letter of the first
word, separate phrases by commas, and do not include ``and'' before
the last one. Keywords should be noun phrases, not adjectives.}
@defproc[(startPage [content pre-content?] ...) content?]{
Sets the start page for the paper.}
@defproc[(ccsdesc [#:number number? #f] [content pre-content?] ...) content?]{
Declares CCS description with optional numeric code.}
@defproc[(received [#:stage stage string? #f] [date string?]) content?]{
Sets the history of the publication. If @racket[stage] is omitted, it
defaults to @racket{Received} for the first occurrence and
@racket{revised} in subsequent uses.
@codeblock[#:keep-lang-line? #f]|{
#lang scribble/acmart
@received{February 2007}
@received[#:stage "revised"]{March 2009}
@received[#:stage "accepted"]{June 2009}
}|}
@defproc[(citestyle [content pre-content?]) content?]{
Sets the citation style for the paper.}
@defproc[(setcitestyle [content pre-content?] ...) content?]{
Sets customization options for the citation style for the paper.}
@defproc[(teaserfigure [content pre-content?] ...) block?]{
Creates a teaser figure to appear before main text.}
@deftogether[(
@defproc[(sidebar [content pre-content?] ...) block?]
@defproc[(marginfigure [content pre-content?] ...) block?]
@defproc[(margintable [content pre-content?] ...) block?]
)]{
In the @racket[sigchi-a] format, special sidebars,
tables and figures on the margin.}
@deftogether[(
@defproc[(printonly [content pre-content?] ...) block?]
@defproc[(screenonly [content pre-content?] ...) block?]
@defproc[(anonsuppress [content pre-content?] ...) block?]
)]{
Marks content to be included only for print or screen
editions, or excluded from anonymous editions.}
@defproc[(acks [content pre-content?] ...) block?]{
Creates an unnumbered section ``Acknowledgments'' section, unless the
@racket[anonymous] mode is selected.}
@deftogether[(
@defproc[(grantsponsor [sponsorID string?] [name string?] [url string?]) content?]
@defproc[(grantnum [#:url url string? #f] [sponsorID string?] [num string?]) content?]
)]{
All financial support @emph{must} be listed using the
@racket[grantsponsor] and @racket[grantnum] commands inside of
@racket[acks].
Here @racket[sponsorID] is the unique ID used to match grants to
sponsors, @racket[name] is the name of the sponsor. The
@racket[sponsorID] of a @racket[grantnum] must match some
@racket[sponsorID] of a @racket[grantsponsor] command.
@codeblock[#:keep-lang-line? #f]|{
#lang scribble/acmart
@acks{
The author thanks Benjamin Greenman for helpful comments on this
code. Financial support provided by the @grantsponsor["NSF7000"
"National Scribble Foundation"]{http://racket-lang.org} under
grant No.: @grantnum["NSF7000"]{867-5309}.}
}|}

View File

@ -105,7 +105,7 @@ removed.}
@def-section-like[section part-start?]{ Like @racket[title], but
generates a @racket[part-start] of depth @racket[0] to be by
generates a @racket[part-start] of depth @racket[0] to be picked up by
@racket[decode] or @racket[decode-part].}
@def-section-like[subsection part-start?]{ Like @racket[section], but

View File

@ -10,5 +10,6 @@
@include-section["book.scrbl"]
@include-section["report.scrbl"]
@include-section["sigplan.scrbl"]
@include-section["acmart.scrbl"]
@include-section["jfp.scrbl"]
@include-section["lncs.scrbl"]

View File

@ -5,7 +5,7 @@
@defmodulelang[scribble/sigplan]{The @racketmodname[scribble/sigplan]
language is like @racketmodname[scribble/base], but configured with
Latex style defaults to use the @filepath{sigplanconf.cls} class
LaTeX style defaults to use the @filepath{sigplanconf.cls} class
file that is included with Scribble.}
@defidform[preprint]{

View File

@ -0,0 +1,211 @@
#lang racket/base
(require setup/collects
racket/contract/base
scribble/core
scribble/base
scribble/decode
scribble/html-properties
scribble/latex-properties
(for-syntax racket/base))
(provide/contract
[title (->* (pre-content?) (#:short pre-content?) content?)]
[abstract
(->* () () #:rest (listof pre-content?)
block?)]
[acmJournal
(->* () () #:rest (listof pre-content?)
content?)]
[acmConference
(-> string? string? string? content?)]
[grantsponsor
(-> string? string? string? content?)]
[grantnum
(->* (string? string?) (#:url string?) content?)]
[acmBadgeR (->* (string?) (#:url string?) content?)]
[acmBadgeL (->* (string?) (#:url string?) content?)]
[received (->* (string?) (#:stage string?) content?)]
[citestyle (-> content? content?)]
[CCSXML
(->* () () #:rest (listof pre-content?)
any/c)])
(provide maketitle)
(define-syntax-rule (defopts name ...)
(begin (define-syntax (name stx)
(raise-syntax-error #f
"option must appear on the same line as `#lang scribble/acmart'"
stx))
...
(provide name ...)))
(define-syntax-rule (define-commands name ...)
(begin
(begin
(provide/contract [name (->* () () #:rest (listof pre-content?)
content?)])
(define (name . str)
(make-element (make-style (symbol->string 'name) command-props)
(decode-content str))))
...))
(define-syntax-rule (define-environments name ...)
(begin
(begin
(provide/contract [name (->* () () #:rest (listof pre-content?)
block?)])
(define (name . str)
(make-nested-flow (make-style (symbol->string 'name) acmart-extras)
(decode-flow str))))
...))
; comment environments ensure the \begin and \end are on their own lines
(define-syntax-rule (define-comment-environments name ...)
(begin
(begin
(provide/contract [name (->* () () #:rest (listof pre-content?)
block?)])
(define (name . str)
(make-nested-flow (make-style (symbol->string 'name) acmart-extras)
(append (list (make-paragraph (style #f '()) '("")))
(decode-flow str)
(list (make-paragraph (style #f '()) '("")))))))
...))
; format options
(defopts manuscript acmsmall acmlarge acmtog sigconf siggraph sigplan sigchi sigchi-a)
; boolean options
(defopts review screen natbib anonymous authorversion)
(define acmart-extras
(let ([abs (lambda (s)
(path->collects-relative
(collection-file-path s "scribble" "acmart")))])
(list
(make-css-addition (abs "acmart.css"))
(make-tex-addition (abs "acmart.tex")))))
;; ----------------------------------------
;; Abstracts:
(define abstract-style (make-style "abstract" acmart-extras))
(define command-props (cons 'command acmart-extras))
(define multicommand-props (cons 'multicommand acmart-extras))
(define (abstract . strs)
(make-nested-flow
abstract-style
(decode-flow strs)))
(define (maketitle)
(make-nested-flow (make-style "maketitle" command-props) '()))
(define (extract-abstract p)
(unless (part? p)
(error 'include-abstract "doc binding is not a part: ~e" p))
(unless (null? (part-parts p))
(error 'include-abstract "abstract part has sub-parts: ~e" (part-parts p)))
(when (part-title-content p)
(error 'include-abstract "abstract part has title content: ~e" (part-title-content p)))
(part-blocks p))
(define-syntax-rule (include-abstract mp)
(begin
(require (only-in mp [doc abstract-doc]))
(make-nested-flow abstract-style (extract-abstract abstract-doc))))
(define (acmJournal . str)
(make-element (make-style "acmJournal" command-props)
(decode-content str)))
(define (acmConference name date venue)
(make-multiarg-element (make-style "acmConference" multicommand-props)
(list (decode-string name)
(decode-string date)
(decode-string venue))))
(define (grantsponsor id name url)
(make-multiarg-element (make-style "grantsponsor" multicommand-props)
(list (decode-string id)
(decode-string name)
(decode-string url))))
(define (grantnum #:url [url #f] id num)
(if url
(make-multiarg-element (make-style "SgrantnumURL" multicommand-props)
(list (decode-string url)
(decode-string id)
(decode-string num)))
(make-multiarg-element (make-style "grantnum" multicommand-props)
(list (decode-string id)
(decode-string num)))))
(define (acmBadgeR #:url [url #f] str)
(if url
(make-multiarg-element (make-style "SacmBadgeRURL" multicommand-props)
(list (decode-string url)
(decode-string str)))
(make-element (make-style "acmBadgeR" command-props)
(decode-string str))))
(define (acmBadgeL #:url [url #f] str)
(if url
(make-multiarg-element (make-style "SacmBadgeLURL" multicommand-props)
(list (decode-string url)
(decode-string str)))
(make-element (make-style "acmBadgeL" command-props)
(decode-string str))))
(define (received #:stage [s #f] str)
(if s
(make-multiarg-element (make-style "SreceivedStage" multicommand-props)
(list (decode-string s)
(decode-string str)))
(make-element (make-style "received" command-props)
(decode-string str))))
(define (citestyle str)
(make-element (make-style "citestyle" command-props)
(decode-string str)))
(define (ccsdesc #:number [n #f] str)
(if n
(make-multiarg-element (make-style "SccsdescNumber" multicommand-props)
(list (number->string n)
(decode-string str)))
(make-element (make-style "ccsdesc" command-props)
(decode-string str))))
(define (title #:short [st #f] str)
(if st
(make-multiarg-element (make-style "StitleShort" multicommand-props)
(list (decode-string st)
(decode-string str)))
(make-element (make-style "title" command-props)
(decode-string str))))
(define-commands subtitle orcid author affiliation email
position institution department streetaddress city state postcode country
thanks titlenote subtitlenote authornote acmVolume acmNumber acmArticle acmYear acmMonth
acmArticleSeq acmPrice acmISBN acmDOI
startPage terms keywords
setcopyright copyrightyear
settopmatter ; could be "Rackety"
shortauthors
setcitstyle)
(define (CCSXML . strs)
(make-nested-flow (make-style "CCSXML" '())
(list (make-paragraph (make-style #f '())
(make-element (make-style #f '(exact-chars))
(apply string-append strs))))))
(define-environments teaserfigure sidebar marginfigure margintable)
(define-comment-environments printonly screenonly anonsuppress acks)
; FIXME: theorem styles

View File

@ -0,0 +1,2 @@
% Avoid package option conflict
\renewcommand\packageColor\relax

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,13 @@
/* Support for styles in scribble/sigplan */
.SAuthorPlace, .SAuthorEmail,
.SConferenceInfo, .SCopyrightYear, .SCopyrightData,
.Sdoi, .SPexclusivelicense,
.SCategory, .SCategoryPlus, .STerms, .SKeywords {
display: none;
}
.SSubtitle {
display: block;
font-size: smaller;
}

View File

@ -0,0 +1,24 @@
% Support for styles in scribble/acmart
% These are replaced by scribble/acmart/style.tex,
% which is used in combination with acmart.cls
\newcommand{\SAuthorPlace}[1]{#1}
\newcommand{\SAuthorEmail}[1]{#1}
\newcommand{\SConferenceInfo}[2]{}
\newcommand{\SCopyrightYear}[1]{}
\newcommand{\SCopyrightData}[1]{}
\newcommand{\Sdoi}[1]{}
\newcommand{\SPexclusivelicense}[0]{}
\newcommand{\SCategory}[3]{}
\newcommand{\SCategoryPlus}[4]{}
\newcommand{\STerms}[1]{}
\newcommand{\SKeywords}[1]{}
% Normally gets re-written by the title macro:
\newcommand{\SSubtitle}[1]{{\bf #1}}

View File

@ -0,0 +1,136 @@
#lang racket/base
(require scribble/doclang
scribble/core
(except-in scribble/base author title)
scribble/acmart
scribble/latex-prefix
racket/list
"../private/defaults.rkt"
(for-syntax racket/base))
(provide (except-out (all-from-out scribble/doclang) #%module-begin)
(all-from-out scribble/acmart)
(all-from-out scribble/base)
(rename-out [module-begin #%module-begin]))
(define-syntax (module-begin stx)
(syntax-case stx ()
[(_ id . body)
(let ([format? #f]
[review? #f]
[screen? #f]
[natbib? #f]
[anonymous? #f]
[authorversion? #f])
(let loop ([stuff #'body])
(syntax-case* stuff (manuscript acmsmall acmlarge acmtog sigconf siggraph sigplan sigchi sigchi-a
review screen natbib anonymous authorversion)
(lambda (a b) (eq? (syntax-e a) (syntax-e b)))
[(ws . body)
;; Skip intraline whitespace to find options:
(and (string? (syntax-e #'ws))
(regexp-match? #rx"^ *$" (syntax-e #'ws)))
(loop #'body)]
; boolean options
[((review #t) . body)
(set! review? "review=true")
(loop #'body)]
[((review #f) . body)
(set! review? "review=false")
(loop #'body)]
[(review . body)
(set! review? "review=true")
(loop #'body)]
[((screen #t) . body)
(set! screen? "screen=true")
(loop #'body)]
[((screen #f) . body)
(set! screen? "screen=false")
(loop #'body)]
[(screen . body)
(set! screen? "screen=true")
(loop #'body)]
[((natbib #t) . body)
(set! natbib? "natbib=true")
(loop #'body)]
[((natbib #f) . body)
(set! natbib? "natbib=false")
(loop #'body)]
[(natbib . body)
(set! natbib? "natbib=true")
(loop #'body)]
[((anonymous #t) . body)
(set! anonymous? "anonymous=true")
(loop #'body)]
[((anonymous #f) . body)
(set! anonymous? "anonymous=false")
(loop #'body)]
[(anonymous . body)
(set! anonymous? "anonymous=true")
(loop #'body)]
[((authorversion #t) . body)
(set! authorversion? "authorversion=true")
(loop #'body)]
[((authorversion #f) . body)
(set! authorversion? "authorversion=false")
(loop #'body)]
[(authorversion . body)
(set! authorversion? "authorversion=true")
(loop #'body)]
; format options
[(manuscript . body)
(set! format? "manuscript")
(loop #'body)]
[(acmsmall . body)
(set! format? "acmsmall")
(loop #'body)]
[(acmlarge . body)
(set! format? "acmlarge")
(loop #'body)]
[(acmtog . body)
(set! format? "acmtog")
(loop #'body)]
[(sigconf . body)
(set! format? "sigconf")
(loop #'body)]
[(sigconf . body)
(set! format? "siggraph")
(loop #'body)]
[(sigplan . body)
(set! format? "sigplan")
(loop #'body)]
[(sigchi . body)
(set! format? "sigchi")
(loop #'body)]
[(sigchi-a . body)
(set! format? "sigchi-a")
(loop #'body)]
[body
#`(#%module-begin id (post-process #,review? #,screen? #,natbib? #,anonymous? #,authorversion? #,format?) () . body)])))]))
(define ((post-process . opts) doc)
(let ([options
(if (ormap values opts)
(format "[~a]" (apply string-append (add-between (filter values opts) ", ")))
"")])
(add-acmart-styles
(add-defaults doc
(string->bytes/utf-8
(format "\\documentclass~a{acmart}\n~a"
options
unicode-encoding-packages))
(scribble-file "acmart/style.tex")
(list (scribble-file "acmart/acmart.cls"))
#f
#:replacements (hash "scribble-load-replace.tex" (scribble-file "acmart/acmart-load.tex"))))))
(define (add-acmart-styles doc)
;; Ensure that "acmart.tex" is used, since "style.tex"
;; re-defines commands.
(struct-copy part doc [to-collect
(cons '(terms) ; FIXME
(part-to-collect doc))]))

View File

@ -0,0 +1,3 @@
#lang s-exp scribble/base/reader
scribble/acmart/lang
#:wrapper1 (lambda (t) (cons 'doc (t)))

View File

@ -0,0 +1,42 @@
% Define \SXtitle to lift \SSubtitle out:
\def\SXtitle#1{\title{\let\SSubtitle\SSubtitleDrop#1}\SExtractSubtitle#1\SExtractSubtitleDone}
\def\SSubtitleDrop#1{}
\def\SExtractSubtitleDone {}
\def\SExtractSubtitle{\futurelet\next\SExtractSubtitleX}
\def\SExtractSubtitleX#1{\ifx#1\SSubtitle \let\Snext\SWithSubtitle \else \let\Snext\SExtractSubtitleY \fi \Snext}
\def\SExtractSubtitleY{\ifx\next\SExtractSubtitleDone \let\Snext\relax \else \let\Snext\SExtractSubtitle \fi \Snext}
\def\SWithSubtitle#1{\subtitle{#1}\SExtractSubtitle}
\renewcommand{\titleAndVersionAndAuthors}[3]{\SXtitle{#1}#3}
\renewcommand{\titleAndEmptyVersionAndAuthors}[3]{\titleAndVersionAndAuthors{#1}{#2}{#3}}
\renewcommand{\titleAndVersionAndEmptyAuthors}[3]{\SXtitle{#1}\author{Anonymous Author(s)}}
\renewcommand{\titleAndEmptyVersionAndEmptyAuthors}[3]{\titleAndVersionAndEmptyAuthors{#1}{#2}{#3}}
% Support plain `author' while enabling `authorinfo': for each
% use of \SAuthor, check whether it contains an \SAuthorinfo form:
\def\SAuthor#1{\author{#1}}
\renewcommand{\SAuthorSep}[1]{}
\renewcommand{\SConferenceInfo}[2]{\conferenceinfo{#1}{#2}}
\renewcommand{\SCopyrightYear}[1]{\copyrightyear{#1}}
\renewcommand{\SCopyrightData}[1]{\copyrightdata{#1}}
%\renewcommand{\Sdoi}[1]{\doi{#1}}
\renewcommand{\SPexclusivelicense}[0]{\exclusivelicense}
\renewcommand{\SCategory}[3]{\category{#1}{#2}{#3}}
\renewcommand{\SCategoryPlus}[4]{\category{#1}{#2}{#3}[#4]}
\renewcommand{\STerms}[1]{\terms{#1}}
\renewcommand{\SKeywords}[1]{\keywords{#1}}
\newcommand{\StitleShort}[2]{\title[#1]{#2}}
\newcommand{\SacmBadgeRURL}[2]{\acmBadgeR[#1]{#2}}
\newcommand{\SacmBadgeLURL}[2]{\acmBadgeL[#1]{#2}}
\newcommand{\SgrantnumURL}[3]{\grantnum[#1]{#2}{#3}}
\newcommand{\SreceivedStage}[2]{\received[#1]{#2}}
\newcommand{\SccsdescNumber}[2]{\ccsdesc[#1]{#2}}