# 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 ...