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.

Checking a Paper with jsslintr

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.

A small example paper

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")

Lint

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.

Inspect

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      0

For 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).

Fix

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").

Re-lint

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.

Lower-level access

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.