Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions classprims_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,16 +310,22 @@ func pageChars(e *Engine) string {
}
}
}
walk(e.mvl)
walk(e.parList)
// Column-region spans are typeset material too — revtex's frontmatter, a
// figure*/table* band — and they reach the page without passing through the main
// vertical list.
// In PAGE ORDER: a column region's span is typeset material that reaches the page
// ABOVE the region's own material — revtex's frontmatter is one, a figure*/table*
// band is another — and it never passes through the main vertical list. Walking
// the list first and the spans after put a title block AFTER the body it heads.
at := 0
for _, r := range e.colRegions {
if r.at > at {
walk(e.mvl[at:r.at])
at = r.at
}
if r.span != nil {
walk([]node{r.span})
}
}
walk(e.mvl[at:])
walk(e.parList)
return string(s)
}

Expand Down
18 changes: 17 additions & 1 deletion revtex.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ package engine
// match against the reference even though every word is present (measured: 2605.12538,
// 7 authors, went to 5.8 layout-divergence at 94.5% recall). Comma/semicolon joining
// keeps the block height near revtex's, recovering that layout without losing content.
// The ABSTRACT is captured, not typeset where it stands. In revtex the abstract is
// written BEFORE \maketitle and emitted BY it, after the authors; the generic
// \abstract (latex.go) sets it in place, so the playground and every rendered revtex
// paper carried its abstract ABOVE its own title. It is collected into a box with
// \global\setbox — local would be restored by the \endgroup that \end{abstract}
// runs, and the abstract would vanish — and \maketitle places it. An abstract that
// comes AFTER \maketitle (some papers do) is emitted as soon as it closes, so the
// order is right either way and nothing is ever dropped.
//
// \author accumulates here — revtex allows several, each followed by its own
// \affiliation — rather than overwriting as the base article \author does. It runs at
// document time (from \documentclass), where @ is an "other" character, so it opens
Expand All @@ -47,7 +56,14 @@ const RevtexAuthorBlock = `
\def\preprint#1{}
\def\pacs#1{}
\def\keywords#1{}
\long\def\maketitle{\par\begin{center}{\large\bfseries\@title\par}\medskip{\@revtexauthors\par}\smallskip{\itshape\@revtexaffils\par}\end{center}\par\bigskip\gotex@revtexbodytwocol}
\newbox\@revtexabsbox
\newif\if@revtexmadetitle
\long\def\abstract{\global\setbox\@revtexabsbox\vbox\bgroup
\centerline{\small\bfseries Abstract}\smallskip
\leftskip=20pt \rightskip=20pt \small}
\def\endabstract{\egroup\if@revtexmadetitle\@revtexputabstract\fi}
\def\@revtexputabstract{\par\bigskip\noindent\box\@revtexabsbox\par}
\long\def\maketitle{\par\begin{center}{\large\bfseries\@title\par}\medskip{\@revtexauthors\par}\smallskip{\itshape\@revtexaffils\par}\end{center}\@revtexputabstract\@revtexmadetitletrue\par\bigskip\gotex@revtexbodytwocol}
\makeatother
`

Expand Down
54 changes: 54 additions & 0 deletions revtexabstract_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (c) the go-tex/engine authors.
// SPDX-License-Identifier: BSD-3-Clause

package engine

import (
"strings"
"testing"
)

// In revtex the abstract is written BEFORE \maketitle and emitted BY it, after the
// authors. The generic \abstract sets it where it stands, so every rendered revtex
// paper carried its abstract ABOVE its own title — visible on the deployed
// playground, and on 2203.15077 whose page 1 opened with "Abstract Growing a flat
// lamina…" where the reference opens with "How to grow a flat leaf".
//
// It costs no page, so Σ cannot see it, which is why it survived.
func TestRevtexAbstractFollowsTheTitle(t *testing.T) {
src := `\documentclass[reprint,aps]{revtex4-2}\begin{document}` +
`\title{TITREICI}\author{AUTEURICI}\affiliation{AFFILIATIONICI}` +
`\begin{abstract}RESUMEICI\end{abstract}\maketitle CORPSICI\end{document}`
e, err := compile([]byte(src), Options{Lenient: true})
if err != nil {
t.Fatal(err)
}
got := pageChars(e)
order := []string{"TITREICI", "AUTEURICI", "AFFILIATIONICI", "RESUMEICI", "CORPSICI"}
at := -1
for _, want := range order {
i := strings.Index(got, want)
if i < 0 {
t.Fatalf("%q is not on the page: %q", want, got)
}
if i < at {
t.Errorf("%q comes before what should precede it — order is %v in %q", want, order, got)
}
at = i
}
}

// An abstract written AFTER \maketitle (some papers do) is emitted as soon as it
// closes, so nothing is ever captured into a box that no one empties.
func TestRevtexAbstractAfterMaketitleIsStillSet(t *testing.T) {
src := `\documentclass[reprint,aps]{revtex4-2}\begin{document}` +
`\title{TITREICI}\author{AUTEURICI}\maketitle` +
`\begin{abstract}RESUMEICI\end{abstract} CORPSICI\end{document}`
e, err := compile([]byte(src), Options{Lenient: true})
if err != nil {
t.Fatal(err)
}
if got := pageChars(e); !strings.Contains(got, "RESUMEICI") {
t.Errorf("the abstract vanished: %q", got)
}
}
15 changes: 10 additions & 5 deletions theorem_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,21 @@ func hasRuleNode(nodes []node) bool {
// treeText reads back every typeset character in the main vertical list.
func treeText(e *Engine) string {
var b strings.Builder
collectChars(e.mvl, &b)
// A column region's SPAN is typeset material that reaches the page without ever
// being on the main vertical list — revtex's frontmatter is one, a figure*/table*
// band is another. Walking mvl alone made a revtex title block look absent when
// it was merely somewhere else.
// In PAGE ORDER: a column region's SPAN reaches the page ABOVE the region's own
// material and never passes through the main vertical list — revtex's frontmatter
// is one, a figure*/table* band is another. Walking mvl alone made a revtex title
// block look absent; walking it first and the spans after put it after the body.
at := 0
for _, r := range e.colRegions {
if r.at > at {
collectChars(e.mvl[at:r.at], &b)
at = r.at
}
if r.span != nil {
collectChars([]node{r.span}, &b)
}
}
collectChars(e.mvl[at:], &b)
return b.String()
}

Expand Down