Skip to content
/ argmap Public

tools for working with argument maps represented in YAML

License

Notifications You must be signed in to change notification settings

dsanson/argmap

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

35 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Argument Maps in YAML

This project is not being actively maintained by me at the moment. If you are interested in it, you might consider Michael Hayes's fork: https://github.com/s6mike/argmap

This repository contains some tools for working with argument maps written in a relatively simple YAML format, described below. For example, the map above was generated from this YAML:

"Brunellus is irrational":
  r1:
    "Brunellus is a donkey.":
    "All donkeys are irrational.": 
  o1:
    "Brunellus studied in Paris.":
    "-Most who study in Paris are rational.":

The map above is also a hyper-link: click on it to open an version of the map in Mindmup's Argument Visualization Mode.

Installation

Place argmap2mup, argmap2tikz, and mup2argmap somewhere in your path. Place pandoc-argmap.lua in the filters folder inside your pandoc data directory, e.g., $HOME/.pandoc/filters/pandoc-argmap.lua.

Dependencies

argmap2mup, argmap2tikz, and mup2argmap require penlight (for command line option parsing), , lyaml (for parsing YAML), and json (for encoding JSON). You can install these with:

$ luarocks install penlight
$ luarocks install lyaml
$ luarocks install json

argmap2mup and mup2argmap also depend on the command line utility gdrive for Google Drive integration. Follow the link for installation instructions.

Converting the tikz code generated by argmap2tikz to PDF requires several TeX packages, some of which you may need to install if they are not already available on your system.

pandoc-argmap.lua depends on pandoc, and on argmap2lua and argmap2tikz. It also depends on pdf2svg for conversion to svg, and ImageMagick's convert for conversion to png.

Some Examples of Basic Usage

There are some example files in the examples folder in the repository. Here are some things to try:

$ cat example.yml | argmap2mup > example.mup: generate a MindMup map from example.yml. Import that map into MindMup to work with.

$ argmap2mup -u example-2.yml: generate a MindMup map and upload it to your Google Drive. You can then go to Google Drive and open the map in MindMup to work with it.

Create an argument map on Mindmup and download it as a MindMup file (File → Download As → MindMup). Now convert it to YAML:

mup2argmap download.mup > download.yml

Next, try generating a PDF image from example.yml:

$ cat example.yml | argmap2tikz -s > example.tex
$ lualatex example

Finally, try generating an HTML document from a markdown document containing an embedded argument map:

$ pandoc example.md -o example.html --lua-filter pandoc-argmap.lua

Argument Maps in YAML

The goal here is to describe a spec for argument maps that is relatively easy for humans to read and write. The spec we use is much less ambitious than other specs that I know of, like Argdown and the Argument Interchange Format.

For our purposes, an argument map consists of claims and reasons: each claim can be supported by zero or more reasons; each reason consists of zero or more claims.

We represent each claim as a key-value pair:

  • the key is the content of the claim;
  • the value is a (possibly empty) list of reasons.

So here is how we represent the claim that Brunellus is irrational unsupported by any reasons:

"Brunellus is irrational": {}

We also represent each reason as a key-value pair:

  • the key is an identifier;
  • the value is a (possibly empty) list of claims.

For example, here is a reason that consists of two claims:

  reason1:
    "Brunellus is a donkey.": {}
    "All donkeys are irrational.": {} 

There are two kinds of reasons: supporting reasons and reasons against (i.e., objections). We use the identifier to represent this difference:

  • a reason whose key begins with an o or - is an objection;
  • all other reasons are supporting reasons.

So that takes us back to our original example:

"Brunellus is irrational":
  r1:
    "Brunellus is a donkey.": {}
    "All donkeys are irrational.": {}
  o1:
    "Brunellus studied in Paris.": {}
    "-Most who study in Paris are rational.": {}

Note the '-' before "Most who study..". Claims are either explicit or implicit. We use the key to represent this:

  • a claim whose key begins with a - is implicit;
  • all other claims are explicit.

We also include a way to attach a single note to each claim, and a way to label reasons and specify their relative strength.

Unique Identifiers

Note that the reasons for a given claim cannot share the same identifier. Something like this will lead to unpredictable behavior:

"Brunellus is irrational":
  reason: {}
  reason: {}

The resulting map will only display a single reason, and which one it will choose in unpredictable.

