diff --git a/slides_template/mknotes b/slides_template/mknotes index 7ecb1f4..571ec99 100755 --- a/slides_template/mknotes +++ b/slides_template/mknotes @@ -44,6 +44,7 @@ class Page: self.section = "" self.subsection = "" self.notes = [] + self.items = [] def parse_notes_file(path): @@ -77,9 +78,10 @@ def parse_notes_file(path): i += 1 continue - match = re.match(r"^NOTE FRAME (\d+)\|SPEC (.*)$", line) + match = re.match(r"^NOTE FRAME (\d+)\|SPEC (.*)\|KIND (.*)$", line) if match: - frame, spec = int(match.group(1)), match.group(2).strip() + frame = int(match.group(1)) + spec, kind = match.group(2).strip(), match.group(3).strip() body = [] i += 1 while i < len(lines) and lines[i].strip() != "ENDNOTE": @@ -90,10 +92,10 @@ def parse_notes_file(path): text = " ".join(part.strip() for part in body).strip() # A note is re-run for every slide of its frame, so the same record # arrives once per slide. Keep the first occurrence only. - key = (frame, spec, text) + key = (frame, spec, kind, text) if key not in seen: seen.add(key) - notes.setdefault(frame, []).append((spec, text)) + notes.setdefault(frame, []).append((spec, kind, text)) continue i += 1 @@ -141,9 +143,12 @@ def attach_notes(pages, notes): last_slide[page.frame] = max(last_slide.get(page.frame, 0), page.slide) for page in pages: - for spec, text in notes.get(page.frame, []): + for spec, kind, text in notes.get(page.frame, []): if spec_matches(spec, page.slide, last_slide[page.frame]): - page.notes.append(text) + if kind == "item": + page.items.append(text) + else: + page.notes.append(text) # ---------------------------------------------------------------- typesetting @@ -243,14 +248,25 @@ def build_notes_pdf(pages, width, height, thumb_w, thumb_h, workdir, body.append(r"\noindent\colorbox{notegrey}{%s}%%" % band) body.append(r"\par\vspace{%.2fbp}%%" % gap) + # Paragraph spacing is set here rather than in the preamble so that it + # separates the notes without also loosening the heading band above. body.append(r"\noindent\hspace{%.2fbp}\begin{minipage}[t]{%.2fbp}" + r"\setlength{\parskip}{0.7em}" % (hmargin, textwidth)) + # As in beamer, plain \note commands run together as text and + # \note[item] ones become a numbered list printed after it. beamer + # concatenates the plain ones with no separator at all; a paragraph + # break between them is easier to read and is the one deviation. if page.notes: - body.append(r"\begin{itemize}\setlength{\itemsep}{0.6em}" - r"\setlength{\leftmargini}{1.2em}") - for note in page.notes: - body.append(r"\item %s" % escape_for_context(note)) - body.append(r"\end{itemize}") + body.append("\n\n".join( + escape_for_context(n) for n in page.notes)) + if page.items: + body.append(r"\par\begin{enumerate}\setlength{\itemsep}{0pt}" + r"\setlength{\parskip}{0pt}" + r"\setlength{\leftmargini}{1.4em}") + for item in page.items: + body.append(r"\item %s" % escape_for_context(item)) + body.append(r"\end{enumerate}") body.append(r"\end{minipage}") if index != total - 1: diff --git a/slides_template/talk-notes.sty b/slides_template/talk-notes.sty index 25e9403..456b668 100644 --- a/slides_template/talk-notes.sty +++ b/slides_template/talk-notes.sty @@ -58,21 +58,25 @@ { SUBSECTION ~ \tl_to_str:N \g__talknotes_subsection_tl } } -% \note[]{text} +% \note[item]{text} +% +% Follows beamer's interface. A plain \note contributes running text; \note[item] +% contributes an entry to a numbered list printed after that text. % % The body is written out stringified, so LaTeX markup inside a note survives % to be typeset again on the notes page. A note is recorded once per slide of % its frame (the frame body is re-run for each), so mknotes deduplicates. % Records are bracketed by ENDNOTE because a long note may be broken across % output lines. -\NewDocumentCommand \note { d<> +m } +\NewDocumentCommand \note { d<> o +m } { \iow_now:Nx \g__talknotes_iow { NOTE ~ FRAME ~ \int_use:N \g__talk_frame_int | - SPEC ~ \IfNoValueTF {#1} { - } { \tl_to_str:n {#1} } + SPEC ~ \IfNoValueTF {#1} { - } { \tl_to_str:n {#1} } | + KIND ~ \IfNoValueTF {#2} { text } { \tl_to_str:n {#2} } } - \iow_now:Nx \g__talknotes_iow { TEXT ~ \tl_to_str:n {#2} } + \iow_now:Nx \g__talknotes_iow { TEXT ~ \tl_to_str:n {#3} } \iow_now:Nn \g__talknotes_iow { ENDNOTE } }