---
title: "argparse Command Line Argument Parsing"
output: rmarkdown::html_vignette
vignette: >
    %\VignetteEngine{knitr::rmarkdown}
    %\VignetteIndexEntry{argparse Command Line Argument Parsing}
    %\VignetteEncoding{UTF-8}
---

argparse is a command line argument parser inspired by Python's "argparse" library.  Use this with Rscript to write "#!"-shebang scripts that accept short and long flags/options and positional arguments, generate a usage statement, and set default values for options that are not specified on the command line.

```{r echo=FALSE}
library("knitr")
rscript_executable <- paste(file.path(R.home(), "bin", "Rscript"), "--vanilla")
opts_knit$set(root.dir = system.file("exec", package = "argparse")) # to access the "Rscript files"
opts_chunk$set(comment = NA, echo = FALSE)
list_file_command <- "ls"
chmod_command <- "chmod ug+x display_file.R example.R"
path_command <- "export PATH=$PATH:`pwd`"
run_command <- function(string) suppressWarnings(cat(system(string, intern = TRUE), sep = "\n"))
```

In our working directory we have two example R scripts, named "example.R" and "display_file.R" illustrating the use of the argparse package.

**`r paste("bash$", list_file_command)`**
```{r}
run_command(sprintf("%s", list_file_command))
command <- "display_file.R example.R" # to show file
```

In order for a \*nix system to recognize a "\#!"-shebang line you need to mark the file executable with the ``chmod`` command, it also helps to add the directory containing your Rscripts to your path:

**`r paste("bash$", chmod_command)`**

**`r paste("bash$", command)`**

Here is what "example.R" contains:

**`r paste("bash$", command)`**
```{r}
run_command(sprintf("%s %s 2>&1", rscript_executable, command))
command <- "example.R --help" # same as system("Rscript example.R -h")
```

By default ``argparse`` will generate a help message if it encounters ``--help`` or ``-h`` on the command line.  Note how ``%(default)s`` in the example program was replaced by the actual default values in the help statement that ``argparse`` generated.

**`r paste("bash$", command)`**
```{r}
run_command(sprintf("%s %s 2>&1", rscript_executable, command))
command <- "example.R" # rely only on defaults
```

If you specify default values when creating your ``ArgumentParser`` then ``argparse`` will use them as expected.

**`r paste("bash$", command)`**
```{r}
run_command(sprintf("%s %s 2>&1", rscript_executable, command))
command <- "example.R --mean=10 --sd=10 --count=3"
```

Or you can specify your own values.

**`r paste("bash$", command)`**
```{r}
run_command(sprintf("%s %s 2>&1", rscript_executable, command))
command <- "example.R --quiet -c 4 --generator=\"runif\"" #  same as above but "quiet"
```

If you remember from the example program that ``--quiet`` had ``action="store_false"`` and 
``dest="verbose"``.  This means that ``--quiet`` is a switch that turns the ``verbose`` option from its default value of ``TRUE`` to ``FALSE``.  Note how the ``verbose`` and ``quiet`` options store their value in the exact same variable.

**`r paste("bash$", command)`**
```{r}
run_command(sprintf("%s %s 2>&1", rscript_executable, command))
command <- "example.R --silent -m 5" #  same as above but "quiet"
```

If you specify an illegal flag then \emph{argparse} will print out a usage message and an error message and quit.  

**`r paste("bash$", command)`**
```{r}
run_command(sprintf("%s %s 2>&1", rscript_executable, command))
command <- "example.R -c 100 -c 2 -c 1000 -c 7" #  same as above but "quiet"
```

If you specify the same option multiple times then \emph{argparse} will use the value of the last option specified. 

**`r paste("bash$", command)`**
```{r}
run_command(sprintf("%s %s 2>&1", rscript_executable, command))
command <- "display_file.R --help"
```

``argparse`` can also parse positional arguments.  Below we give an example program ``display_file.R``, which is a program that prints out the contents of a single file (the required positional argument, not an optional argument) and which accepts the normal help option as well as an option to add line numbers to the output.

**`r paste("bash$", command)`**
```{r}
run_command(sprintf("%s %s 2>&1", rscript_executable, command))
command <- "display_file.R --add_numbers display_file.R"
```

**`r paste("bash$", command)`**
```{r}
run_command(sprintf("%s %s 2>&1", rscript_executable, command))
command <- "display_file.R non_existent_file.txt"
```
**`r paste("bash$", command)`**
```{r}
run_command(sprintf("%s %s 2>&1", rscript_executable, command))
command <- "display_file.R"
```
**`r paste("bash$", command)`**
```{r}
run_command(sprintf("%s %s 2>&1", rscript_executable, command))
```