Instead, you need to ensure that the keys are distinct:

"Brunellus is irrational.":
  reason1: {}
  reason2: {}

Reasons for distinct claims can have the same identifier. So this is okay:

"Brunellus is a donkey.": 
  reason1: {}
"All donkeys are irrational.":
  reason1: {}

The same holds for claims: each of the claims that make up a given reason must have distinct keys. So don't write something like this:

"Brunellus is irrational":
  r1:
    "Brunellus is a donkey.": {}
    "Brunellus is a donkey.": {}

Since the key is the content of the claim, this restriction makes sense: you would not want to represent the same premise twice as part of a single reason. But, of course, the same premise can occur as part of two distinct reasons:

"Brunellus is irrational":
  r1:
    "Brunellus is a donkey.": {}
    "All donkeys are irrational.": {}
  r2:
    "Brunellus is a donkey.": {}
    "Most donkeys I've met have been irrational.": {}

Empty Lists

Note that every claim is represented as key-value pair, where the value is a list of reasons. If there are no reasons offered for or against a claim, that means that the value is an empty list. You can represent this empty list explicitly if you like:

    "Brunellus is a donkey.": {}

Or you can leave it implicit, omitting the '{}'. But you still must put the colon (':') after the claim:

    "Brunellus is a donkey.": 

In practice, the implicit empty list notation is preferred, because it means you don't have to delete the braces before adding reasons in support of a claim.

Keys and Quotation

YAML allows just about any string to be a key, but you do have to be careful about quotes and line-wrapping. If your key has no special characters, like ':', you get away with omitting the quotes:

    Brunellus is a donkey.: 

Multiline keys are also possible, but the format is a bit complicated (1, 2)

?
 "Brunellus is a donkey who wanted a longer tail, and he went to Paris
 to study, but he couldn't remember the city's name."
:
  r1:
    ?
     "The wikipedia says that Brunellus is a donkey who wanted a longer
     tail, and he went to Paris to study, but he couldn't remember the
     city's name."
    :
    ?
     "The wikipedia is a reliable source for information about donkeys
     in medieval literature."
    :

Markdown Formatting

Each claim key is processed by pandoc. This means that you should be able to get away with using simple markdown inside the claim keys.

"Brunellus is *probably* 90% H~2~O":

Keep in mind that MindMup offers very limited support for formatted text. So, for MindMup maps, formatting will be converted to pandoc's "plain" output:

Brunellus is _probably_ 90% H₂O

For TikZ maps, formatting will be converted to latex:

Brunellus is \emph{probably} 90\% H\textsubscript{2}O

Notes, Labels, and Strength

(Currently, notes are only supported for MindMup input and output, and do not appear in TikZ output.)

You can attach one note to any claim (if you attach more than one note, only one of them will be processed). A note is represented by a key-value pair, where the key is the string "note" and the value is the content of the note. To attach a note to a claim, add it to the list of reasons:

Brunellus is irrational:
  r1:
    Brunellus is a donkey.: 
      note: |
        Brunellus means "brown one" in Latin, and was the name of a stock
        character in medieval logic texts.
    All donkeys are irrational.: 
  note: |
    Although donkeys *are* notoriously stubborn, it seems a bit much to
    suppose that irrationality is the defining feature of a donkey.

Notes are also processed by pandoc, allowing the use of simple markdown.

You can attach a label or strength to any reason. A label is a key-value pair, where the key is the string "label" and the value is the content of the label. A strength is a key-value pair, where the key is "strength" and the value is a number between 1 (weak) and 5 (strong). Labels and strengths are added to the list of a reason's claims:

Brunellus is irrational:
  r1:
    Brunellus is a donkey.: 
    All donkeys are irrational.:
    label: argumentum ad asinum
    strength: 4
  o1:                                            
    Brunellus studied in Paris.: 
    -Most who study in Paris are rational.:
    label: argumentum ad parisiensis
    strength: 2

argmap2mup

argmap2mup is a pipe for converting YAML maps to JSON encoded MindMup maps. It takes as its input the first cli argument that is not an option, or, if there is no such argument, STDIN.

