Conversation
|
PS: I'm tempted to have a clanker improve the parsing of bibtex to support (a) emphasis, in notes, (b) {} in titles to prevent lowercasification when using LaTeX. Also, maybe to improve autobib so multi-paragraph notes are a thing, and maybe crossing page boundaries within a bibliography entry. These two would also much improve LtUO. PPS: I'm still thinking about (a), but at least the basics of (b) was apparently done by #571. PPPS: The clankers did it! |
|
Weird: the CI failed on Racket 9.3.0.8, but at home it just worked on v9.3.0.8-2026-09-14-06fd59e02c [cs]. PS: I had forgotten to update a test. |
|
The change to add |
|
Yes, adding a "." only if there's a note makes a lot sense, especially for backwards compatibility. Thanks for the suggestion. PS: also rebasing to the latest master. |
Much improves the bibliography for my book LtUO.
There was a problem hiding this comment.
Resyntax analyzed 1 file in this pull request and found no issues.
There was a problem hiding this comment.
Resyntax analyzed 1 file in this pull request and found no issues.
There was a problem hiding this comment.
Resyntax analyzed 1 file in this pull request and found no issues.
There was a problem hiding this comment.
Resyntax analyzed 1 file in this pull request and found no issues.
There was a problem hiding this comment.
Resyntax analyzed 1 file in this pull request and found no issues.
There was a problem hiding this comment.
Resyntax analyzed 1 file in this pull request and found no issues.
There was a problem hiding this comment.
Resyntax analyzed 2 files in this pull request and found no issues.
There was a problem hiding this comment.
Resyntax analyzed 3 files in this pull request and found no issues.
There was a problem hiding this comment.
Resyntax analyzed 3 files in this pull request and found no issues.
Use CSS and LaTeX environments for autobib number-style. Much nicer output in HTML and PDF. In number-style, text output won't align as a table anymore, but will have a space after the [number].
There was a problem hiding this comment.
Resyntax analyzed 4 files in this pull request and found no issues.
There was a problem hiding this comment.
Resyntax analyzed 7 files in this pull request and has added suggestions.
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Resyntax analyzed 7 files in this pull request and has added suggestions.
| (cond | ||
| [(= depth 1) (unescape-url (get-output-string out))] | ||
| [else | ||
| (write-char #\} out) | ||
| (loop (sub1 depth))])] |
There was a problem hiding this comment.
if-begin-to-cond: Using cond instead of if here makes begin unnecessary
| (cond | |
| [(= depth 1) (unescape-url (get-output-string out))] | |
| [else | |
| (write-char #\} out) | |
| (loop (sub1 depth))])] | |
| (cond | |
| [(= depth 1) (unescape-url (get-output-string out))] | |
| [else | |
| (write-char #\} out) | |
| (loop (sub1 depth))])] |
Debugging details
Textual replacement
(line-replacement
#:new-lines
'#(" (cond"
" [(= depth 1) (unescape-url (get-output-string out))]"
" [else"
" (write-char #\\} out)"
" (loop (sub1 depth))])]")
#:original-lines
'#(" (if (= depth 1)"
" (unescape-url (get-output-string out))"
" (begin"
" (write-char #\\} out)"
" (loop (sub1 depth))))]")
#:start-line 106)Syntactic replacement
(syntax-replacement
#:introduction-scope #<procedure:...and/syntax-local.rkt:148:2>
#:new-syntax
#<syntax:/home/runner/.local/share/racket/9.3.0.8/pkgs/resyntax/default-recommendations/conditional-shortcuts.rkt:204:2 (cond ((= depth 1) (unescape-url (get-output-string out))) (else (write-char #\} out) (loop (sub1 depth))))>
#:original-syntax
#<syntax:scribble-lib/scriblib/private/read-latex.rkt:106:12 (if (= depth 1) (unescape-url (get-output-string out)) (begin (write-char #\} out) (loop (sub1 depth))))>
#:source
(file-source
#<path:/home/runner/work/scribble/scribble/scribble-lib/scriblib/private/read-latex.rkt>)
#:uses-universal-tagged-syntax? #f)| (when (eqv? (peek-char ip) #\{) | ||
| (define depth 0) | ||
| (let copy () | ||
| (match (read-char ip) | ||
| [(? eof-object?) (error 'latex->content "unclosed argument in ~e" source)] | ||
| [#\\ | ||
| (write-char #\\ out) | ||
| (define next (read-char ip)) | ||
| (when (eof-object? next) | ||
| (error 'latex->content "trailing backslash in ~e" source)) | ||
| (write-char next out) | ||
| (copy)] | ||
| [#\{ | ||
| (set! depth (add1 depth)) | ||
| (write-char #\{ out) | ||
| (copy)] | ||
| [#\} | ||
| (set! depth (sub1 depth)) | ||
| (write-char #\} out) | ||
| (unless (zero? depth) | ||
| (copy))] | ||
| [c | ||
| (write-char c out) | ||
| (copy)])) | ||
| (arguments))) |
There was a problem hiding this comment.
let-to-define: Internal definitions are recommended instead of let expressions, to reduce nesting.
| (when (eqv? (peek-char ip) #\{) | |
| (define depth 0) | |
| (let copy () | |
| (match (read-char ip) | |
| [(? eof-object?) (error 'latex->content "unclosed argument in ~e" source)] | |
| [#\\ | |
| (write-char #\\ out) | |
| (define next (read-char ip)) | |
| (when (eof-object? next) | |
| (error 'latex->content "trailing backslash in ~e" source)) | |
| (write-char next out) | |
| (copy)] | |
| [#\{ | |
| (set! depth (add1 depth)) | |
| (write-char #\{ out) | |
| (copy)] | |
| [#\} | |
| (set! depth (sub1 depth)) | |
| (write-char #\} out) | |
| (unless (zero? depth) | |
| (copy))] | |
| [c | |
| (write-char c out) | |
| (copy)])) | |
| (arguments))) | |
| (when (eqv? (peek-char ip) #\{) | |
| (define depth 0) | |
| (let copy () | |
| (match (read-char ip) | |
| [(? eof-object?) (error 'latex->content "unclosed argument in ~e" source)] | |
| [#\\ | |
| (write-char #\\ out) | |
| (define next (read-char ip)) | |
| (when (eof-object? next) | |
| (error 'latex->content "trailing backslash in ~e" source)) | |
| (write-char next out) | |
| (copy)] | |
| [#\{ | |
| (set! depth (add1 depth)) | |
| (write-char #\{ out) | |
| (copy)] | |
| [#\} | |
| (set! depth (sub1 depth)) | |
| (write-char #\} out) | |
| (unless (zero? depth) | |
| (copy))] | |
| [c | |
| (write-char c out) | |
| (copy)])) | |
| (arguments))) |
Debugging details
Textual replacement
(line-replacement
#:new-lines
'#(" (when (eqv? (peek-char ip) #\\{)"
" (define depth 0)"
" (let copy ()"
" (match (read-char ip)"
" [(? eof-object?) (error 'latex->content \"unclosed argument in ~e\" source)]"
" [#\\\\"
" (write-char #\\\\ out)"
" (define next (read-char ip))"
" (when (eof-object? next)"
" (error 'latex->content \"trailing backslash in ~e\" source))"
" (write-char next out)"
" (copy)]"
" [#\\{"
" (set! depth (add1 depth))"
" (write-char #\\{ out)"
" (copy)]"
" [#\\}"
" (set! depth (sub1 depth))"
" (write-char #\\} out)"
" (unless (zero? depth)"
" (copy))]"
" [c"
" (write-char c out)"
" (copy)]))"
" (arguments)))")
#:original-lines
'#(" (when (eqv? (peek-char ip) #\\{)"
" (let ([depth 0])"
" (let copy ()"
" (match (read-char ip)"
" [(? eof-object?) (error 'latex->content \"unclosed argument in ~e\" source)]"
" [#\\\\"
" (write-char #\\\\ out)"
" (define next (read-char ip))"
" (when (eof-object? next)"
" (error 'latex->content \"trailing backslash in ~e\" source))"
" (write-char next out)"
" (copy)]"
" [#\\{"
" (set! depth (add1 depth))"
" (write-char #\\{ out)"
" (copy)]"
" [#\\}"
" (set! depth (sub1 depth))"
" (write-char #\\} out)"
" (unless (zero? depth)"
" (copy))]"
" [c"
" (write-char c out)"
" (copy)]))"
" (arguments))))")
#:start-line 126)Syntactic replacement
(syntax-replacement
#:introduction-scope #<procedure:...and/syntax-local.rkt:148:2>
#:new-syntax
#<syntax:.../resyntax/base.rkt:215:28 (when (eqv? (peek-char ip) #\{) (define depth 0) (let copy () (match (read-char ip) ((? eof-object?) (error (quote latex->content) "unclosed argument in ~e" source)) (#\\ (write-char #\\ out) (define next (read-char ip)) (when (eof-object? next) (error ...>
#:original-syntax
#<syntax:scribble-lib/scriblib/private/read-latex.rkt:126:9 (when (eqv? (peek-char ip) #\{) (let ((depth 0)) (let copy () (match (read-char ip) ((? eof-object?) (error (quote latex->content) "unclosed argument in ~e" source)) (#\\ (write-char #\\ out) (define next (read-char ip)) (when (eof-object? next) (error ...>
#:source
(file-source
#<path:/home/runner/work/scribble/scribble/scribble-lib/scriblib/private/read-latex.rkt>)
#:uses-universal-tagged-syntax? #f)| (cond | ||
| [(and display? (not (eqv? (peek-char ip) #\$))) (loop)] | ||
| [else | ||
| (when display? | ||
| (write-char (read-char ip) out)) | ||
| (get-output-string out)])] |
There was a problem hiding this comment.
if-begin-to-cond: Using cond instead of if here makes begin unnecessary
| (cond | |
| [(and display? (not (eqv? (peek-char ip) #\$))) (loop)] | |
| [else | |
| (when display? | |
| (write-char (read-char ip) out)) | |
| (get-output-string out)])] | |
| (cond | |
| [(and display? (not (eqv? (peek-char ip) #\$))) (loop)] | |
| [else | |
| (when display? | |
| (write-char (read-char ip) out)) | |
| (get-output-string out)])] |
Debugging details
Textual replacement
(line-replacement
#:new-lines
'#(" (cond"
" [(and display? (not (eqv? (peek-char ip) #\\$))) (loop)]"
" [else"
" (when display?"
" (write-char (read-char ip) out))"
" (get-output-string out)])]")
#:original-lines
'#(" (if (and display? (not (eqv? (peek-char ip) #\\$)))"
" (loop)"
" (begin"
" (when display?"
" (write-char (read-char ip) out))"
" (get-output-string out)))]")
#:start-line 172)Syntactic replacement
(syntax-replacement
#:introduction-scope #<procedure:...and/syntax-local.rkt:148:2>
#:new-syntax
#<syntax:/home/runner/.local/share/racket/9.3.0.8/pkgs/resyntax/default-recommendations/conditional-shortcuts.rkt:204:2 (cond ((and display? (not (eqv? (peek-char ip) #\$))) (loop)) (else (when display? (write-char (read-char ip) out)) (get-output-string out)))>
#:original-syntax
#<syntax:scribble-lib/scriblib/private/read-latex.rkt:172:12 (if (and display? (not (eqv? (peek-char ip) #\$))) (loop) (begin (when display? (write-char (read-char ip) out)) (get-output-string out)))>
#:source
(file-source
#<path:/home/runner/work/scribble/scribble/scribble-lib/scriblib/private/read-latex.rkt>)
#:uses-universal-tagged-syntax? #f)| (read-char ip) | ||
| (define body (read-group #t)) | ||
| (emit! (cond | ||
| [(string=? word "emph") (apply emph body)] |
There was a problem hiding this comment.
define-begin-extraction: The begin in this definition can be extracted into the surrounding definition context.
| (read-char ip) | |
| (define body (read-group #t)) | |
| (emit! (cond | |
| [(string=? word "emph") (apply emph body)] | |
| (read-char ip) | |
| (define body (read-group #t)) |
Debugging details
Textual replacement
(line-replacement
#:new-lines
'#(" (read-char ip)"
" (define body (read-group #t))")
#:original-lines
'#(" (define body"
" (begin"
" (read-char ip)"
" (read-group #t)))")
#:start-line 263)Syntactic replacement
(syntax-replacement
#:introduction-scope #<procedure:...and/syntax-local.rkt:148:2>
#:new-syntax
#<syntax:.../resyntax/base.rkt:223:10 (cond ((eqv? (peek-char ip) #\{) (read-char ip) (define body (read-group #t)) (emit! (cond ((string=? word "emph") (apply emph body)) ((string=? word "texttt") (apply tt body)) ((string=? word "textit") (apply italic body)) ((string=? word "textbf") (ap...>
#:original-syntax
#<syntax:scribble-lib/scriblib/private/read-latex.rkt:261:18 (cond ((eqv? (peek-char ip) #\{) (define body (begin (read-char ip) (read-group #t))) (emit! (cond ((string=? word "emph") (apply emph body)) ((string=? word "texttt") (apply tt body)) ((string=? word "textit") (apply italic body)) ((string=? word "text...>
#:source
(file-source
#<path:/home/runner/work/scribble/scribble/scribble-lib/scriblib/private/read-latex.rkt>)
#:uses-universal-tagged-syntax? #f)There was a problem hiding this comment.
Resyntax analyzed 7 files in this pull request and has added suggestions.
| (cond | ||
| [(= depth 1) (unescape-url (get-output-string out))] | ||
| [else | ||
| (write-char #\} out) | ||
| (loop (sub1 depth))])] |
There was a problem hiding this comment.
if-begin-to-cond: Using cond instead of if here makes begin unnecessary
| (cond | |
| [(= depth 1) (unescape-url (get-output-string out))] | |
| [else | |
| (write-char #\} out) | |
| (loop (sub1 depth))])] | |
| (cond | |
| [(= depth 1) (unescape-url (get-output-string out))] | |
| [else | |
| (write-char #\} out) | |
| (loop (sub1 depth))])] |
Debugging details
Textual replacement
(line-replacement
#:new-lines
'#(" (cond"
" [(= depth 1) (unescape-url (get-output-string out))]"
" [else"
" (write-char #\\} out)"
" (loop (sub1 depth))])]")
#:original-lines
'#(" (if (= depth 1)"
" (unescape-url (get-output-string out))"
" (begin"
" (write-char #\\} out)"
" (loop (sub1 depth))))]")
#:start-line 106)Syntactic replacement
(syntax-replacement
#:introduction-scope #<procedure:...and/syntax-local.rkt:148:2>
#:new-syntax
#<syntax:/home/runner/.local/share/racket/9.3.0.8/pkgs/resyntax/default-recommendations/conditional-shortcuts.rkt:204:2 (cond ((= depth 1) (unescape-url (get-output-string out))) (else (write-char #\} out) (loop (sub1 depth))))>
#:original-syntax
#<syntax:scribble-lib/scriblib/private/read-latex.rkt:106:12 (if (= depth 1) (unescape-url (get-output-string out)) (begin (write-char #\} out) (loop (sub1 depth))))>
#:source
(file-source
#<path:/home/runner/work/scribble/scribble/scribble-lib/scriblib/private/read-latex.rkt>)
#:uses-universal-tagged-syntax? #f)| (when (eqv? (peek-char ip) #\{) | ||
| (define depth 0) | ||
| (let copy () | ||
| (match (read-char ip) | ||
| [(? eof-object?) (error 'latex->content "unclosed argument in ~e" source)] | ||
| [#\\ | ||
| (write-char #\\ out) | ||
| (define next (read-char ip)) | ||
| (when (eof-object? next) | ||
| (error 'latex->content "trailing backslash in ~e" source)) | ||
| (write-char next out) | ||
| (copy)] | ||
| [#\{ | ||
| (set! depth (add1 depth)) | ||
| (write-char #\{ out) | ||
| (copy)] | ||
| [#\} | ||
| (set! depth (sub1 depth)) | ||
| (write-char #\} out) | ||
| (unless (zero? depth) | ||
| (copy))] | ||
| [c | ||
| (write-char c out) | ||
| (copy)])) | ||
| (arguments))) |
There was a problem hiding this comment.
let-to-define: Internal definitions are recommended instead of let expressions, to reduce nesting.
| (when (eqv? (peek-char ip) #\{) | |
| (define depth 0) | |
| (let copy () | |
| (match (read-char ip) | |
| [(? eof-object?) (error 'latex->content "unclosed argument in ~e" source)] | |
| [#\\ | |
| (write-char #\\ out) | |
| (define next (read-char ip)) | |
| (when (eof-object? next) | |
| (error 'latex->content "trailing backslash in ~e" source)) | |
| (write-char next out) | |
| (copy)] | |
| [#\{ | |
| (set! depth (add1 depth)) | |
| (write-char #\{ out) | |
| (copy)] | |
| [#\} | |
| (set! depth (sub1 depth)) | |
| (write-char #\} out) | |
| (unless (zero? depth) | |
| (copy))] | |
| [c | |
| (write-char c out) | |
| (copy)])) | |
| (arguments))) | |
| (when (eqv? (peek-char ip) #\{) | |
| (define depth 0) | |
| (let copy () | |
| (match (read-char ip) | |
| [(? eof-object?) (error 'latex->content "unclosed argument in ~e" source)] | |
| [#\\ | |
| (write-char #\\ out) | |
| (define next (read-char ip)) | |
| (when (eof-object? next) | |
| (error 'latex->content "trailing backslash in ~e" source)) | |
| (write-char next out) | |
| (copy)] | |
| [#\{ | |
| (set! depth (add1 depth)) | |
| (write-char #\{ out) | |
| (copy)] | |
| [#\} | |
| (set! depth (sub1 depth)) | |
| (write-char #\} out) | |
| (unless (zero? depth) | |
| (copy))] | |
| [c | |
| (write-char c out) | |
| (copy)])) | |
| (arguments))) |
Debugging details
Textual replacement
(line-replacement
#:new-lines
'#(" (when (eqv? (peek-char ip) #\\{)"
" (define depth 0)"
" (let copy ()"
" (match (read-char ip)"
" [(? eof-object?) (error 'latex->content \"unclosed argument in ~e\" source)]"
" [#\\\\"
" (write-char #\\\\ out)"
" (define next (read-char ip))"
" (when (eof-object? next)"
" (error 'latex->content \"trailing backslash in ~e\" source))"
" (write-char next out)"
" (copy)]"
" [#\\{"
" (set! depth (add1 depth))"
" (write-char #\\{ out)"
" (copy)]"
" [#\\}"
" (set! depth (sub1 depth))"
" (write-char #\\} out)"
" (unless (zero? depth)"
" (copy))]"
" [c"
" (write-char c out)"
" (copy)]))"
" (arguments)))")
#:original-lines
'#(" (when (eqv? (peek-char ip) #\\{)"
" (let ([depth 0])"
" (let copy ()"
" (match (read-char ip)"
" [(? eof-object?) (error 'latex->content \"unclosed argument in ~e\" source)]"
" [#\\\\"
" (write-char #\\\\ out)"
" (define next (read-char ip))"
" (when (eof-object? next)"
" (error 'latex->content \"trailing backslash in ~e\" source))"
" (write-char next out)"
" (copy)]"
" [#\\{"
" (set! depth (add1 depth))"
" (write-char #\\{ out)"
" (copy)]"
" [#\\}"
" (set! depth (sub1 depth))"
" (write-char #\\} out)"
" (unless (zero? depth)"
" (copy))]"
" [c"
" (write-char c out)"
" (copy)]))"
" (arguments))))")
#:start-line 126)Syntactic replacement
(syntax-replacement
#:introduction-scope #<procedure:...and/syntax-local.rkt:148:2>
#:new-syntax
#<syntax:.../resyntax/base.rkt:215:28 (when (eqv? (peek-char ip) #\{) (define depth 0) (let copy () (match (read-char ip) ((? eof-object?) (error (quote latex->content) "unclosed argument in ~e" source)) (#\\ (write-char #\\ out) (define next (read-char ip)) (when (eof-object? next) (error ...>
#:original-syntax
#<syntax:scribble-lib/scriblib/private/read-latex.rkt:126:9 (when (eqv? (peek-char ip) #\{) (let ((depth 0)) (let copy () (match (read-char ip) ((? eof-object?) (error (quote latex->content) "unclosed argument in ~e" source)) (#\\ (write-char #\\ out) (define next (read-char ip)) (when (eof-object? next) (error ...>
#:source
(file-source
#<path:/home/runner/work/scribble/scribble/scribble-lib/scriblib/private/read-latex.rkt>)
#:uses-universal-tagged-syntax? #f)| (read-char ip) | ||
| (define body (read-group #t)) | ||
| (emit! (cond | ||
| [(string=? word "emph") (apply emph body)] |
There was a problem hiding this comment.
define-begin-extraction: The begin in this definition can be extracted into the surrounding definition context.
| (read-char ip) | |
| (define body (read-group #t)) | |
| (emit! (cond | |
| [(string=? word "emph") (apply emph body)] | |
| (read-char ip) | |
| (define body (read-group #t)) |
Debugging details
Textual replacement
(line-replacement
#:new-lines
'#(" (read-char ip)"
" (define body (read-group #t))")
#:original-lines
'#(" (define body"
" (begin"
" (read-char ip)"
" (read-group #t)))")
#:start-line 263)Syntactic replacement
(syntax-replacement
#:introduction-scope #<procedure:...and/syntax-local.rkt:148:2>
#:new-syntax
#<syntax:.../resyntax/base.rkt:223:10 (cond ((eqv? (peek-char ip) #\{) (read-char ip) (define body (read-group #t)) (emit! (cond ((string=? word "emph") (apply emph body)) ((string=? word "texttt") (apply tt body)) ((string=? word "textit") (apply italic body)) ((string=? word "textbf") (ap...>
#:original-syntax
#<syntax:scribble-lib/scriblib/private/read-latex.rkt:261:18 (cond ((eqv? (peek-char ip) #\{) (define body (begin (read-char ip) (read-group #t))) (emit! (cond ((string=? word "emph") (apply emph body)) ((string=? word "texttt") (apply tt body)) ((string=? word "textit") (apply italic body)) ((string=? word "text...>
#:source
(file-source
#<path:/home/runner/work/scribble/scribble/scribble-lib/scriblib/private/read-latex.rkt>)
#:uses-universal-tagged-syntax? #f)There was a problem hiding this comment.
Resyntax analyzed 7 files in this pull request and has added suggestions.
| (cond | ||
| [(= depth 1) (unescape-url (get-output-string out))] | ||
| [else | ||
| (write-char #\} out) | ||
| (loop (sub1 depth))])] |
There was a problem hiding this comment.
if-begin-to-cond: Using cond instead of if here makes begin unnecessary
| (cond | |
| [(= depth 1) (unescape-url (get-output-string out))] | |
| [else | |
| (write-char #\} out) | |
| (loop (sub1 depth))])] | |
| (cond | |
| [(= depth 1) (unescape-url (get-output-string out))] | |
| [else | |
| (write-char #\} out) | |
| (loop (sub1 depth))])] |
Debugging details
Textual replacement
(line-replacement
#:new-lines
'#(" (cond"
" [(= depth 1) (unescape-url (get-output-string out))]"
" [else"
" (write-char #\\} out)"
" (loop (sub1 depth))])]")
#:original-lines
'#(" (if (= depth 1)"
" (unescape-url (get-output-string out))"
" (begin"
" (write-char #\\} out)"
" (loop (sub1 depth))))]")
#:start-line 106)Syntactic replacement
(syntax-replacement
#:introduction-scope #<procedure:...and/syntax-local.rkt:148:2>
#:new-syntax
#<syntax:/home/runner/.local/share/racket/9.3.0.8/pkgs/resyntax/default-recommendations/conditional-shortcuts.rkt:204:2 (cond ((= depth 1) (unescape-url (get-output-string out))) (else (write-char #\} out) (loop (sub1 depth))))>
#:original-syntax
#<syntax:scribble-lib/scriblib/private/read-latex.rkt:106:12 (if (= depth 1) (unescape-url (get-output-string out)) (begin (write-char #\} out) (loop (sub1 depth))))>
#:source
(file-source
#<path:/home/runner/work/scribble/scribble/scribble-lib/scriblib/private/read-latex.rkt>)
#:uses-universal-tagged-syntax? #f)| (when (eqv? (peek-char ip) #\{) | ||
| (define depth 0) | ||
| (let copy () | ||
| (match (read-char ip) | ||
| [(? eof-object?) (error 'latex->content "unclosed argument in ~e" source)] | ||
| [#\\ | ||
| (write-char #\\ out) | ||
| (define next (read-char ip)) | ||
| (when (eof-object? next) | ||
| (error 'latex->content "trailing backslash in ~e" source)) | ||
| (write-char next out) | ||
| (copy)] | ||
| [#\{ | ||
| (set! depth (add1 depth)) | ||
| (write-char #\{ out) | ||
| (copy)] | ||
| [#\} | ||
| (set! depth (sub1 depth)) | ||
| (write-char #\} out) | ||
| (unless (zero? depth) | ||
| (copy))] | ||
| [c | ||
| (write-char c out) | ||
| (copy)])) | ||
| (arguments))) |
There was a problem hiding this comment.
let-to-define: Internal definitions are recommended instead of let expressions, to reduce nesting.
| (when (eqv? (peek-char ip) #\{) | |
| (define depth 0) | |
| (let copy () | |
| (match (read-char ip) | |
| [(? eof-object?) (error 'latex->content "unclosed argument in ~e" source)] | |
| [#\\ | |
| (write-char #\\ out) | |
| (define next (read-char ip)) | |
| (when (eof-object? next) | |
| (error 'latex->content "trailing backslash in ~e" source)) | |
| (write-char next out) | |
| (copy)] | |
| [#\{ | |
| (set! depth (add1 depth)) | |
| (write-char #\{ out) | |
| (copy)] | |
| [#\} | |
| (set! depth (sub1 depth)) | |
| (write-char #\} out) | |
| (unless (zero? depth) | |
| (copy))] | |
| [c | |
| (write-char c out) | |
| (copy)])) | |
| (arguments))) | |
| (when (eqv? (peek-char ip) #\{) | |
| (define depth 0) | |
| (let copy () | |
| (match (read-char ip) | |
| [(? eof-object?) (error 'latex->content "unclosed argument in ~e" source)] | |
| [#\\ | |
| (write-char #\\ out) | |
| (define next (read-char ip)) | |
| (when (eof-object? next) | |
| (error 'latex->content "trailing backslash in ~e" source)) | |
| (write-char next out) | |
| (copy)] | |
| [#\{ | |
| (set! depth (add1 depth)) | |
| (write-char #\{ out) | |
| (copy)] | |
| [#\} | |
| (set! depth (sub1 depth)) | |
| (write-char #\} out) | |
| (unless (zero? depth) | |
| (copy))] | |
| [c | |
| (write-char c out) | |
| (copy)])) | |
| (arguments))) |
Debugging details
Textual replacement
(line-replacement
#:new-lines
'#(" (when (eqv? (peek-char ip) #\\{)"
" (define depth 0)"
" (let copy ()"
" (match (read-char ip)"
" [(? eof-object?) (error 'latex->content \"unclosed argument in ~e\" source)]"
" [#\\\\"
" (write-char #\\\\ out)"
" (define next (read-char ip))"
" (when (eof-object? next)"
" (error 'latex->content \"trailing backslash in ~e\" source))"
" (write-char next out)"
" (copy)]"
" [#\\{"
" (set! depth (add1 depth))"
" (write-char #\\{ out)"
" (copy)]"
" [#\\}"
" (set! depth (sub1 depth))"
" (write-char #\\} out)"
" (unless (zero? depth)"
" (copy))]"
" [c"
" (write-char c out)"
" (copy)]))"
" (arguments)))")
#:original-lines
'#(" (when (eqv? (peek-char ip) #\\{)"
" (let ([depth 0])"
" (let copy ()"
" (match (read-char ip)"
" [(? eof-object?) (error 'latex->content \"unclosed argument in ~e\" source)]"
" [#\\\\"
" (write-char #\\\\ out)"
" (define next (read-char ip))"
" (when (eof-object? next)"
" (error 'latex->content \"trailing backslash in ~e\" source))"
" (write-char next out)"
" (copy)]"
" [#\\{"
" (set! depth (add1 depth))"
" (write-char #\\{ out)"
" (copy)]"
" [#\\}"
" (set! depth (sub1 depth))"
" (write-char #\\} out)"
" (unless (zero? depth)"
" (copy))]"
" [c"
" (write-char c out)"
" (copy)]))"
" (arguments))))")
#:start-line 126)Syntactic replacement
(syntax-replacement
#:introduction-scope #<procedure:...and/syntax-local.rkt:148:2>
#:new-syntax
#<syntax:.../resyntax/base.rkt:215:28 (when (eqv? (peek-char ip) #\{) (define depth 0) (let copy () (match (read-char ip) ((? eof-object?) (error (quote latex->content) "unclosed argument in ~e" source)) (#\\ (write-char #\\ out) (define next (read-char ip)) (when (eof-object? next) (error ...>
#:original-syntax
#<syntax:scribble-lib/scriblib/private/read-latex.rkt:126:9 (when (eqv? (peek-char ip) #\{) (let ((depth 0)) (let copy () (match (read-char ip) ((? eof-object?) (error (quote latex->content) "unclosed argument in ~e" source)) (#\\ (write-char #\\ out) (define next (read-char ip)) (when (eof-object? next) (error ...>
#:source
(file-source
#<path:/home/runner/work/scribble/scribble/scribble-lib/scriblib/private/read-latex.rkt>)
#:uses-universal-tagged-syntax? #f)| (cond | ||
| [(and display? (not (eqv? (peek-char ip) #\$))) (loop)] | ||
| [else | ||
| (when display? | ||
| (write-char (read-char ip) out)) | ||
| (get-output-string out)])] |
There was a problem hiding this comment.
if-begin-to-cond: Using cond instead of if here makes begin unnecessary
| (cond | |
| [(and display? (not (eqv? (peek-char ip) #\$))) (loop)] | |
| [else | |
| (when display? | |
| (write-char (read-char ip) out)) | |
| (get-output-string out)])] | |
| (cond | |
| [(and display? (not (eqv? (peek-char ip) #\$))) (loop)] | |
| [else | |
| (when display? | |
| (write-char (read-char ip) out)) | |
| (get-output-string out)])] |
Debugging details
Textual replacement
(line-replacement
#:new-lines
'#(" (cond"
" [(and display? (not (eqv? (peek-char ip) #\\$))) (loop)]"
" [else"
" (when display?"
" (write-char (read-char ip) out))"
" (get-output-string out)])]")
#:original-lines
'#(" (if (and display? (not (eqv? (peek-char ip) #\\$)))"
" (loop)"
" (begin"
" (when display?"
" (write-char (read-char ip) out))"
" (get-output-string out)))]")
#:start-line 172)Syntactic replacement
(syntax-replacement
#:introduction-scope #<procedure:...and/syntax-local.rkt:148:2>
#:new-syntax
#<syntax:/home/runner/.local/share/racket/9.3.0.8/pkgs/resyntax/default-recommendations/conditional-shortcuts.rkt:204:2 (cond ((and display? (not (eqv? (peek-char ip) #\$))) (loop)) (else (when display? (write-char (read-char ip) out)) (get-output-string out)))>
#:original-syntax
#<syntax:scribble-lib/scriblib/private/read-latex.rkt:172:12 (if (and display? (not (eqv? (peek-char ip) #\$))) (loop) (begin (when display? (write-char (read-char ip) out)) (get-output-string out)))>
#:source
(file-source
#<path:/home/runner/work/scribble/scribble/scribble-lib/scriblib/private/read-latex.rkt>)
#:uses-universal-tagged-syntax? #f)| (cond | ||
| [(eqv? (peek-char ip) #\{) | ||
| (read-char ip) | ||
| (define body (read-group #t)) | ||
| (emit! (cond | ||
| [(string=? word "emph") (apply emph body)] | ||
| [(string=? word "texttt") (apply tt body)] | ||
| [(string=? word "textit") (apply italic body)] | ||
| [(string=? word "textbf") (apply bold body)] | ||
| [else (make-element bibtex-smallcaps-style body)]))] | ||
| [else | ||
| (emit! (make-element raw-tex-style |
There was a problem hiding this comment.
if-let-to-cond: cond with internal definitions is preferred over if with let, to reduce nesting
| (cond | |
| [(eqv? (peek-char ip) #\{) | |
| (read-char ip) | |
| (define body (read-group #t)) | |
| (emit! (cond | |
| [(string=? word "emph") (apply emph body)] | |
| [(string=? word "texttt") (apply tt body)] | |
| [(string=? word "textit") (apply italic body)] | |
| [(string=? word "textbf") (apply bold body)] | |
| [else (make-element bibtex-smallcaps-style body)]))] | |
| [else | |
| (emit! (make-element raw-tex-style | |
| (cond | |
| [(eqv? (peek-char ip) #\{) | |
| (define body | |
| (begin | |
| (read-char ip) | |
| (read-group #t))) | |
| (emit! (cond | |
| [(string=? word "emph") (apply emph body)] | |
| [(string=? word "texttt") (apply tt body)] | |
| [(string=? word "textit") (apply italic body)] | |
| [(string=? word "textbf") (apply bold body)] | |
| [else (make-element bibtex-smallcaps-style body)]))] | |
| [else | |
| (emit! (make-element raw-tex-style | |
| (list (string-append "\\" word whitespace))))])] |
Debugging details
Textual replacement
(line-replacement
#:new-lines
'#(" (cond"
" [(eqv? (peek-char ip) #\\{)"
" (define body"
" (begin"
" (read-char ip)"
" (read-group #t)))"
" (emit! (cond"
" [(string=? word \"emph\") (apply emph body)]"
" [(string=? word \"texttt\") (apply tt body)]"
" [(string=? word \"textit\") (apply italic body)]"
" [(string=? word \"textbf\") (apply bold body)]"
" [else (make-element bibtex-smallcaps-style body)]))]"
" [else"
" (emit! (make-element raw-tex-style"
" (list (string-append \"\\\\\" word whitespace))))])]")
#:original-lines
'#(" (if (eqv? (peek-char ip) #\\{)"
" (let ([body (begin"
" (read-char ip)"
" (read-group #t))])"
" (emit! (cond"
" [(string=? word \"emph\") (apply emph body)]"
" [(string=? word \"texttt\") (apply tt body)]"
" [(string=? word \"textit\") (apply italic body)]"
" [(string=? word \"textbf\") (apply bold body)]"
" [else (make-element bibtex-smallcaps-style body)])))"
" (emit! (make-element raw-tex-style"
" (list (string-append \"\\\\\" word whitespace)))))]")
#:start-line 261)Syntactic replacement
(syntax-replacement
#:introduction-scope #<procedure:...and/syntax-local.rkt:148:2>
#:new-syntax
#<syntax:/home/runner/.local/share/racket/9.3.0.8/pkgs/resyntax/default-recommendations/let-replacement/cond-let-replacement.rkt:47:2 (cond ((eqv? (peek-char ip) #\{) (define body (begin (read-char ip) (read-group #t))) (emit! (cond ((string=? word "emph") (apply emph body)) ((string=? word "texttt") (apply tt body)) ((string=? word "textit") (apply italic body)) ((string=? word "text...>
#:original-syntax
#<syntax:scribble-lib/scriblib/private/read-latex.rkt:261:18 (if (eqv? (peek-char ip) #\{) (let ((body (begin (read-char ip) (read-group #t)))) (emit! (cond ((string=? word "emph") (apply emph body)) ((string=? word "texttt") (apply tt body)) ((string=? word "textit") (apply italic body)) ((string=? word "textbf"...>
#:source
(file-source
#<path:/home/runner/work/scribble/scribble/scribble-lib/scriblib/private/read-latex.rkt>)
#:uses-universal-tagged-syntax? #f)There was a problem hiding this comment.
Resyntax analyzed 7 files in this pull request and has added suggestions.
| (cond | ||
| [(= depth 1) (unescape-url (get-output-string out))] | ||
| [else | ||
| (write-char #\} out) | ||
| (loop (sub1 depth))])] |
There was a problem hiding this comment.
if-begin-to-cond: Using cond instead of if here makes begin unnecessary
| (cond | |
| [(= depth 1) (unescape-url (get-output-string out))] | |
| [else | |
| (write-char #\} out) | |
| (loop (sub1 depth))])] | |
| (cond | |
| [(= depth 1) (unescape-url (get-output-string out))] | |
| [else | |
| (write-char #\} out) | |
| (loop (sub1 depth))])] |
Debugging details
Textual replacement
(line-replacement
#:new-lines
'#(" (cond"
" [(= depth 1) (unescape-url (get-output-string out))]"
" [else"
" (write-char #\\} out)"
" (loop (sub1 depth))])]")
#:original-lines
'#(" (if (= depth 1)"
" (unescape-url (get-output-string out))"
" (begin"
" (write-char #\\} out)"
" (loop (sub1 depth))))]")
#:start-line 106)Syntactic replacement
(syntax-replacement
#:introduction-scope #<procedure:...and/syntax-local.rkt:148:2>
#:new-syntax
#<syntax:/home/runner/.local/share/racket/9.3.0.8/pkgs/resyntax/default-recommendations/conditional-shortcuts.rkt:204:2 (cond ((= depth 1) (unescape-url (get-output-string out))) (else (write-char #\} out) (loop (sub1 depth))))>
#:original-syntax
#<syntax:scribble-lib/scriblib/private/read-latex.rkt:106:12 (if (= depth 1) (unescape-url (get-output-string out)) (begin (write-char #\} out) (loop (sub1 depth))))>
#:source
(file-source
#<path:/home/runner/work/scribble/scribble/scribble-lib/scriblib/private/read-latex.rkt>)
#:uses-universal-tagged-syntax? #f)| (read-char ip) | ||
| (define body (read-group #t)) | ||
| (emit! (cond | ||
| [(string=? word "emph") (apply emph body)] |
There was a problem hiding this comment.
define-begin-extraction: The begin in this definition can be extracted into the surrounding definition context.
| (read-char ip) | |
| (define body (read-group #t)) | |
| (emit! (cond | |
| [(string=? word "emph") (apply emph body)] | |
| (read-char ip) | |
| (define body (read-group #t)) |
Debugging details
Textual replacement
(line-replacement
#:new-lines
'#(" (read-char ip)"
" (define body (read-group #t))")
#:original-lines
'#(" (define body"
" (begin"
" (read-char ip)"
" (read-group #t)))")
#:start-line 263)Syntactic replacement
(syntax-replacement
#:introduction-scope #<procedure:...and/syntax-local.rkt:148:2>
#:new-syntax
#<syntax:.../resyntax/base.rkt:223:10 (cond ((eqv? (peek-char ip) #\{) (read-char ip) (define body (read-group #t)) (emit! (cond ((string=? word "emph") (apply emph body)) ((string=? word "texttt") (apply tt body)) ((string=? word "textit") (apply italic body)) ((string=? word "textbf") (ap...>
#:original-syntax
#<syntax:scribble-lib/scriblib/private/read-latex.rkt:261:18 (cond ((eqv? (peek-char ip) #\{) (define body (begin (read-char ip) (read-group #t))) (emit! (cond ((string=? word "emph") (apply emph body)) ((string=? word "texttt") (apply tt body)) ((string=? word "textit") (apply italic body)) ((string=? word "text...>
#:source
(file-source
#<path:/home/runner/work/scribble/scribble/scribble-lib/scriblib/private/read-latex.rkt>)
#:uses-universal-tagged-syntax? #f)There was a problem hiding this comment.
Resyntax analyzed 7 files in this pull request and has added suggestions.
| (read-char ip) | ||
| (define body (read-group #t)) | ||
| (emit! (cond | ||
| [(string=? word "emph") (apply emph body)] |
There was a problem hiding this comment.
define-begin-extraction: The begin in this definition can be extracted into the surrounding definition context.
| (read-char ip) | |
| (define body (read-group #t)) | |
| (emit! (cond | |
| [(string=? word "emph") (apply emph body)] | |
| (read-char ip) | |
| (define body (read-group #t)) |
Debugging details
Textual replacement
(line-replacement
#:new-lines
'#(" (read-char ip)"
" (define body (read-group #t))")
#:original-lines
'#(" (define body"
" (begin"
" (read-char ip)"
" (read-group #t)))")
#:start-line 263)Syntactic replacement
(syntax-replacement
#:introduction-scope #<procedure:...and/syntax-local.rkt:148:2>
#:new-syntax
#<syntax:.../resyntax/base.rkt:223:10 (cond ((eqv? (peek-char ip) #\{) (read-char ip) (define body (read-group #t)) (emit! (cond ((string=? word "emph") (apply emph body)) ((string=? word "texttt") (apply tt body)) ((string=? word "textit") (apply italic body)) ((string=? word "textbf") (ap...>
#:original-syntax
#<syntax:scribble-lib/scriblib/private/read-latex.rkt:261:18 (cond ((eqv? (peek-char ip) #\{) (define body (begin (read-char ip) (read-group #t))) (emit! (cond ((string=? word "emph") (apply emph body)) ((string=? word "texttt") (apply tt body)) ((string=? word "textit") (apply italic body)) ((string=? word "text...>
#:source
(file-source
#<path:/home/runner/work/scribble/scribble/scribble-lib/scriblib/private/read-latex.rkt>)
#:uses-universal-tagged-syntax? #f)There was a problem hiding this comment.
Resyntax analyzed 7 files in this pull request and found no issues.
There was a problem hiding this comment.
Resyntax analyzed 7 files in this pull request and found no issues.
There was a problem hiding this comment.
Resyntax analyzed 7 files in this pull request and found no issues.
There was a problem hiding this comment.
Resyntax analyzed 7 files in this pull request and found no issues.
There was a problem hiding this comment.
Resyntax analyzed 7 files in this pull request and found no issues.
|
Can you say more about why location helpers need to be able to return |
There was a problem hiding this comment.
Resyntax analyzed 7 files in this pull request and found no issues.
|
The ability to return Returning content instead of element also seemed more practical to me, considering that the output has a loose structure and is meant to be further aggregated into bigger lists. It seemed to me that at that point, if we really wanted an element, we could better add one in the caller when the content is not #f. But I'm not sure I understand the invariants of Scribble with respect to element vs content vs decoded-content vs blocks vs passes, etc., so I admit I don't really know. |
Improve BibTeX parsing and bibliography rendering
Improve Scribble's support for rich bibliographies, particularly annotated bibliographies with long, formatted, multi-paragraph notes. The immediate motivation is the bibliography of my book Lambda: the Ultimate Object, but the improvements apply to ordinary academic papers as well.
BibTeX parsing
The reader deliberately supports a useful subset of LaTeX rather than attempting to implement a complete TeX interpreter. Unknown commands are preserved rather than silently discarded.
Bibliography rendering
\parboxlayout, which prevented page breaks within bibliography entries, withneedspace, allowing long annotations to span pages. Keep a five-line minimum by default to approximate the previous behavior.needspaceoptional and expose configurable page-breaking and line-breaking settings without imposing new line-breaking parameters on existing documents.The improvements primarily target HTML and LaTeX. Typst receives minimal compatibility support rather than a new rendering implementation.
API, documentation and tests
#frather than necessarily returning an element. This is a public API change.scribble-libto version 1.68.The changes have been exercised against my book's heavily annotated bibliography and reviewed through several rounds of automated and manual testing.
Implementation was substantially assisted by GPT-5.6 Sol, with additional review by Claude Opus 5.5.
Compatibility notes
bibtex-parsenow keeps inner braces in raw field values(e.g. "The {ACM} Paper") so that protected groups survive until
rendering; rendered output is unchanged, but code that reads
bibdb-rawdirectly will now see the braces.they go through the same reader as other fields. Math and unknown
commands are still emitted verbatim in LaTeX output.
--becomesan en dash and straight quotes become curly quotes.
#:chapternow renders as "chapter N".the five-line minimum), and numbered bibliographies use hanging
indentation instead of a table.