The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
jsslintr checks LaTeX/BibTeX manuscripts against the Journal of Statistical Software (JSS) style guide and can apply many of the fixes automatically. This vignette walks through the typical workflow: lint, inspect, fix, re-lint.
Let’s write a deliberately sloppy two-file manuscript to work with:
writeLines(c(
"\\documentclass[nojss]{jss}",
"\\author{Jane Doe\\\\University of Somewhere}",
"\\title{A great package for doing things in R}",
"\\Abstract{We present a package for R, e.g. for plotting.}",
"\\Keywords{stuff, things}",
"\\begin{document}",
"\\section{introduction}",
"We use R and the ggplot2 package for our p-values.",
"\\end{document}"
), "paper.tex")
writeLines(c(
"@article{smith2020,",
" author = {John Smith},",
" title = {Some Methods for Data},",
" journal = {Journal of Statistical Software},",
" year = {2020},",
" volume = {95},",
" pages = {1--20}",
"}"
), "refs.bib")jsslint() takes the file paths, reads them, and returns
a check result. Printing it gives a quick overview; each line is one
issue in file:line:column form. (Called with no arguments,
jsslint() checks every
.tex/.ltx/.bib file in the
working directory.)
library("jsslintr")
res <- jsslint(c("paper.tex", "refs.bib"))
res
#> JSS style check (journal "jss"): paper.tex, refs.bib
#> Compliance: 75.0%
#>
#> 6 issues (6 warnings; 5 auto-fixable)
#>
#> paper.tex:3:1 [warning] JSS-CAP-001 \title{} is in title style (principal words capitalised)
#> paper.tex:4:36 [warning] JSS-MARKUP-001 Programming-language names in prose are wrapped in \proglang{}
#> paper.tex:4:39 [warning] JSS-HOUSE-001 "e.g." and "i.e." are followed by a comma so LaTeX does not treat the period as a sentence end
#> paper.tex:8:8 [warning] JSS-MARKUP-001 Programming-language names in prose are wrapped in \proglang{}
#> paper.tex:8:18 [warning] JSS-MARKUP-002 Software-package names in prose are wrapped in \pkg{}
#> paper.tex:8:42 [warning] JSS-OPER-001 Symbol-plus-noun constructs like p-value and t-statistic are typeset as $p$~value and $t$~statistic (tie, no hyphen)
#>
#> Use summary() for a breakdown by rule and category, and jssfix() to apply the 5 automatic fixes.summary() breaks the issues down by rule, file, and
style-guide category:
summary(res)
#> JSS style check (journal "jss"): paper.tex, refs.bib
#> Compliance: 75.0% -- 6 issues (6 warnings; 5 auto-fixable)
#>
#> Files:
#> file error warning info total
#> paper.tex 0 6 0 6
#> refs.bib 0 0 0 0
#>
#> Issues by rule:
#> rule_id severity issues fixable guide_section
#> JSS-MARKUP-001 warning 2 2 §4.1 Markup
#> JSS-CAP-001 warning 1 0 §6.2 Capitalisation
#> JSS-HOUSE-001 warning 1 1 §8.1 House style
#> JSS-MARKUP-002 warning 1 1 §4.1 Markup
#> JSS-OPER-001 warning 1 1 §4.4 Mathematical notation
#>
#> Categories:
#> category status rules_passed issues
#> Preamble PASS 8/8 0
#> Structure PASS 6/6 0
#> Markup FAIL 2/4 3
#> Citations PASS 3/3 0
#> References PASS 6/6 0
#> BibTeX PASS 5/5 0
#> Naming PASS 2/2 0
#> Capitalization FAIL 2/3 1
#> Typography PASS 4/4 0
#> Abbreviations PASS 1/1 0
#> Code style PASS 3/3 0
#> Code width PASS 1/1 0
#> Operators FAIL 3/4 1
#> Cross-references PASS 7/7 0
#> House style FAIL 2/3 1
#> Project PASS 2/2 0For programmatic access — filtering, counting, or feeding issues into
your own tooling — as.data.frame() gives one row per issue,
including the suggested rewrite and whether an automatic fix exists:
df <- as.data.frame(res)
df[df$fixable, c("file", "line", "rule_id", "suggestion")]
#> file line rule_id
#> 2 paper.tex 4 JSS-MARKUP-001
#> 3 paper.tex 4 JSS-HOUSE-001
#> 4 paper.tex 8 JSS-MARKUP-001
#> 5 paper.tex 8 JSS-MARKUP-002
#> 6 paper.tex 8 JSS-OPER-001
#> suggestion
#> 2 Wrap 'R' in \\proglang{R}.
#> 3 Add a comma after 'e.g.': 'e.g.,'.
#> 4 Wrap 'R' in \\proglang{R}.
#> 5 Wrap 'ggplot2' in \\pkg{ggplot2}.
#> 6 Replace 'p-values' with '$p$~values' (italicized symbol, tie).jssfix() applies the automatic fixes in place. Pass the
check result (its files and options are reused) or file paths directly.
With dry_run = TRUE it only shows the diff of what would
change:
jssfix(res, dry_run = TRUE)
#> --- paper.tex
#> +++ paper.tex
#> @@ -1,9 +1,9 @@
#> \documentclass[nojss]{jss}
#> \author{Jane Doe\\University of Somewhere}
#> \title{A great package for doing things in R}
#> -\Abstract{We present a package for R, e.g. for plotting.}
#> +\Abstract{We present a package for \proglang{R}, e.g., for plotting.}
#> \Keywords{stuff, things}
#> \begin{document}
#> \section{introduction}
#> -We use R and the ggplot2 package for our p-values.
#> +We use \proglang{R} and the \pkg{ggplot2} package for our $p$~values.
#> \end{document}
#>
#> Dry run: 5 fixes would be applied to 1 file. Re-run with dry_run = FALSE to write.That looks right, so let it write the files:
jssfix(res)
#> Applied 5 fixes to 1 file:
#> paper.tex: 5 fixes
#> Re-run jsslint() to review the remaining issues.Fixes are applied atomically, and a fix that would reintroduce its
own violation is rolled back. Overlapping fixes are resolved to one
winner per span; if any were skipped as conflicting, running
jssfix() again picks them up. A rules argument
restricts fixing to selected rules, e.g.,
jssfix(res, rules = "JSS-HOUSE-001").
The remaining issues need manual attention — the printed suggestions say what to do:
jsslint(c("paper.tex", "refs.bib"))
#> JSS style check (journal "jss"): paper.tex, refs.bib
#> Compliance: 87.5%
#>
#> 2 issues (2 warnings; 0 auto-fixable)
#>
#> paper.tex:3:1 [warning] JSS-CAP-001 \title{} is in title style (principal words capitalised)
#> paper.tex:8:29 [warning] JSS-CITE-002 First occurrence of a software package has a citation within the same paragraph
#>
#> Use summary() for a breakdown by rule and category.render() is the bare in-memory binding underneath
jsslint(): it takes a named character vector (names =
paths, values = contents) and returns a report rendered as
"terminal", "json", "sarif", or
"html" text — useful when the files never touch disk or you
want machine-readable output:
cat(substr(render(c("paper.tex" = "\\documentclass{article}"),
output = "json"
), 1, 300), "...\n")
#> {
#> "categories": [
#> {
#> "category_id": "preamble",
#> "rules_applied": 8,
#> "rules_passed": 7,
#> "status": "FAIL",
#> "title": "Preamble"
#> },
#> {
#> "category_id": "structure",
#> "rules_applied": 6,
#> "rules_passed": 6,
#> "status": "PASS",
#> "title": "St ...These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.