$ cat example.yml | argmap2mup | jq
{
  ⋮
  "ideas": {
    "1": {
      "attr": {},
      "title": "Brunellus is irrational",
      ⋮
}

(Here I've used jq to pretty-print the JSON output.)

The following options are available:

-u, --upload: Upload to Google Drive.

If this option is selected, then, instead of dumping the map to STDOUT, it is uploaded to Google Drive, and its Google Drive ID is returned.

$  argmap2mup -u example.yml
1e4HAl1iHPKBiKZ_BI_yBw7rXYbuvMsC2

If you have connected your MindMup account to Google Drive, you can use this Google Drive ID to construct a URL that allows you to open the file directly in MindMup. The format for the URL is:

https://drive.mindmup.com/map/ID

-g ID, --gdrive_id ID: Update the file with ID on Google Drive.

By default, argmap2mup creates a new file on your Google Drive every time you run it. If you have already uploaded a map, and would prefer to update that map rather than create a new one, use this option to specify its Google Drive ID. If you don't know its Google Drive ID, use gdrive list to find it. This command implies --upload:

$ cat example.yml | argmap2mup -g 1e4HAl1iHPKBiKZ_BI_yBw7rXYbuvMsC2
1e4HAl1iHPKBiKZ_BI_yBw7rXYbuvMsC2

-f ID, --folder ID: upload to Google Drive folder with ID

For example, I prefer to upload all of my automatically generated maps to a folder called argmaps.

p, --public: Mark the uploaded file as shareable.

By default, files uploaded to Google Drive are private and unshared. Use this flag to mark them as shareable instead. This option also implies --upload.

-n, --name: Specify a name for your map.

This name is used to set the title attribute within the map itself. It is also used as the name of the file on Google Drive. If this option is omitted, and so no name is specified, the conclusion of the argument will be used as the name. No sanity checks are performed on this: no doubt you can break things by specifying weird things as the name.

-h, --help: Display a brief synopsis of these options.

mup2argmap

mup2argmap is a pipe for converting MindMup maps into the argmap YAML format. It takes as its input the first cli argument that is not an option, or, if there is no such argument, STDIN.

cat example.mup | mup2argmap
mup2argmap example.mup

The following options are available:

-g ID, --gdrive_id ID: read the file with the specified Google Drive ID.

This option takes precedence any files specified on the command line or anything piped to STDIN.

-e, --embed: wrap output in a pandoc markdown code block with attributes, suitable for embedding.

-h, --help: Display a brief synopsis of these options.

argmap2tikz

argmap2tikz is a pipe for converting YAML maps to TikZ pictures, suitable for embedding in LaTeX. It takes as its input the first cli argument that is not an option, or, if there is no such argument, STDIN.

$ cat example.yml | argmap2tikz
\begin{tikzpicture}
  ⋮ 
  {
    c1/"Brunellus is irrational
"[claim]
      --[opposingedge]
      r2/"" [opposing] // [ tree layout ] {
      ⋮
\end{tikzpicture}      

Note that it uses TikZ's graph support, and TikZ's graph support only works with lualatex. So you need to use lualatex instead of pdflatex or xelatex to convert the tikz code to PDF.

Also note that the resulting tikz code requires some settings in your preamble. For the required settings, see the --includes option below.

The following options are available:

-s, --standalone: generate a standalone LaTeX file.

$ argmap2tikz -s example.yml
\documentclass[tikz]{standalone}
    \usepackage{tikz}
    \usetikzlibrary{graphs,graphdrawing}
    ⋮
\begin{document}
\begin{tikzpicture}
    ⋮
\end{tikzpicture}
\end{document}

This standalone LaTeX file is suitable for generating a PDF image of the map, which can then be used as is or converted into other formats using other tools, e.g.,

$ argmap2tikz -s example.yml > example.tex
$ lualatex example
$ convert example.pdf example.png

-i, --includes: dump lines suitable for including in a LaTeX preamble

-t, --template: dump lines suitable for including in a LaTeX preamble in a pandoc template.

If you want to use the tikz code inside your own LaTeX file, include the output of --includes in your preamble:

$ argmap2tikz -i
    \usepackage{tikz}
    \usetikzlibrary{graphs,graphdrawing}
    ⋮
    \usepackage{varwidth}
    \newcommand{\argmapmaxnodewidth}{15em}

If you want to use the tikz code with pandoc, include the output of --template in a custom pandoc LaTeX template, and set the metadata variable argmaps to true, either in your document's YAML metadata block, or using the --metadata option.

$ argmap2tikz -t
$if(argmaps)$
    \usepackage{tikz}
    \usetikzlibrary{graphs,graphdrawing}
    ⋮
    \usepackage{varwidth}
    \newcommand{\argmapmaxnodewidth}{15em}
$endif$

-h, --help: Display a brief synopsis of these options.

pandoc-argmap.lua

pandoc-argmap.lua is a pandoc lua filter for converting YAML argument maps embedded in a pandoc document, using argmap2mup and argmap2tikz.

Default Google Folder

I put a line like this at the top of my personal copy of pandoc-argmap.lua:

local gdriveFolder = "11w-foIj3p_FWSUROEX0VJg1KsslhJR0m"

This tells pandoc to upload all the maps it generates to a specific folder on my Google Drive.

Embedding Maps in Markdown

Embedded argument maps are represented as code blocks with the class argmap.

```{.argmap}
"Brunellus is irrational":
  r1:
    "Brunellus is a donkey.":
    "All donkeys are irrational.":
  o1:
    "Brunellus studied in Paris.":
    "-Most who study in Paris are rational.":
```

A name and Google Drive ID can also be specified as attributes of the code block:

``` {.argmap name="A Donkey Argument" gid="1X6uD8KyrSawW2qSqhmPaNtuSy-6eEK6g"}
"Brunellus is irrational":
  r1:
    "Brunellus is a donkey.":
    "All donkeys are irrational.": 
  o1:
    "Brunellus studied in Paris.":
    "-Most who study in Paris are rational.":
```

Processing Maps

To process a file containing argument maps, use the --lua-filter option with pandoc:

$ pandoc example.md -o example.html --lua-filter pandoc-argmap.lua

If you want to generate a PDF file using LaTeX, you will also need to use the --pdf-engine=lualatex option, and use a custom template with the --template:

$ pandoc example.md -o example.pdf --lua-filter pandoc-argmap.lua --pdf-engine lualatex --template example-template.latex

If you prefer, you could use the --include-in-header option instead of a custom template:

$ argmap2tikz -i > header.tex
$ pandoc example.md -o example.pdf --lua-filter pandoc-argmap.lua --pdf-engine lualatex --include-in-header header.tex

Output

With one exception, pandoc-argmap.lua replaces each embedded YAML map with a TikZ generated image of the map, generates a MindMup map and uploads it to Google Drive, and links the image to the MindMup url.

Here is the exception: if your output format is markdown and the map has the attribute "tidy" set to "true",

```{.argmap tidy=true}
"Brunellus is irrational":
```

then the filter will generate and upload a MindMup map to Google Drive, but it will not use TikZ to generate any images. In addition, if a gid attribute will be added to the code block, pointing to the map on Google Drive. That makes this a useful way to associate the map in your markdown file with a specific map on your Google Drive, so that future conversions will update that map, rather than cluttering your Google Drive by generating a new map every time.

LaTeX and PDF output

If the output format is latex, the filter directly embeds the tikzpicture code into the latex file as raw latex. This is why, if you want to use pandoc to directly produce a PDF using one of its latex engines, you will need to specify --pdf-engine lualatex and use a custom template or the --include-in-header option.

$ pandoc example.md -o example.pdf --lua-filter pandoc-argmap.lua --template
custom.latex --pdf-engine lualatex

HTML5 Output

If the output format is html5, the filter generates individual pdf files for each map, and then uses pdf2svg to convert them to svg, which it embeds directly into the html file.

Output in All Other Formats

For all other formats, it uploads the mindmup file to Google Drive and generates individual pdf files for each map, and then converts them to png using ImageMagick's convert command. It replaces the code block with a paragraph containing the generated image, linked to the mindmup file.

TODO

  • add sane syntax checking: right now, if you mess up the syntax of your map, everything breaks.
  • improve the tikz styling of maps.
    • support for labels in tikz output
    • support for strength in tikz output
    • support for notes in tikz output
    • the green and red "umbrellas" should only be as wide as the claim boxes immediately beneath them.
    • the green and red edges should be curved.
  • support for other formats?
    • import/export rationale?
    • DOT output? (See AIF's DOT format?)
  • merge the three pipes into a single argmap command, using cli options to select input and output formats
  • mup2argmap should support fetching mup files from Google Drive and offer embeddable output (i.e., code block with both name and gid attributes)

About

tools for working with argument maps represented in YAML

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages