├── diff.pdf ├── template.pdf ├── .gitignore ├── diamondrule.pdf ├── figs ├── 4-slab.pdf ├── teaser.pdf ├── 3-dots_two.pdf ├── 3-dots_emoji.png ├── 3-lineribbon.pdf ├── 3-slab_rope.pdf ├── emoji-frown.png ├── emoji-smile.png ├── 2-mpg_v_weight.pdf ├── 3-slab_raindrop.pdf ├── 4-slab_pipeline.pdf ├── 3-lineribbon_fan.pdf ├── 3-slab_consonance.pdf ├── 3-slab_fuzzygram.pdf ├── teaser-raincloud.pdf ├── teaser-weepeople.pdf ├── 2-mean_sd_interval.pdf ├── 2-xmin_xmax_interval.pdf ├── 3-jacobian-correct.pdf ├── 3-jacobian-incorrect.pdf ├── 3-jacobian-lognorm.pdf ├── teaser-mtcars-lines.pdf ├── teaser-slabinterval.pdf ├── 3-slab_violin_gradient.pdf ├── 3-slab_violin_interval.pdf ├── 3-stat_pointinterval_A.pdf ├── teaser-logit_dotplots.pdf ├── 3-slab_density_two_groups.pdf ├── 3-slab_gradient_correll.pdf ├── 3-slab_gradient_two_groups.pdf ├── 3-stat_pointinterval_color.pdf ├── 3-stat_pointinterval_normal.pdf ├── 3-geom_pointinterval_quantiles.pdf ├── 3-stat_pointinterval_linewidth.pdf └── 3-stat_pointinterval_student_t.pdf ├── issues_tagged.xlsx ├── template-tagged.pdf ├── fonts ├── wee-people │ ├── weepeople.ttf │ └── LICENSE.md └── source-sans │ ├── SourceSansPro-Black.ttf │ ├── SourceSansPro-Bold.ttf │ ├── SourceSansPro-Light.ttf │ ├── SourceSansPro-Italic.ttf │ ├── SourceSansPro-Regular.ttf │ ├── SourceSansPro-SemiBold.ttf │ ├── SourceSansPro-BoldItalic.ttf │ ├── SourceSansPro-ExtraLight.ttf │ ├── SourceSansPro-BlackItalic.ttf │ ├── SourceSansPro-LightItalic.ttf │ ├── SourceSansPro-SemiBoldItalic.ttf │ ├── SourceSansPro-ExtraLightItalic.ttf │ └── OFL.txt ├── ggdist-paper.Rproj ├── README.md ├── diamondrule.eps ├── issues.Rmd ├── makefile ├── BUILDING.md ├── LICENSE.md ├── template.bib ├── figures.Rmd ├── abbrv-doi-hyperref.bst ├── abbrv-doi.bst └── abbrv-doi-hyperref-narrow.bst /diff.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/diff.pdf -------------------------------------------------------------------------------- /template.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/template.pdf -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | models/ 6 | *~ 7 | -------------------------------------------------------------------------------- /diamondrule.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/diamondrule.pdf -------------------------------------------------------------------------------- /figs/4-slab.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/4-slab.pdf -------------------------------------------------------------------------------- /figs/teaser.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/teaser.pdf -------------------------------------------------------------------------------- /figs/3-dots_two.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/3-dots_two.pdf -------------------------------------------------------------------------------- /issues_tagged.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/issues_tagged.xlsx -------------------------------------------------------------------------------- /template-tagged.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/template-tagged.pdf -------------------------------------------------------------------------------- /figs/3-dots_emoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/3-dots_emoji.png -------------------------------------------------------------------------------- /figs/3-lineribbon.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/3-lineribbon.pdf -------------------------------------------------------------------------------- /figs/3-slab_rope.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/3-slab_rope.pdf -------------------------------------------------------------------------------- /figs/emoji-frown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/emoji-frown.png -------------------------------------------------------------------------------- /figs/emoji-smile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/emoji-smile.png -------------------------------------------------------------------------------- /figs/2-mpg_v_weight.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/2-mpg_v_weight.pdf -------------------------------------------------------------------------------- /figs/3-slab_raindrop.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/3-slab_raindrop.pdf -------------------------------------------------------------------------------- /figs/4-slab_pipeline.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/4-slab_pipeline.pdf -------------------------------------------------------------------------------- /figs/3-lineribbon_fan.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/3-lineribbon_fan.pdf -------------------------------------------------------------------------------- /figs/3-slab_consonance.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/3-slab_consonance.pdf -------------------------------------------------------------------------------- /figs/3-slab_fuzzygram.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/3-slab_fuzzygram.pdf -------------------------------------------------------------------------------- /figs/teaser-raincloud.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/teaser-raincloud.pdf -------------------------------------------------------------------------------- /figs/teaser-weepeople.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/teaser-weepeople.pdf -------------------------------------------------------------------------------- /figs/2-mean_sd_interval.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/2-mean_sd_interval.pdf -------------------------------------------------------------------------------- /figs/2-xmin_xmax_interval.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/2-xmin_xmax_interval.pdf -------------------------------------------------------------------------------- /figs/3-jacobian-correct.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/3-jacobian-correct.pdf -------------------------------------------------------------------------------- /figs/3-jacobian-incorrect.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/3-jacobian-incorrect.pdf -------------------------------------------------------------------------------- /figs/3-jacobian-lognorm.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/3-jacobian-lognorm.pdf -------------------------------------------------------------------------------- /figs/teaser-mtcars-lines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/teaser-mtcars-lines.pdf -------------------------------------------------------------------------------- /figs/teaser-slabinterval.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/teaser-slabinterval.pdf -------------------------------------------------------------------------------- /figs/3-slab_violin_gradient.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/3-slab_violin_gradient.pdf -------------------------------------------------------------------------------- /figs/3-slab_violin_interval.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/3-slab_violin_interval.pdf -------------------------------------------------------------------------------- /figs/3-stat_pointinterval_A.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/3-stat_pointinterval_A.pdf -------------------------------------------------------------------------------- /figs/teaser-logit_dotplots.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/teaser-logit_dotplots.pdf -------------------------------------------------------------------------------- /fonts/wee-people/weepeople.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/fonts/wee-people/weepeople.ttf -------------------------------------------------------------------------------- /figs/3-slab_density_two_groups.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/3-slab_density_two_groups.pdf -------------------------------------------------------------------------------- /figs/3-slab_gradient_correll.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/3-slab_gradient_correll.pdf -------------------------------------------------------------------------------- /figs/3-slab_gradient_two_groups.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/3-slab_gradient_two_groups.pdf -------------------------------------------------------------------------------- /figs/3-stat_pointinterval_color.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/3-stat_pointinterval_color.pdf -------------------------------------------------------------------------------- /figs/3-stat_pointinterval_normal.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/3-stat_pointinterval_normal.pdf -------------------------------------------------------------------------------- /figs/3-geom_pointinterval_quantiles.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/3-geom_pointinterval_quantiles.pdf -------------------------------------------------------------------------------- /figs/3-stat_pointinterval_linewidth.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/3-stat_pointinterval_linewidth.pdf -------------------------------------------------------------------------------- /figs/3-stat_pointinterval_student_t.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/figs/3-stat_pointinterval_student_t.pdf -------------------------------------------------------------------------------- /fonts/source-sans/SourceSansPro-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/fonts/source-sans/SourceSansPro-Black.ttf -------------------------------------------------------------------------------- /fonts/source-sans/SourceSansPro-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/fonts/source-sans/SourceSansPro-Bold.ttf -------------------------------------------------------------------------------- /fonts/source-sans/SourceSansPro-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/fonts/source-sans/SourceSansPro-Light.ttf -------------------------------------------------------------------------------- /fonts/source-sans/SourceSansPro-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/fonts/source-sans/SourceSansPro-Italic.ttf -------------------------------------------------------------------------------- /fonts/source-sans/SourceSansPro-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/fonts/source-sans/SourceSansPro-Regular.ttf -------------------------------------------------------------------------------- /fonts/source-sans/SourceSansPro-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/fonts/source-sans/SourceSansPro-SemiBold.ttf -------------------------------------------------------------------------------- /fonts/source-sans/SourceSansPro-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/fonts/source-sans/SourceSansPro-BoldItalic.ttf -------------------------------------------------------------------------------- /fonts/source-sans/SourceSansPro-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/fonts/source-sans/SourceSansPro-ExtraLight.ttf -------------------------------------------------------------------------------- /fonts/source-sans/SourceSansPro-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/fonts/source-sans/SourceSansPro-BlackItalic.ttf -------------------------------------------------------------------------------- /fonts/source-sans/SourceSansPro-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/fonts/source-sans/SourceSansPro-LightItalic.ttf -------------------------------------------------------------------------------- /fonts/source-sans/SourceSansPro-SemiBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/fonts/source-sans/SourceSansPro-SemiBoldItalic.ttf -------------------------------------------------------------------------------- /fonts/source-sans/SourceSansPro-ExtraLightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjskay/ggdist-paper/main/fonts/source-sans/SourceSansPro-ExtraLightItalic.ttf -------------------------------------------------------------------------------- /ggdist-paper.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Makefile 19 | -------------------------------------------------------------------------------- /fonts/wee-people/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 ProPublica and Alberto Cairo 2 | 3 | You can use this font for free if you follow the rules: 4 | 5 | 1. If you use Wee People you have to credit us. 6 | 2. Wee People can't be sold separately. It’s okay to use it on pages with ads, or as a design element in a publication for which money is charged. 7 | 3. You can’t alter the shapes in Wee People or add new shapes without our approval. 8 | 9 | 10 | This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 United States License. To view a copy of this license, visit [http://creativecommons.org/licenses/by-nc-nd/3.0/us/](http://creativecommons.org/licenses/by-nc-nd/3.0/us/) or send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Source and supplement for the paper *ggdist: Visualizations of Distributions and Uncertainty in the Grammar of Graphics* 2 | 3 | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.7770984.svg)](https://doi.org/10.5281/zenodo.7770984) 4 | 5 | *Matthew Kay, Northwestern University* 6 | 7 | This repository is based on the IEEE TVCG paper format repository. The main files of interest are: 8 | 9 | * `BUILDING.md`: The original `README` file from the IEEE TVCG template repository, which contains instructions for building the paper from source. 10 | * `template.tex`: The source LaTeX file for the body of the paper. 11 | * `template.pdf`: The rendered paper. 12 | * `template-tagged.pdf`: The rendered paper, with accessibility tags added. 13 | * `figures.Rmd`: The RMarkdown file used to generate figures for the paper. 14 | * `issues.json`, `issues.csv`: An archive of [*ggdist* Github issues](https://github.com/mjskay/ggdist/issues). 15 | * `issues_tagged.csv`, `issues_tagged.xlsx`: A lightly-tagged version of the *ggdist* Github issues. 16 | * `issues.Rmd`: The RMarkdown file used to generate description statistics of the *ggdist* Github issues. 17 | -------------------------------------------------------------------------------- /diamondrule.eps: -------------------------------------------------------------------------------- 1 | %!PS-Adobe-3.0 EPSF-3.0 2 | %%Title: diamondrule2.eps 3 | %%Creator: Gordon Kindlmann + emacs (TLA) 4 | %%BoundingBox: 0 0 213 12 5 | %%HiResBoundingBox: 0 0 213 12 6 | %%Pages: 1 7 | %%EndComments 8 | %%BeginProlog 9 | %%EndProlog 10 | %%Page: 1 1 11 | 12 | % This is very much like "diamondrule.eps", but simpler, shorter, better 13 | % centered, and slightly thinner. Unlike in the original "diamondrule.eps": 14 | % * Diamond is made of circular arcs (with no rounding at the tips) 15 | % * Diamond is centered between the two lines 16 | % * The two lines are centered vertically 17 | % * The BoundingBox and HiResBoundingBox are equal. The original 18 | % HiResBoundingBox was 0 0 212.9981 12.2764 19 | % * The vertical height was decreased from 13 to 12 points, in recognition 20 | % of what the height was in the original HiResBoundingBox (12.2764). 21 | 22 | 0 setgray % everything is black 23 | 24 | 0 setlinecap % line parameters 25 | 0.92 setlinewidth 26 | 27 | 0 6 moveto % first line (original lines were at Y ~= 6.3) 28 | 95.45 0 rlineto stroke 29 | 30 | 213 6 moveto % second line 31 | -95.45 0 rlineto stroke 32 | 33 | gsave % diamond 34 | 106.5 6 translate % center (original was at around 106.755 5.875) 35 | 4.55 dup scale % size 36 | 0.31 % smaller means more concave on sides 37 | dup dup 1 add dup % begin stack hacking ... 38 | dup 39 | dup dup mul 40 | 5 -1 roll 41 | dup mul 42 | add sqrt 43 | 5 -2 roll 44 | atan 45 | dup 46 | 180 add 47 | 2 -1 roll 48 | -1 mul 49 | 270 add % stack now has the 5 args to "arc" 50 | 5 copy 5 copy 5 copy % copy the "arc" args 3 more times 51 | arc % do four sides of diamond 52 | 90 rotate arc 53 | 90 rotate arc 54 | 90 rotate arc 55 | closepath fill 56 | grestore 57 | -------------------------------------------------------------------------------- /fonts/source-sans/OFL.txt: -------------------------------------------------------------------------------- 1 | Copyright 2010, 2012, 2014 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name ‘Source’. 2 | 3 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 4 | This license is copied below, and is also available with a FAQ at: 5 | http://scripts.sil.org/OFL 6 | 7 | 8 | ----------------------------------------------------------- 9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 10 | ----------------------------------------------------------- 11 | 12 | PREAMBLE 13 | The goals of the Open Font License (OFL) are to stimulate worldwide 14 | development of collaborative font projects, to support the font creation 15 | efforts of academic and linguistic communities, and to provide a free and 16 | open framework in which fonts may be shared and improved in partnership 17 | with others. 18 | 19 | The OFL allows the licensed fonts to be used, studied, modified and 20 | redistributed freely as long as they are not sold by themselves. The 21 | fonts, including any derivative works, can be bundled, embedded, 22 | redistributed and/or sold with any software provided that any reserved 23 | names are not used by derivative works. The fonts and derivatives, 24 | however, cannot be released under any other type of license. The 25 | requirement for fonts to remain under this license does not apply 26 | to any document created using the fonts or their derivatives. 27 | 28 | DEFINITIONS 29 | "Font Software" refers to the set of files released by the Copyright 30 | Holder(s) under this license and clearly marked as such. This may 31 | include source files, build scripts and documentation. 32 | 33 | "Reserved Font Name" refers to any names specified as such after the 34 | copyright statement(s). 35 | 36 | "Original Version" refers to the collection of Font Software components as 37 | distributed by the Copyright Holder(s). 38 | 39 | "Modified Version" refers to any derivative made by adding to, deleting, 40 | or substituting -- in part or in whole -- any of the components of the 41 | Original Version, by changing formats or by porting the Font Software to a 42 | new environment. 43 | 44 | "Author" refers to any designer, engineer, programmer, technical 45 | writer or other person who contributed to the Font Software. 46 | 47 | PERMISSION & CONDITIONS 48 | Permission is hereby granted, free of charge, to any person obtaining 49 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 50 | redistribute, and sell modified and unmodified copies of the Font 51 | Software, subject to the following conditions: 52 | 53 | 1) Neither the Font Software nor any of its individual components, 54 | in Original or Modified Versions, may be sold by itself. 55 | 56 | 2) Original or Modified Versions of the Font Software may be bundled, 57 | redistributed and/or sold with any software, provided that each copy 58 | contains the above copyright notice and this license. These can be 59 | included either as stand-alone text files, human-readable headers or 60 | in the appropriate machine-readable metadata fields within text or 61 | binary files as long as those fields can be easily viewed by the user. 62 | 63 | 3) No Modified Version of the Font Software may use the Reserved Font 64 | Name(s) unless explicit written permission is granted by the corresponding 65 | Copyright Holder. This restriction only applies to the primary font name as 66 | presented to the users. 67 | 68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 69 | Software shall not be used to promote, endorse or advertise any 70 | Modified Version, except to acknowledge the contribution(s) of the 71 | Copyright Holder(s) and the Author(s) or with their explicit written 72 | permission. 73 | 74 | 5) The Font Software, modified or unmodified, in part or in whole, 75 | must be distributed entirely under this license, and must not be 76 | distributed under any other license. The requirement for fonts to 77 | remain under this license does not apply to any document created 78 | using the Font Software. 79 | 80 | TERMINATION 81 | This license becomes null and void if any of the above conditions are 82 | not met. 83 | 84 | DISCLAIMER 85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 93 | OTHER DEALINGS IN THE FONT SOFTWARE. 94 | -------------------------------------------------------------------------------- /issues.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Analysis of ggdist issues" 3 | author: "Matthew Kay" 4 | date: "2023-03-25" 5 | output: html_document 6 | --- 7 | 8 | ## Introduction 9 | 10 | This document does some simple data cleaning of issues exported from the `ggdist` Github repository for the paper, *ggdist: Visualizations of Distributions and Uncertainty in the Grammar of Graphics*. 11 | 12 | ## Setup 13 | 14 | These libraries are needed to build this file: 15 | 16 | ```{r setup} 17 | library(ggplot2) 18 | library(ggdist) 19 | library(jsonlite) 20 | library(dplyr) # for data manipulation 21 | library(rlang) 22 | library(readr) 23 | 24 | theme_set(theme_ggdist()) 25 | ``` 26 | 27 | ## Data 28 | 29 | The JSON file containing issues from the `ggdist` repository is `issues.json`, and 30 | was generated using this [Github CLI](https://cli.github.com/) command on March 25, 2023: 31 | 32 | ``` 33 | gh issue list --json assignees,author,body,closed,closedAt,comments,createdAt,labels,milestone,number,id,title,reactionGroups,state,updatedAt,url --limit 1000 --state all > issues.json 34 | ``` 35 | 36 | We will load it into R: 37 | 38 | ```{r load_json} 39 | issues = read_json("issues.json") 40 | ``` 41 | 42 | Let's turn this into a data frame at the top level so it's easier to work with: 43 | 44 | ```{r} 45 | issues_df = bind_rows(lapply(issues, \(issue) { 46 | # some fields need to be wrapped in a list so the output is a list column 47 | if (length(issue$comments) > 0) issue$comments = list(issue$comments) 48 | issue$labels = list(vapply(issue$labels, `[[`, "name", FUN.VALUE = character(1))) 49 | issue$assignees = list(vapply(issue$assignees, `[[`, "login", FUN.VALUE = character(1))) 50 | # for some fields, we only want the human-readable name, not metadata 51 | issue$author = issue$author$login 52 | issue$milestone = issue$milestone$title 53 | # encode zero-length entries as NA 54 | issue = lapply(issue, \(entry) if (length(entry) == 0) NA else entry) 55 | 56 | issue_df = as_tibble(issue) 57 | if (nrow(issue_df) != 1) { 58 | print(issue$number) 59 | stop() 60 | } 61 | # stopifnot(nrow(issue_df) == 1) 62 | issue_df 63 | })) |> 64 | mutate( 65 | closedAt = parse_datetime(closedAt), 66 | createdAt = parse_datetime(createdAt), 67 | updatedAt = parse_datetime(updatedAt), 68 | ) 69 | 70 | glimpse(issues_df) 71 | ``` 72 | 73 | Now, let's encode the remaining list-columns into strings so we can output something useful to CSV format: 74 | 75 | ```{r} 76 | issues_df |> 77 | mutate( 78 | assignees = vapply(assignees, paste0, collapse = ",", FUN.VALUE = character(1)), 79 | labels = vapply(labels, paste0, collapse = ",", FUN.VALUE = character(1)), 80 | comments = sapply(comments, \(comments) { 81 | paste0(lapply(comments, \(comment) 82 | paste0( 83 | "----------------------------\n", 84 | comment$author$login, ":\n\n", 85 | comment$body 86 | )), 87 | collapse = "\n\n") 88 | }) 89 | ) |> 90 | write_excel_csv("issues.csv") 91 | ``` 92 | 93 | After this export, I manually imported the above CSV into Excel and tagged some issues (the `from_users` and `notes` columns) and saved the output in `issues_tagged.xlsx` and `issues_tagged.csv`. Let's import that updated csv now: 94 | 95 | ```{r} 96 | issues_tagged = read_csv("issues_tagged.csv", 97 | col_type = cols( 98 | closed = col_logical(), 99 | number = col_double(), 100 | from_users = col_logical(), 101 | createdAt = col_datetime(), 102 | closedAt = col_datetime(), 103 | updatedAt = col_datetime(), 104 | .default = col_character() 105 | ) 106 | ) 107 | ``` 108 | 109 | ## Summaries 110 | 111 | Closed issues: 112 | 113 | ```{r} 114 | table(issues_tagged$closed) 115 | prop.table(table(issues_tagged$closed)) 116 | ``` 117 | Open issues are in these categories: 118 | 119 | ```{r} 120 | table(unique(issues_tagged[!issues_tagged$closed,]$notes)) 121 | ``` 122 | 123 | Number of authors (including me): 124 | 125 | ```{r} 126 | length(unique(issues_tagged$author)) 127 | ``` 128 | 129 | Number of issues created by users directly: 130 | 131 | ```{r} 132 | table(issues_tagged$author != "mjskay") 133 | prop.table(table(issues_tagged$author != "mjskay")) 134 | ``` 135 | 136 | 137 | Number of issues that stemmed from users, even if not created by them directly (e.g., because I created an issue based on a user's comment on another issue, or from a Twitter conversation with that user, etc): 138 | 139 | ```{r} 140 | table(issues_tagged$from_users) 141 | prop.table(table(issues_tagged$from_users)) 142 | ``` 143 | 144 | Breakdown of categories: first, all unique combinations: 145 | 146 | ```{r} 147 | table(issues_tagged$notes) 148 | ``` 149 | 150 | We don't really care about issues that are *purely* internal: e.g., refactoring, code cleanup, performance, etc. So we'll just lump those all together as "internal": 151 | 152 | ```{r} 153 | categories = issues_tagged$notes 154 | categories[categories %in% c("refactor", "cleanup", "internal", "performance")] = "internal" 155 | ``` 156 | 157 | Then we'll count categories (note: these are not unique per-issue): 158 | 159 | ```{r} 160 | cat_counts = sort(table(unlist(strsplit(categories, ",")))) 161 | cat_counts / nrow(issues_tagged) #can't use prop table because categories overlap 162 | ``` 163 | 164 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | # This file seems to originate from something called 'the ultimate 2 | # latex makefile' that different authors worked on. Find original 3 | # versions at: 4 | # http://tadek.pietraszek.org/blog/2006/03/24/the-ultimate-latex-makefile/ 5 | # (c) by Tadeusz Pietraszek 6 | # http://www.acoustics.hut.fi/u/mairas/UltimateLatexMakefile/ 7 | # (c) by Matti Airas 8 | # 9 | # This file has been assembled and adjusted by Steven Bergner, Nov 2005 10 | # - support for multiple sub-texfiles 11 | # - fixed '=' '#' problem in mingw/msys environment (see E variable) 12 | # - PS compilation uses VGTC recommended settings 13 | # - targets restructured to make PDF by default 14 | # 15 | # Call 'make dvi' for minimal compilation, to check for proper latex 16 | # syntax. This can be much faster than a full PDF generation when big 17 | # figures are involved. 18 | # 19 | # Call 'make pdf' for direct compilation to PDF using pdfTeX. Note that this 20 | # requires you to use .pdf files. pdfTeX can not use .ps or .eps graphics. 21 | # use epstopdf to convert such files to .pdf files. 22 | # 23 | #---------------------------------------------------------------------------- 24 | #adjust the following for your purpose 25 | 26 | #set the a .dvi name that corresponds to your main .tex file 27 | DVIFILES = template.dvi 28 | MAINTEXFILE = $(DVIFILES:.dvi=.tex) 29 | SUBTEXFILES = 30 | BIBFILES = template.bib 31 | 32 | #switch = to # when using ps2pdf in win32 (mingw/msys), i.e. uncomment 2nd line 33 | #E=\= 34 | E=\# 35 | 36 | #adjust paper size: letter/a4 37 | PAPERSIZE=letter 38 | PDFLATEXPAPERSIZE="-sPAPERSIZE$E$(PAPERSIZE)" 39 | DVIPSPAPERSIZE=-t $(PAPERSIZE) 40 | #uncomment the following two lines when using option tvcgpapersize 41 | #DVIPSPAPERSIZE=-T 7.875in,10.75in 42 | #PDFLATEXPAPERSIZE= 43 | 44 | #---------------------------------------------------------------------------- 45 | LATEX = latex 46 | BIBTEX = bibtex 47 | L2H = latex2html 48 | PDFLATEX = ps2pdf 49 | PDFTEX = pdflatex 50 | DVIPS = dvips 51 | 52 | RERUN = "(There were undefined references|Rerun to get (cross-references|the bars) right)" 53 | RERUNBIB = "No file.*\.bbl|Citation.*undefined" 54 | 55 | PSFILES = $(DVIFILES:.dvi=.ps) 56 | 57 | PDFFILES7 = $(DVIFILES:.dvi=.pdf7) 58 | PDFFILES8 = $(DVIFILES:.dvi=.pdf8) 59 | 60 | PDFTEXFILES = $(DVIFILES:.dvi=.pdftex) 61 | 62 | COPY = if test -r $*.toc; then cp $*.toc $*.toc.bak; fi 63 | #RM = /usr/bin/rm -f 64 | RM = rm -f 65 | 66 | all: msg gs8 67 | 68 | msg: 69 | @echo " This script defaults to GhostScript 8. If you are using GhostScipt 7 please type" 70 | @echo " make gs7 instead. If unsure type gs -v from the command line" 71 | @echo " To use pdflatex/pdftex, type make pdf" 72 | @echo "" 73 | 74 | 75 | pdf: clean pdftex 76 | 77 | gs7: clean dvi ps pdf7 78 | 79 | gs8: clean dvi ps pdf8 80 | 81 | dvi: $(DVIFILES) 82 | 83 | ps: $(PSFILES) 84 | 85 | pdf7: $(PDFFILES7) 86 | 87 | pdf8: $(PDFFILES8) 88 | 89 | pdftex: $(PDFTEXFILES) 90 | 91 | $(MAINTEXFILE) : $(SUBTEXFILES) $(BIBFILES) 92 | 93 | %.dvi: %.tex 94 | $(COPY);$(LATEX) $< 95 | egrep -c $(RERUNBIB) $*.log && ($(BIBTEX) $*;$(COPY);$(LATEX) $<) ; true 96 | egrep $(RERUN) $*.log && ($(COPY);$(LATEX) $<) ; true 97 | egrep $(RERUN) $*.log && ($(COPY);$(LATEX) $<) ; true 98 | if cmp -s $*.toc $*.toc.bak; then . ;else $(LATEX) $< ; fi 99 | $(RM) $*.toc.bak 100 | # Display relevant warnings 101 | egrep -i "(Reference|Citation).*undefined" $*.log ; true 102 | 103 | %.pdftex: %.tex 104 | echo "wir sind da" 105 | $(COPY);$(PDFTEX) $< 106 | egrep -c $(RERUNBIB) $*.log && ($(BIBTEX) $*;$(COPY);$(PDFTEX) $<) ; true 107 | egrep $(RERUN) $*.log && ($(COPY);$(PDFTEX) $<) ; true 108 | egrep $(RERUN) $*.log && ($(COPY);$(PDFTEX) $<) ; true 109 | if cmp -s $*.toc $*.toc.bak; then . ;else $(PDFTEX) $< ; fi 110 | $(RM) $*.toc.bak 111 | # Display relevant warnings 112 | egrep -i "(Reference|Citation).*undefined" $*.log ; true 113 | 114 | %.ps: %.dvi 115 | # dvips -T 7.875in,10.75in -Ppdf -G0 $< -o $@ #use tvcgpapersize 116 | # dvips -Ppdf -G0 $< -o $@ 117 | dvips $(DVIPSPAPERSIZE) -Pdownload35 -Ppdf -G0 $< -o $@ 118 | # dvips $< -o $@ 119 | 120 | 121 | %.pdf7: %.ps 122 | $(PDFLATEX) \ 123 | $(PDFLATEXPAPERSIZE) \ 124 | "-dMaxSubsetPct$E100" \ 125 | "-dCompatibilityLevel$E1.3" \ 126 | "-dSubsetFonts$Etrue" \ 127 | "-dEmbedAllFonts$Etrue" \ 128 | "-dAutoFilterColorImages$Efalse" \ 129 | "-dAutoFilterGrayImages$Efalse" \ 130 | "-dColorImageFilter$E/FlateEncode" \ 131 | "-dGrayImageFilter$E/FlateEncode" \ 132 | "-dMonoImageFilter$E/FlateEncode" \ 133 | $< template.pdf 134 | 135 | # $(PDFLATEX) $< 136 | 137 | %.pdf8: %.ps 138 | $(PDFLATEX) \ 139 | $(PDFLATEXPAPERSIZE) \ 140 | "-dPDFSETTINGS=/prepress" \ 141 | "-dCompatibilityLevel=1.3" \ 142 | "-dAutoFilterColorImages=false" \ 143 | "-dAutoFilterGrayImages=false" \ 144 | "-dColorImageFilter=/FlateEncode" \ 145 | "-dGrayImageFilter=/FlateEncode" \ 146 | "-dMonoImageFilter=/FlateEncode" \ 147 | "-dDownsampleGrayImages=false" \ 148 | "-dDownsampleColorImages=false" \ 149 | $< template.pdf 150 | # $(PDFLATEX) $< 151 | 152 | # cleans anything that can be re-generated automatically, plus emacs backups 153 | clean: 154 | rm -f *.aux *.log *.bbl *.blg *.brf *.cb *.ind *.idx *.ilg \ 155 | *.inx *.toc *.out $(DVIFILES) $(PSFILES) template.pdf *~ 156 | 157 | .PHONY : all pdf ps dvi clean $(MAINTEXFILE) 158 | -------------------------------------------------------------------------------- /BUILDING.md: -------------------------------------------------------------------------------- 1 | Created by Torsten Moeller, April 6 2004 2 | modified by Steven Bergner and Torsten Moeller, June 30 2006 3 | modified by James Peltier and Torsten Moeller, March 28, 2007 4 | modified by Bernhard Finkbeiner, July 5, 2010 5 | modified by Tobias Isenberg, January 2016 6 | modified by Filip Sadlo, March 2016 7 | modified by Tobias Isenberg, July 2016 8 | modified by Cagatay Turkay and Soumya Dutta, September 2019 9 | modified by Cody Dunne, January 2022 10 | 11 | This distribution provides a document class for formatting papers according to the specifications for submission to conferences sponsored by the IEEE Visualization & Graphics Technical Committee (VGTC). 12 | 13 | Conferences that use the 'journal' document option: 14 | - IEEE Visualization Conference (VIS) 15 | - IEEE Virtual Reality (VR) 16 | - IEEE International Symposium on Mixed and Augmented Reality (ISMAR) 17 | 18 | It contains 13 files/directories: 19 | 20 | README - this file 21 | diamondrule.eps - abstract and body separator 22 | diamondrule.pdf - its PDF version 23 | vgtc.cls - the VGTC class file, which should be placed, somewhere in the TeX search path (or in the local directory) 24 | template.tex - an example paper 25 | template.bib - a small bibliography file used by the example 26 | template.pdf - an example proper pdf output in default journal mode 27 | abbrv-doi*.bst - four different versions to generate the bibliography including DOI output, with and without hyperref support, with and without narrow rendering of DOIs 28 | makefile - makefile including bibtex compilation and proper PDF generation 29 | pictures/ - subdirectory with sample images, both in EPS and in direct pixel/vector format 30 | 31 | Usage 32 | ===== 33 | 34 | The template can be used with an established LaTeX environment by calling pdfLaTeX or LaTex. For online collaborative editing or without a local LaTeX installation, one option is to use https://www.overleaf.com/. For Windows-based LaTeX installations you can use, for example, the environment provided by http://www.texniccenter.org/ along with MikTeX (http://miktex.org/). For Unux-based installations, please use your favorite LaTeX distribution and editing environment or use the makefile following the instructions below. 35 | 36 | Use of the Makefile 37 | =================== 38 | 39 | Prior to "building" a paper please be sure to run 40 | 41 | make clean 42 | 43 | This will ensure that the paper is built cleanly each and every time. We suggest to run this command before each new compilation. 44 | 45 | To compile the example, run 46 | 47 | make 48 | 49 | or manually, if the makefile does not work for you 50 | 51 | latex template 52 | bibtex template 53 | latex template 54 | latex template 55 | 56 | If you run 'make' for the first time, a successful compilation will create a file called 'template.pdf'. Please make sure, that its layout is identical to the file 'template-journal.pdf' provided with this package. 57 | 58 | The included makefile also allows you to run each step of the process manually. Below are a list of available options that may be passed to make 59 | 60 | "make clean" 61 | removes all files that can be generated automatically. 62 | 63 | "make gs7" 64 | This will perform all functions to build a proper paper using GhostScript 7. 65 | 66 | "make gs8" 67 | This will perform all functions to build a proper paper using GhostScript 8. 68 | 69 | "make dvi" 70 | This will process the .tex file and produce a DVI output file. This 71 | step may process the .tex file several times to process all references 72 | and citations. 73 | 74 | "make ps" 75 | This will process the .tex file and the DVI output and convert it to a 76 | PostScript file. 77 | 78 | "make pdf" 79 | This will process the .tex file using pdfTeX/pdflatex to produce a PDF 80 | file directly (not using a DVI and PostScript file). 81 | Please make sure that all fonts are embedded. 82 | You can use pdffonts my_document.pdf to check if they are. 83 | It is standard in all modern latex distributions. 84 | If you use eps figures (e.g. R or gnuplot figures) which you convert to 85 | PDF using epstopdf, do the following: 86 | Use GL_OPTIONS, a global environment variable for ghostscript: 87 | export GS_OPTIONS="-dEmbedAllFonts=true -dPDFSETTINGS=/printer" 88 | # and run 89 | epstopdf myfile.eps 90 | 91 | See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=411651 for the 92 | origin of this solution. 93 | 94 | 95 | If you have problems with the makefile please notify us with the output of 96 | the errors produced when running make and we will work to figure out the 97 | resolution. 98 | 99 | 100 | To produce proper pdf output, please use: 101 | dvips -t letter -Pdownload35 -Ppdf -G0 template.dvi -o template.ps 102 | 103 | The "-Ppdf" and "-G0" flags should be specified in that order; reversing 104 | them does not work, and will result in unacceptable results. 105 | 106 | The following information is an exerpt from the ACM SIGGRAPH Conference / 107 | Symposium / Workshop Content Formatting Instructions which can be found 108 | here. 109 | 110 | http://www.siggraph.org/publications/instructions/author-instructions.pdf 111 | 112 | If you are using version 7.x of GhostScript, please use the following 113 | method of invoking ‘ps2pdf,’ in order to embed all typefaces and ensure 114 | that images are not downsampled or subsampled in the PDF creation process: 115 | 116 | ps2pdf -dCompatibilityLevel=1.3 -dMaxSubsetPct=100 \ 117 | -dSubsetFonts=true -dEmbedAllFonts=true \ 118 | -dAutoFilterColorImages=false -dAutoFilterGrayImages=false \ 119 | -dColorImageFilter=/FlateEncode -dGrayImageFilter=/FlateEncode \ 120 | -dMonoImageFilter=/FlateEncode template.ps template.pdf 121 | 122 | If you are using version 8.x of GhostScript, please use this method in 123 | place of the example above: 124 | 125 | ps2pdf -dPDFSETTINGS=/prepress -dCompatibilityLevel=1.3 \ 126 | -dAutoFilterColorImages=false -dAutoFilterGrayImages=false \ 127 | -dColorImageFilter=/FlateEncode -dGrayImageFilter=/FlateEncode \ 128 | -dMonoImageFilter=/FlateEncode template.ps template.pdf 129 | 130 | This has been incorporated into the makefile and should no longer be needed 131 | unless you are building the PDF file manually. 132 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # Creative Commons Attribution 4.0 International 2 | 3 | Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible. 4 | 5 | **Using Creative Commons Public Licenses** 6 | 7 | Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses. 8 | 9 | * __Considerations for licensors:__ Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. [More considerations for licensors](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors). 10 | 11 | * __Considerations for the public:__ By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. [More considerations for the public](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensees). 12 | 13 | ## Creative Commons Attribution 4.0 International Public License 14 | 15 | By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions. 16 | 17 | ### Section 1 – Definitions. 18 | 19 | a. __Adapted Material__ means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image. 20 | 21 | b. __Adapter's License__ means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License. 22 | 23 | c. __Copyright and Similar Rights__ means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. 24 | 25 | d. __Effective Technological Measures__ means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements. 26 | 27 | e. __Exceptions and Limitations__ means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material. 28 | 29 | f. __Licensed Material__ means the artistic or literary work, database, or other material to which the Licensor applied this Public License. 30 | 31 | g. __Licensed Rights__ means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license. 32 | 33 | h. __Licensor__ means the individual(s) or entity(ies) granting rights under this Public License. 34 | 35 | i. __Share__ means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them. 36 | 37 | j. __Sui Generis Database Rights__ means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world. 38 | 39 | k. __You__ means the individual or entity exercising the Licensed Rights under this Public License. __Your__ has a corresponding meaning. 40 | 41 | ### Section 2 – Scope. 42 | 43 | a. ___License grant.___ 44 | 45 | 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to: 46 | 47 | A. reproduce and Share the Licensed Material, in whole or in part; and 48 | 49 | B. produce, reproduce, and Share Adapted Material. 50 | 51 | 2. __Exceptions and Limitations.__ For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions. 52 | 53 | 3. __Term.__ The term of this Public License is specified in Section 6(a). 54 | 55 | 4. __Media and formats; technical modifications allowed.__ The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material. 56 | 57 | 5. __Downstream recipients.__ 58 | 59 | A. __Offer from the Licensor – Licensed Material.__ Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License. 60 | 61 | B. __No downstream restrictions.__ You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material. 62 | 63 | 6. __No endorsement.__ Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i). 64 | 65 | b. ___Other rights.___ 66 | 67 | 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise. 68 | 69 | 2. Patent and trademark rights are not licensed under this Public License. 70 | 71 | 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties. 72 | 73 | ### Section 3 – License Conditions. 74 | 75 | Your exercise of the Licensed Rights is expressly made subject to the following conditions. 76 | 77 | a. ___Attribution.___ 78 | 79 | 1. If You Share the Licensed Material (including in modified form), You must: 80 | 81 | A. retain the following if it is supplied by the Licensor with the Licensed Material: 82 | 83 | i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated); 84 | 85 | ii. a copyright notice; 86 | 87 | iii. a notice that refers to this Public License; 88 | 89 | iv. a notice that refers to the disclaimer of warranties; 90 | 91 | v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; 92 | 93 | B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and 94 | 95 | C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License. 96 | 97 | 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information. 98 | 99 | 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable. 100 | 101 | 4. If You Share Adapted Material You produce, the Adapter's License You apply must not prevent recipients of the Adapted Material from complying with this Public License. 102 | 103 | ### Section 4 – Sui Generis Database Rights. 104 | 105 | Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material: 106 | 107 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database; 108 | 109 | b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and 110 | 111 | c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database. 112 | 113 | For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights. 114 | 115 | ### Section 5 – Disclaimer of Warranties and Limitation of Liability. 116 | 117 | a. __Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.__ 118 | 119 | b. __To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.__ 120 | 121 | c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability. 122 | 123 | ### Section 6 – Term and Termination. 124 | 125 | a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically. 126 | 127 | b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates: 128 | 129 | 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or 130 | 131 | 2. upon express reinstatement by the Licensor. 132 | 133 | For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License. 134 | 135 | c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License. 136 | 137 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. 138 | 139 | ### Section 7 – Other Terms and Conditions. 140 | 141 | a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed. 142 | 143 | b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License. 144 | 145 | ### Section 8 – Interpretation. 146 | 147 | a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License. 148 | 149 | b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions. 150 | 151 | c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor. 152 | 153 | d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority. 154 | 155 | > Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at [creativecommons.org/policies](http://creativecommons.org/policies), Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses. 156 | > 157 | > Creative Commons may be contacted at creativecommons.org 158 | -------------------------------------------------------------------------------- /template.bib: -------------------------------------------------------------------------------- 1 | @article{correll2014error, 2 | author={Correll, Michael and Gleicher, Michael}, 3 | journal={IEEE Transactions on Visualization and Computer Graphics}, 4 | title={Error Bars Considered Harmful: Exploring Alternate Encodings for Mean and Error}, 5 | year={2014}, 6 | volume={20}, 7 | number={12}, 8 | pages={2142--2151}, 9 | doi={10.1109/TVCG.2014.2346298} 10 | } 11 | 12 | @article{helske2021can, 13 | author={Helske, Jouni and Helske, Satu and Cooper, Matthew and Ynnerman, Anders and Besançon, Lonni}, 14 | journal={IEEE Transactions on Visualization and Computer Graphics}, 15 | title={Can Visualization Alleviate Dichotomous Thinking? {E}ffects of Visual Representations on the Cliff Effect}, 16 | year={2021}, 17 | volume={27}, 18 | number={8}, 19 | pages={3397-3409}, 20 | doi={10.1109/TVCG.2021.3073466} 21 | } 22 | 23 | 24 | @article{barrowman2003raindrop, 25 | title={Raindrop plots: a new way to display collections of likelihoods and distributions}, 26 | author={Barrowman, Nicholas J and Myers, Ransom A}, 27 | journal={The American Statistician}, 28 | volume={57}, 29 | number={4}, 30 | pages={268--274}, 31 | year={2003}, 32 | publisher={Taylor \& Francis}, 33 | doi={10.1198/0003130032369} 34 | } 35 | 36 | @article{haber1982perceptual, 37 | title = {Perceptual Components of Computer Displays}, 38 | author={Haber, Ralph Norman and Wilkinson, Leland}, 39 | journal={IEEE Computer Graphics and Applications}, 40 | year = {1982}, 41 | volume = {2}, 42 | number = {03}, 43 | issn = {1558-1756}, 44 | pages = {23--35}, 45 | doi = {10.1109/MCG.1982.1674217}, 46 | publisher = {IEEE Computer Society}, 47 | address = {Los Alamitos, CA, USA}, 48 | month = {March} 49 | } 50 | 51 | @article{newman2012bar, 52 | title={Bar graphs depicting averages are perceptually misinterpreted: The within-the-bar bias}, 53 | author={Newman, George E and Scholl, Brian J}, 54 | journal={Psychonomic Bulletin \& Review}, 55 | volume={19}, 56 | pages={601--607}, 57 | year={2012}, 58 | publisher={Springer}, 59 | doi={10.3758/s13423-012-0247-5} 60 | } 61 | 62 | @article{kruschke2018rejecting, 63 | title={Rejecting or accepting parameter values in Bayesian estimation}, 64 | author={Kruschke, John K}, 65 | journal={Advances in Methods and Practices in Psychological Science}, 66 | volume={1}, 67 | number={2}, 68 | pages={270--280}, 69 | year={2018}, 70 | publisher={Sage Publications Sage CA: Los Angeles, CA}, 71 | doi={10.1177/2515245918771304} 72 | } 73 | 74 | @article{wickham2011ggplot2, 75 | title={ggplot2}, 76 | author={Wickham, Hadley}, 77 | journal={Wiley Interdisciplinary Reviews: Computational Statistics}, 78 | volume={3}, 79 | number={2}, 80 | pages={180--185}, 81 | year={2011}, 82 | publisher={Wiley Online Library}, 83 | doi = {https://doi.org/10.1002/wics.147} 84 | } 85 | 86 | @article{wickham2010layered, 87 | title={A Layered Grammar of Graphics}, 88 | author={Wickham, Hadley}, 89 | journal={Journal of Computational and Graphical Statistics}, 90 | volume={19}, 91 | number={1}, 92 | pages={3--28}, 93 | year={2010}, 94 | publisher={Taylor \& Francis}, 95 | doi={10.1198/jcgs.2009.07098} 96 | } 97 | 98 | @book{wilkinson2012grammar, 99 | title={The Grammar of Graphics}, 100 | author={Wilkinson, Leland}, 101 | isbn={9780387245447}, 102 | series={Statistics and Computing}, 103 | year={2005}, 104 | publisher={Springer}, 105 | address={New York, NY, USA} 106 | } 107 | 108 | 109 | @article{satyanarayan2016vega, 110 | author={Satyanarayan, Arvind and Moritz, Dominik and Wongsuphasawat, Kanit and Heer, Jeffrey}, 111 | journal={IEEE Transactions on Visualization and Computer Graphics}, 112 | title={Vega-Lite: A Grammar of Interactive Graphics}, 113 | year={2017}, 114 | volume={23}, 115 | number={1}, 116 | pages={341-350}, 117 | doi={10.1109/TVCG.2016.2599030} 118 | } 119 | 120 | @inproceedings{kay2016ish, 121 | author = {Kay, Matthew and Kola, Tara and Hullman, Jessica R. and Munson, Sean A.}, 122 | title = {When (Ish) is My Bus? User-Centered Visualizations of Uncertainty in Everyday, Mobile Predictive Systems}, 123 | year = {2016}, 124 | isbn = {9781450333627}, 125 | publisher = {Association for Computing Machinery}, 126 | address = {New York, NY, USA}, 127 | url = {https://doi.org/10.1145/2858036.2858558}, 128 | doi = {10.1145/2858036.2858558}, 129 | booktitle = {Proceedings of the 2016 CHI Conference on Human Factors in Computing Systems}, 130 | pages = {5092–5103}, 131 | numpages = {12}, 132 | location = {San Jose, California, USA}, 133 | series = {CHI '16} 134 | } 135 | 136 | @inproceedings{fernandes2018uncertainty, 137 | author = {Fernandes, Michael and Walls, Logan and Munson, Sean and Hullman, Jessica and Kay, Matthew}, 138 | title = {Uncertainty Displays Using Quantile Dotplots or {CDFs} Improve Transit Decision-Making}, 139 | year = {2018}, 140 | isbn = {9781450356206}, 141 | publisher = {Association for Computing Machinery}, 142 | address = {New York, NY, USA}, 143 | url = {https://doi.org/10.1145/3173574.3173718}, 144 | doi = {10.1145/3173574.3173718}, 145 | booktitle = {Proceedings of the 2018 CHI Conference on Human Factors in Computing Systems}, 146 | pages = {144:1–144:12}, 147 | numpages = {12}, 148 | keywords = {cumulative distribution plots, mobileinterfaces, dotplots, uncertainty visualization, transit predictions}, 149 | location = {Montreal QC, Canada}, 150 | series = {CHI '18} 151 | } 152 | 153 | @article{bowman2019graphics, 154 | author = {Bowman, Adrian W.}, 155 | title = {Graphics for Uncertainty}, 156 | journal = {Journal of the Royal Statistical Society Series A: Statistics in Society}, 157 | volume = {182}, 158 | number = {2}, 159 | pages = {403--418}, 160 | year = {2019}, 161 | month = {01}, 162 | issn = {0964-1998}, 163 | doi = {10.1111/rssa.12379} 164 | } 165 | 166 | @article{jackson2008displaying, 167 | title={Displaying uncertainty with shading}, 168 | author={Jackson, Christopher H}, 169 | journal={The American Statistician}, 170 | volume={62}, 171 | number={4}, 172 | pages={340--347}, 173 | year={2008}, 174 | publisher={Taylor \& Francis}, 175 | doi = {10.1198/000313008X370843} 176 | } 177 | 178 | @article{spiegelhalter1999surgical, 179 | title={Surgical audit: statistical lessons from {N}ightingale and {C}odman}, 180 | author={Spiegelhalter, David J}, 181 | journal={Journal of the Royal Statistical Society: Series A (Statistics in Society)}, 182 | volume={162}, 183 | number={1}, 184 | pages={45--58}, 185 | year={1999}, 186 | publisher={Wiley Online Library}, 187 | doi={https://doi.org/10.1111/1467-985X.00120} 188 | } 189 | 190 | @inproceedings{pu2020probabilistic, 191 | author = {Pu, Xiaoying and Kay, Matthew}, 192 | title = {A Probabilistic Grammar of Graphics}, 193 | year = {2020}, 194 | isbn = {9781450367080}, 195 | publisher = {Association for Computing Machinery}, 196 | address = {New York, NY, USA}, 197 | url = {https://doi.org/10.1145/3313831.3376466}, 198 | doi = {10.1145/3313831.3376466}, 199 | booktitle = {Proceedings of the 2020 CHI Conference on Human Factors in Computing Systems}, 200 | pages = {339:1–339:13}, 201 | numpages = {13}, 202 | keywords = {grammar of graphics, uncertainty visualization}, 203 | location = {Honolulu, HI, USA}, 204 | series = {CHI '20} 205 | } 206 | 207 | @inproceedings{pu2023inpractice, 208 | author = {Pu, Xiaoying and Kay, Matthew}, 209 | title = {How Data Analysts Use a Visualization Grammar in Practice}, 210 | year = {2023}, 211 | isbn = {9781450394215}, 212 | publisher = {Association for Computing Machinery}, 213 | address = {New York, NY, USA}, 214 | url = {https://doi.org/10.1145/3544548.3580837}, 215 | doi = {10.1145/3544548.3580837}, 216 | abstract = {Visualization grammars, often based on the Grammar of Graphics (GoG), have much potential for augmenting data analysis in a programming environment. However, we do not know how analysts conceptualize grammar abstractions, or how a visualization grammar works with data analysis in practice. Therefore, we qualitatively analyzed how experienced analysts (N = 6) from TidyTuesday, a social data project, wrangled and visualized data using GoG-based ggplot2 without given tasks in R Markdown. Though participants’ analysis and customization needs could mismatch with GoG component design, their analysis processes aligned with the goal of GoG to expedite visualization iteration. We also found a feedback loop and tight coupling between visualization and data transformation code, explaining both participants’ productivity and their errors. From these results, we discuss how future visualization grammars can become more practical for analysts and how visualization grammar and analysis tools can better integrate within a programming (i.e., computational notebook) environment.}, 217 | booktitle = {Proceedings of the 2023 CHI Conference on Human Factors in Computing Systems}, 218 | pages = {840:1-840:22}, 219 | keywords = {Visualization grammar, computational notebook, TidyTuesday}, 220 | location = {Hamburg, Germany}, 221 | series = {CHI '23} 222 | } 223 | 224 | @article{wickham2011product, 225 | author={Wickham, Hadley and Hofmann, Heike}, 226 | journal={IEEE Transactions on Visualization and Computer Graphics}, 227 | title={Product Plots}, 228 | year={2011}, 229 | volume={17}, 230 | number={12}, 231 | pages={2223-2230}, 232 | doi={10.1109/TVCG.2011.227} 233 | } 234 | 235 | @article{ancker2006design, 236 | title={Design features of graphs in health risk communication: a systematic review}, 237 | author={Ancker, Jessica S and Senathirajah, Yalini and Kukafka, Rita and Starren, Justin B}, 238 | journal={Journal of the American Medical Informatics Association}, 239 | volume={13}, 240 | number={6}, 241 | pages={608--618}, 242 | year={2006}, 243 | publisher={BMJ Group BMA House, Tavistock Square, London, WC1H 9JR}, 244 | doi={10.1197/jamia.M2115} 245 | } 246 | 247 | @article{wilkinson1999dot, 248 | title={Dot plots}, 249 | author={Wilkinson, Leland}, 250 | journal={The American Statistician}, 251 | volume={53}, 252 | number={3}, 253 | pages={276--281}, 254 | year={1999}, 255 | publisher={Taylor \& Francis}, 256 | doi={10.1080/00031305.1999.10474474} 257 | } 258 | 259 | @article{xie2013confidence, 260 | title={Confidence distribution, the frequentist distribution estimator of a parameter: A review}, 261 | author={Xie, Min-ge and Singh, Kesar}, 262 | journal={International Statistical Review}, 263 | volume={81}, 264 | number={1}, 265 | pages={3--39}, 266 | year={2013}, 267 | publisher={Wiley Online Library}, 268 | doi={https://doi.org/10.1111/insr.12000} 269 | } 270 | 271 | @misc{kay2018stannames, 272 | title={Unifying names of output columns in bayesplot / tidybayes / etc}, 273 | url={https://discourse.mc-stan.org/t/unifying-names-of-output-columns-in-bayesplot-tidybayes-etc/4577}, 274 | howpublished={\textit{The Stan Forums}. \href{https://discourse.mc-stan.org/t/unifying-names-of-output-columns-in-bayesplot-tidybayes-etc/4577}{https://discourse.mc-stan.org/t/unifying-names-of-output-columns-in-bayesplot-tidybayes-etc/4577}}, 275 | author={Kay, Matthew}, 276 | year={2018}, 277 | month={Jun} 278 | } 279 | 280 | @misc{tidyverse2020dotprefix, 281 | title={Dot prefix}, 282 | author={{Tidyverse Team}}, 283 | url={https://design.tidyverse.org/dots-prefix.html}, 284 | howpublished={\textit{Tidyverse Design Guide}. \href{https://design.tidyverse.org/dots-prefix.html}{https://design.tidyverse.org/dots-prefix.html}}, 285 | year={2020} 286 | } 287 | 288 | @article{hullman2015hypothetical, 289 | doi = {10.1371/journal.pone.0142444}, 290 | author = {Hullman, Jessica and Resnick, Paul and Adar, Eytan}, 291 | journal = {PLOS ONE}, 292 | publisher = {Public Library of Science}, 293 | title = {Hypothetical Outcome Plots Outperform Error Bars and Violin Plots for Inferences about Reliability of Variable Ordering}, 294 | year = {2015}, 295 | volume = {10}, 296 | url = {https://doi.org/10.1371/journal.pone.0142444}, 297 | pages = {e0142444}, 298 | number = {11} 299 | } 300 | 301 | @article{cox2013visualizing, 302 | title={Visualizing uncertainty in predicted hurricane tracks}, 303 | author={Cox, Jonathan and House, Donald and Lindell, Michael}, 304 | journal={International Journal for Uncertainty Quantification}, 305 | volume={3}, 306 | number={2}, 307 | year={2013}, 308 | pages = {143--156}, 309 | publisher={Begel House Inc.}, 310 | doi={10.1615/Int.J.UncertaintyQuantification.2012003966} 311 | } 312 | 313 | @article{liu2018visualizing, 314 | author={Liu, Le and Padilla, Lace and Creem-Regehr, Sarah H. and House, Donald H.}, 315 | journal={IEEE Transactions on Visualization and Computer Graphics}, 316 | title={Visualizing Uncertain Tropical Cyclone Predictions using Representative Samples from Ensembles of Forecast Tracks}, 317 | year={2019}, 318 | volume={25}, 319 | number={1}, 320 | pages={882-891}, 321 | doi={10.1109/TVCG.2018.2865193} 322 | } 323 | 324 | @article{kale2018hypothetical, 325 | title={Hypothetical outcome plots help untrained observers judge trends in ambiguous data}, 326 | author={Kale, Alex and Nguyen, Francis and Kay, Matthew and Hullman, Jessica}, 327 | journal={IEEE Transactions on Visualization and Computer Graphics}, 328 | year={2019}, 329 | volume={25}, 330 | number={1}, 331 | pages={892-902}, 332 | doi={10.1109/TVCG.2018.2864909} 333 | } 334 | 335 | @article{satyanarayan2019critical, 336 | author={Satyanarayan, Arvind and Lee, Bongshin and Ren, Donghao and Heer, Jeffrey and Stasko, John and Thompson, John and Brehmer, Matthew and Liu, Zhicheng}, 337 | journal={IEEE Transactions on Visualization and Computer Graphics}, 338 | title={Critical Reflections on Visualization Authoring Systems}, 339 | year={2020}, 340 | volume={26}, 341 | number={1}, 342 | pages={461-471}, 343 | doi={10.1109/TVCG.2019.2934281} 344 | } 345 | 346 | @article{hyndman1996computing, 347 | author={Hyndman, Rob J}, 348 | title = {Computing and Graphing Highest Density Regions}, 349 | journal = {The American Statistician}, 350 | volume = {50}, 351 | number = {2}, 352 | pages = {120-126}, 353 | year = {1996}, 354 | publisher = {Taylor \& Francis}, 355 | doi = {10.1080/00031305.1996.10474359}, 356 | } 357 | 358 | @article{liu2015spi, 359 | title={Simulation-efficient shortest probability intervals}, 360 | author={Liu, Ying and Gelman, Andrew and Zheng, Tian}, 361 | journal={Statistics and Computing}, 362 | volume={25}, 363 | pages={809--819}, 364 | year={2015}, 365 | publisher={Springer}, 366 | doi={10.1007/s11222-015-9563-8} 367 | } 368 | 369 | @article{hadley2014tidy, 370 | title={Tidy Data}, 371 | volume={59}, 372 | url={https://www.jstatsoft.org/index.php/jss/article/view/v059i10}, 373 | doi={10.18637/jss.v059.i10}, 374 | number={10}, 375 | journal={Journal of Statistical Software}, 376 | author={Wickham, Hadley}, 377 | year={2014}, 378 | pages={10:1–10:23} 379 | } 380 | 381 | 382 | @book{codd1990relational, 383 | author={Codd, Edgar F}, 384 | title = {The Relational Model for Database Management: Version 2}, 385 | year = {1990}, 386 | isbn = {0201141922}, 387 | publisher = {Addison-Wesley Longman Publishing Co., Inc.}, 388 | address = {USA} 389 | } 390 | 391 | 392 | 393 | @article{burkner2018brms, 394 | author = {Paul-Christian Bürkner}, 395 | title = {{Advanced Bayesian Multilevel Modeling with the R Package 396 | brms}}, 397 | year = {2018}, 398 | journal = {{The R Journal}}, 399 | doi = {10.32614/RJ-2018-017}, 400 | url = {https://doi.org/10.32614/RJ-2018-017}, 401 | pages = {395--411}, 402 | volume = {10}, 403 | number = {1} 404 | } 405 | 406 | @misc{burkner2022posterior, 407 | title={posterior: Tools for working with posterior distributions}, 408 | author={B{\"u}rkner, Paul-Christian and Gabry, Jonah and Kay, Matthew and Vehtari, Aki}, 409 | howpublished={\textit{R package version 1.4.1}. \href{https://CRAN.R-project.org/package=posterior}{https://CRAN.R-project.org/package=posterior}}, 410 | year={2022} 411 | } 412 | 413 | @misc{henry2023rlang, 414 | title = {rlang: Functions for Base Types and Core {R} and {Tidyverse} Features}, 415 | author = {Lionel Henry and Hadley Wickham}, 416 | year = {2023}, 417 | howpublished={\textit{R package version 1.1.1}. \href{https://CRAN.R-project.org/package=rlang}{https://CRAN.R-project.org/package=rlang}}, 418 | } 419 | 420 | @book{wickham2019advanced, 421 | title={Advanced R, Second Edition}, 422 | author={Wickham, Hadley}, 423 | year={2019}, 424 | howpublished={\href{https://adv-r.hadley.nz/}{https://adv-r.hadley.nz/}}, 425 | publisher={CRC Press}, 426 | isbn={9781351201292}, 427 | note={\href{https://adv-r.hadley.nz/}{https://adv-r.hadley.nz/}} 428 | } 429 | 430 | @article{amrhein2022discuss, 431 | title={Discuss practical importance of results based on interval estimates and p-value functions, not only on point estimates and null p-values}, 432 | author={Amrhein, Valentin and Greenland, Sander}, 433 | journal={Journal of Information Technology}, 434 | volume={37}, 435 | number={3}, 436 | pages={316--320}, 437 | year={2022}, 438 | publisher={SAGE Publications Sage UK: London, England}, 439 | doi={10.1177/02683962221105904} 440 | } 441 | 442 | @article{huron2013sediment, 443 | author={Huron, Samuel and Vuillemot, Romain and Fekete, Jean-Daniel}, 444 | journal={IEEE Transactions on Visualization and Computer Graphics}, 445 | title={Visual Sedimentation}, 446 | year={2013}, 447 | volume={19}, 448 | number={12}, 449 | pages={2446-2455}, 450 | doi={10.1109/TVCG.2013.227} 451 | } 452 | 453 | @inproceedings{haroz2015isotype, 454 | author = {Haroz, Steve and Kosara, Robert and Franconeri, Steven L.}, 455 | title = {{ISOTYPE} Visualization: Working Memory, Performance, and Engagement with Pictographs}, 456 | year = {2015}, 457 | isbn = {9781450331456}, 458 | publisher = {Association for Computing Machinery}, 459 | address = {New York, NY, USA}, 460 | url = {https://doi.org/10.1145/2702123.2702275}, 461 | doi = {10.1145/2702123.2702275}, 462 | booktitle = {Proceedings of the 33rd Annual ACM Conference on Human Factors in Computing Systems}, 463 | pages = {1191–1200}, 464 | numpages = {10}, 465 | keywords = {pictograph, visualization, embellishment, working memory, psychophysics, user performance, isotype}, 466 | location = {Seoul, Republic of Korea}, 467 | series = {CHI '15} 468 | } 469 | 470 | @misc{cairo2018weepeople, 471 | title={Our Font Is Made of People}, 472 | url={https://source.opennews.org/articles/our-font-made-people/}, 473 | howpublished={\textit{OpenNews -- Source}. \href{https://source.opennews.org/articles/our-font-made-people/}{https://source.opennews.org/articles/our-font-made-people/}}, 474 | author={Cairo, Alberto and Klein, Scott}, 475 | year={2018}, 476 | month={Feb} 477 | } 478 | 479 | @article{munzner2009nested, 480 | author={Munzner, Tamara}, 481 | journal={IEEE Transactions on Visualization and Computer Graphics}, 482 | title={A Nested Model for Visualization Design and Validation}, 483 | year={2009}, 484 | volume={15}, 485 | number={6}, 486 | pages={921-928}, 487 | doi={10.1109/TVCG.2009.111} 488 | } 489 | 490 | @article{bostock2011d3, 491 | author={Bostock, Michael and Ogievetsky, Vadim and Heer, Jeffrey}, 492 | journal={IEEE Transactions on Visualization and Computer Graphics}, 493 | title={D$^3$ data-driven documents}, 494 | year={2011}, 495 | volume={17}, 496 | number={12}, 497 | pages={2301--2309}, 498 | doi={10.1109/TVCG.2011.185} 499 | } 500 | 501 | @misc{csardi2019cranlogs, 502 | title = {cranlogs: Download Logs from the {RStudio} {CRAN} Mirror}, 503 | author = {Gábor Csárdi}, 504 | year = {2019}, 505 | howpublished = {\textit{R package version 2.1.1}. \href{https://CRAN.R-project.org/package=cranlogs}{https://CRAN.R-project.org/package=cranlogs}}, 506 | url = {https://CRAN.R-project.org/package=cranlogs}, 507 | } 508 | 509 | @misc{gilbert2016numderiv, 510 | title = {numDeriv: Accurate Numerical Derivatives}, 511 | author = {Paul Gilbert and Ravi Varadhan}, 512 | year = {2019}, 513 | howpublished = {\textit{R package version 2016.8-1.1}. \href{https://CRAN.R-project.org/package=numDeriv}{https://CRAN.R-project.org/package=numDeriv}}, 514 | url = {https://CRAN.R-project.org/package=numDeriv}, 515 | } 516 | 517 | @article{sun2011functional, 518 | title={Functional boxplots}, 519 | author={Sun, Ying and Genton, Marc G}, 520 | journal={Journal of Computational and Graphical Statistics}, 521 | volume={20}, 522 | number={2}, 523 | pages={316--334}, 524 | year={2011}, 525 | publisher={Taylor \& Francis}, 526 | doi={10.1198/jcgs.2011.09224} 527 | } 528 | 529 | @article{mirzargar2014curve, 530 | author={Mirzargar, Mahsa and Whitaker, Ross T. and Kirby, Robert M.}, 531 | journal={IEEE Transactions on Visualization and Computer Graphics}, 532 | title={Curve Boxplot: Generalization of Boxplot for Ensembles of Curves}, 533 | year={2014}, 534 | volume={20}, 535 | number={12}, 536 | pages={2654-2663}, 537 | doi={10.1109/TVCG.2014.2346455} 538 | } 539 | 540 | @article{juul2021fixed, 541 | title={Fixed-time descriptive statistics underestimate extremes of epidemic curve ensembles}, 542 | author={Juul, Jonas L and Gr{\ae}sb{\o}ll, Kaare and Christiansen, Lasse Engbo and Lehmann, Sune}, 543 | journal={Nature Physics}, 544 | volume={17}, 545 | number={1}, 546 | pages={5--8}, 547 | year={2021}, 548 | publisher={Nature Publishing Group UK London}, 549 | doi={10.1038/s41567-020-01121-y} 550 | } 551 | 552 | @misc{oharawild2022distributional, 553 | title = {distributional: Vectorised Probability Distributions}, 554 | author = {Mitchell O'Hara-Wild and Matthew Kay and Alex Hayes}, 555 | year = {2022}, 556 | howpublished = {\textit{R package version 0.3.1}. \href{https://CRAN.R-project.org/package=distributional}{https://CRAN.R-project.org/package=distributional}}, 557 | url = {https://CRAN.R-project.org/package=distributional}, 558 | } 559 | 560 | @article{allen2019raincloud, 561 | title={Raincloud plots: a multi-platform tool for robust data visualization}, 562 | author={Allen, Micah and Poggiali, Davide and Whitaker, Kirstie and Marshall, Tom Rhys and Kievit, Rogier A}, 563 | journal={Wellcome open research}, 564 | volume={4}, 565 | number={63}, 566 | year={2019}, 567 | publisher={The Wellcome Trust}, 568 | doi={10.12688/wellcomeopenres.15191.1} 569 | } 570 | 571 | @article{henderson1981building, 572 | ISSN = {0006341X, 15410420}, 573 | URL = {http://www.jstor.org/stable/2530428}, 574 | author = {Harold V. Henderson and Paul F. Velleman}, 575 | journal = {Biometrics}, 576 | number = {2}, 577 | pages = {391--411}, 578 | publisher = {Wiley, International Biometric Society}, 579 | title = {Building Multiple Regression Models Interactively}, 580 | urldate = {2023-08-08}, 581 | volume = {37}, 582 | year = {1981}, 583 | doi = {10.2307/2530428} 584 | } 585 | 586 | 587 | 588 | @Article{burkner2017brms, 589 | title = {{brms}: An {R} Package for {Bayesian} Multilevel Models Using {Stan}}, 590 | author = {Paul-Christian Bürkner}, 591 | journal = {Journal of Statistical Software}, 592 | year = {2017}, 593 | volume = {80}, 594 | number = {1}, 595 | pages = {1:1-1:28}, 596 | doi = {10.18637/jss.v080.i01}, 597 | encoding = {UTF-8}, 598 | } 599 | 600 | @misc{r2022, 601 | title = {{R}: A Language and Environment for Statistical Computing}, 602 | author = {{R Core Team}}, 603 | organization = {R Foundation for Statistical Computing}, 604 | address = {Vienna, Austria}, 605 | year = {2022}, 606 | howpublished = {\textit{R Foundation for Statistical Computing}, Vienna, Austria. \href{https://www.R-project.org/}{https://www.R-project.org/}}, 607 | } 608 | 609 | @article{hornik2012cran, 610 | author = {Hornik, Kurt}, 611 | title = {The Comprehensive {R} Archive Network}, 612 | journal = {Wiley Interdisciplinary Reviews: Computational Statistics}, 613 | volume = {4}, 614 | number = {4}, 615 | pages = {394-398}, 616 | doi = {https://doi.org/10.1002/wics.1212}, 617 | url = {https://wires.onlinelibrary.wiley.com/doi/abs/10.1002/wics.1212}, 618 | eprint = {https://wires.onlinelibrary.wiley.com/doi/pdf/10.1002/wics.1212}, 619 | year = {2012} 620 | } 621 | 622 | 623 | 624 | @misc{kay2023ggdist, 625 | title = {{ggdist}: Visualizations of Distributions and Uncertainty}, 626 | author = {Matthew Kay}, 627 | year = {2023}, 628 | howpublished = {\textit{R package version 3.3.0}. \href{https://CRAN.R-project.org/package=ggdist}{https://CRAN.R-project.org/package=ggdist}}, 629 | url = {https://mjskay.github.io/ggdist/}, 630 | doi = {10.5281/zenodo.3879620}, 631 | } 632 | 633 | @misc{kay2023tidybayes, 634 | title = {{tidybayes}: Tidy Data and Geoms for {Bayesian} Models}, 635 | author = {Matthew Kay}, 636 | year = {2023}, 637 | howpublished = {\textit{R package version 3.0.4}. \href{https://CRAN.R-project.org/package=tidybayes}{https://CRAN.R-project.org/package=tidybayes}}, 638 | url = {http://mjskay.github.io/tidybayes/}, 639 | doi = {10.5281/zenodo.1308151}, 640 | } 641 | 642 | 643 | @misc{murrell2022vectorised, 644 | title={Vectorised Pattern Fills in {R} Graphics}, 645 | author={Murrell, Paul}, 646 | year={2022}, 647 | month={May}, 648 | howpublished = {\href{https://www.stat.auckland.ac.nz/~paul/Reports/GraphicsEngine/vecpat/vecpat.html}{https://www.stat.auckland.ac.nz/~paul/Reports/GraphicsEngine/vecpat/vecpat.html}}, 649 | url = {https://www.stat.auckland.ac.nz/~paul/Reports/GraphicsEngine/vecpat/vecpat.html}, 650 | doi = {10.17608/k6.auckland.19945787} 651 | } 652 | -------------------------------------------------------------------------------- /figures.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Figures for the ggdist paper" 3 | author: "Matthew Kay" 4 | date: "2023-03-11" 5 | output: 6 | html_document: 7 | theme: lumen 8 | toc: true 9 | self_contained: true 10 | --- 11 | 12 | ## Introduction 13 | 14 | This document generates the various figures for the paper, *ggdist: Visualizations of Distributions and Uncertainty in the Grammar of Graphics*. 15 | 16 | ## Setup 17 | 18 | These libraries are needed to build this file: 19 | 20 | ```{r setup, message = FALSE, warning = FALSE} 21 | library(ggplot2) 22 | library(ggdist) # obviously 23 | library(distributional) # for dist_... 24 | library(dplyr) # for data manipulation 25 | library(sysfonts) # for using custom fonts 26 | library(brms) # for brm() (model-fitting) 27 | library(posterior) # rvar 28 | library(patchwork) 29 | library(ggtext) # element_textbox_simple 30 | library(ragg) # agg_png 31 | library(colorspace) 32 | library(broom) # augment 33 | library(tidyr) 34 | library(palmerpenguins) 35 | ``` 36 | 37 | And this ggplot theme, based on `theme_ggdist()`, using the Source Sans Pro font (in the `fonts/` folder): 38 | 39 | ```{r} 40 | knitr::opts_chunk$set(dev = "ragg_png", fig.ext = "png") 41 | 42 | font_add( 43 | family = "Source Sans Pro", 44 | regular = "fonts/source-sans/SourceSansPro-Regular.ttf", 45 | bold = "fonts/source-sans/SourceSansPro-Bold.ttf", 46 | italic = "fonts/source-sans/SourceSansPro-Italic.ttf", 47 | bolditalic = "fonts/source-sans/SourceSansPro-BoldItalic.ttf", 48 | ) 49 | 50 | theme_set( 51 | theme_light(base_family = "Source Sans Pro") + theme( 52 | axis.line.x = element_line(color = "gray70", linewidth = rel(0.5)), 53 | axis.line.y = element_line(color = "gray70", linewidth = rel(0.5)), 54 | axis.title.x = element_text(margin = margin(t = 7)), 55 | axis.title.y = element_text(margin = margin(r = 7)), 56 | panel.grid.major = element_blank(), 57 | panel.grid.minor = element_blank(), 58 | panel.border = element_blank(), 59 | strip.text = element_text(color = "black", margin = margin(6, 6, 6, 6)), 60 | strip.background = element_rect(fill = "gray90") 61 | ) 62 | ) 63 | ``` 64 | 65 | And some functions we'll use for annotating stuff: 66 | 67 | ```{r} 68 | red_ = "#e41a1c" 69 | blue_ = "#6BAED6" 70 | label_color = red_ 71 | 72 | bracket_ = function(..., x, xend = x, y, yend = y, color = label_color, linewidth = 0.5) { 73 | annotate("segment", 74 | arrow = arrow(angle = 90, ends = "both", length = unit(3, "points")), 75 | color = color, linewidth = linewidth, 76 | x = x, xend = xend, y = y, yend = yend, 77 | ... 78 | ) 79 | } 80 | arrow_ = function(..., curvature = 0, x, xend = x, y, yend = y, color = label_color, linewidth = 0.5) { 81 | annotate("curve", 82 | color = color, arrow = arrow(angle = 45, length = unit(3, "points"), type = "closed"), 83 | curvature = curvature, linewidth = linewidth, 84 | lineend = "square", linejoin = "mitre", 85 | x = x, xend = xend, y = y, yend = yend 86 | ) 87 | } 88 | label_ = function(..., hjust = 0, color = label_color, family = "serif") { 89 | annotate("text", 90 | color = color, hjust = hjust, lineheight = 1, 91 | size = 3.75, 92 | family = family, 93 | ... 94 | ) 95 | } 96 | ``` 97 | 98 | 99 | ## Teaser 100 | 101 | This section creates the subfigures used to create the teaser figure. 102 | 103 | ### Slabinterval 104 | 105 | ```{r slabinterval_teaser, echo=FALSE, fig.height=4, fig.width=4} 106 | dists_df = tibble( 107 | # enforce order 108 | geom = rev(c( 109 | "halfeye", 110 | "eye", 111 | "gradientinterval", 112 | "ccdfinterval", 113 | "cdfinterval", 114 | "interval", 115 | "pointinterval", 116 | "slab", 117 | "histinterval" 118 | )) %>% 119 | factor(., levels = .), 120 | dist = dist_normal(4, 1) 121 | ) 122 | 123 | hist_df = tibble( 124 | geom = "histinterval", 125 | x = qnorm(ppoints(1000), 4, 1) 126 | ) 127 | 128 | dists_df_ = function(geom_) filter(dists_df, geom == geom_) 129 | 130 | 131 | # FAMILY HEADER 132 | 133 | dists_xlim = c(0,8) 134 | 135 | header_theme = theme( 136 | plot.title = element_textbox_simple(size = 10, lineheight = 1.1, margin = margin(5,0,5,0)), 137 | axis.line.x = element_blank(), 138 | plot.background = element_rect(fill = "gray95"), 139 | panel.background = element_blank(), 140 | plot.margin = unit(c(5.5, 0, 5.5, 5.5), "points") 141 | ) 142 | 143 | dists_header_plot = dists_df_("halfeye") %>% 144 | mutate(geom = "slabinterval") %>% 145 | ggplot(aes(y = geom, xdist = dist)) + 146 | stat_slabinterval(position = position_nudge(y = - 0.2)) + 147 | scale_x_continuous(limits = dists_xlim, expand = c(0,0), breaks = NULL) + 148 | scale_y_discrete(expand = c(0.4,0)) + 149 | labs( 150 | title = "**The *slabinterval* family**
151 | Combinations of *slabs*, *points*, and *intervals*", 152 | x = NULL, 153 | y = NULL 154 | ) + 155 | header_theme 156 | 157 | # SHORTCUT STATS 158 | 159 | dists_plot = dists_df %>% 160 | ggplot(aes(y = geom, xdist = dist)) + 161 | geom_blank() + # ensures order 162 | stat_eye(data = dists_df_("eye")) + 163 | stat_halfeye(data = dists_df_("halfeye"), position = position_nudge(y = -0.2)) + 164 | stat_gradientinterval(data = dists_df_("gradientinterval"), scale = .5, fill_type = "gradient") + 165 | stat_ccdfinterval(data = dists_df_("ccdfinterval"), scale = .5) + 166 | stat_cdfinterval(data = dists_df_("cdfinterval"), scale = .5) + 167 | stat_interval(data = dists_df_("interval"), color = "gray65", alpha = 1/3, linewidth = 10, 168 | position = position_nudge(y = -.1)) + 169 | stat_pointinterval(data = dists_df_("pointinterval")) + 170 | stat_slab(data = dists_df_("slab"), position = position_nudge(y = - 0.2)) + 171 | stat_histinterval(aes(x = x, xdist = NULL), data = hist_df, position = position_nudge(y = - 0.25)) + 172 | scale_slab_alpha_continuous(guide = "none") + 173 | scale_x_continuous(breaks = NULL, limits = dists_xlim, expand = c(0,0)) + 174 | labs( 175 | x = NULL, 176 | y = NULL 177 | ) 178 | 179 | (dists_header_plot / dists_plot) + plot_layout(heights = c(1.2, 8)) 180 | 181 | ggsave("figs/teaser-slabinterval.pdf", device = cairo_pdf) 182 | ``` 183 | 184 | ### Wee people 185 | 186 | Based on my [wee people example](https://github.com/mjskay/uncertainty-examples/blob/master/weepeople_dotplots.md). 187 | 188 | We need to register the Wee People font: 189 | 190 | ```{r} 191 | font_add( 192 | family = "weepeople", 193 | regular = "fonts/wee-people/weepeople.ttf" 194 | ) 195 | ``` 196 | 197 | Then set up a dataset of people: 198 | 199 | ```{r} 200 | set.seed(1234) 201 | 202 | people_df = data.frame( 203 | x = qnorm(ppoints(100), 1:2), 204 | set = c("a", "b"), 205 | icon = factor(sample(52, 100, replace = TRUE)) 206 | ) 207 | 208 | # the lower and upper case letters in the Wee People font are people: 209 | people_letters = c(letters, LETTERS) 210 | ``` 211 | 212 | Then a plot: 213 | 214 | ```{r teaser_weepeople, fig.width = 4.0, fig.height = 2.9} 215 | p = people_df |> 216 | ggplot(aes(x = x, y = set, group = set, shape = icon, color = x > 0)) + 217 | geom_dots(family = "weepeople", dotsize = 2.4, layout = "swarm")+ 218 | scale_shape_manual(values = people_letters, guide = "none") + 219 | scale_color_brewer(palette = "Set1", guide = "none") + 220 | ylab("group") 221 | 222 | p 223 | ggsave("figs/teaser-weepeople.pdf", plot = p, device = cairo_pdf, width = 4.0, height = 2.9) 224 | ``` 225 | 226 | 227 | 228 | ### Rainclouds 229 | 230 | ```{r teaser_raincloud, fig.width = 6.5, fig.height = 4} 231 | set.seed(12345) # for reproducibility 232 | 233 | p = data.frame( 234 | abc = c("a", "b", "c"), 235 | value = rnorm(600, c(1, 8, 3), c(1, 1.7, 1)) 236 | ) %>% 237 | ggplot(aes(y = abc, x = value, fill = abc)) + 238 | stat_slab(density = "unbounded") + 239 | stat_dotsinterval(side = "bottom", slab_linewidth = NA, slab_color = NA, layout = "bin") + 240 | scale_fill_brewer(palette = "Set2") 241 | 242 | p 243 | ggsave("figs/teaser-raincloud.pdf", device = cairo_pdf) 244 | ``` 245 | 246 | 247 | ### Fit lines 248 | 249 | ```{r teaser_mtcars_lines, fig.width = 6, fig.height = 4} 250 | m_mpg = lm(mpg ~ hp * cyl, data = mtcars) 251 | p = mtcars %>% 252 | group_by(cyl) %>% 253 | expand(hp = seq(min(hp), max(hp), length.out = 101)) %>% 254 | augment(m_mpg, newdata = ., se_fit = TRUE) %>% 255 | ggplot(aes(x = hp, fill = ordered(cyl), color = ordered(cyl))) + 256 | stat_lineribbon( 257 | aes(dist = "norm", arg1 = .fitted, arg2 = .se.fit), 258 | alpha = 1/4 259 | ) + 260 | geom_point(aes(y = mpg), data = mtcars) + 261 | 262 | scale_fill_brewer(palette = "Set2") + 263 | scale_color_brewer(palette = "Dark2") + 264 | labs( 265 | color = "Cylinders", 266 | fill = "Cylinders", 267 | y = "Miles/gallon", 268 | x = "Horsepower" 269 | ) + 270 | theme(legend.position = c(0.75, 0.8), legend.direction = "horizontal") 271 | 272 | p 273 | ggsave("figs/teaser-mtcars-lines.pdf", device = cairo_pdf) 274 | ``` 275 | 276 | ### Logit dotplots 277 | 278 | Fit model: 279 | 280 | ```{r} 281 | gentoo = penguins %>% 282 | filter(species == "Gentoo", !is.na(sex)) 283 | 284 | m = glm(sex == "male" ~ body_mass_g, data = gentoo, family = binomial) 285 | m 286 | ``` 287 | 288 | Logit dotplots: 289 | 290 | ```{r teaser_logit_dotplots, fig.width = 5, fig.height = 1.75} 291 | # construct a prediction grid for the fit line 292 | prediction_grid = with(gentoo, 293 | data.frame(body_mass_g = seq(min(body_mass_g), max(body_mass_g), length.out = 100)) 294 | ) 295 | 296 | p = prediction_grid %>% 297 | bind_cols(predict(m, ., se.fit = TRUE)) %>% 298 | mutate( 299 | # distribution describing uncertainty in log odds 300 | log_odds = dist_normal(fit, se.fit), 301 | # inverse-logit transform the log odds to get 302 | # distribution describing uncertainty in Pr(sex == "male") 303 | p_male = dist_transformed(log_odds, plogis, qlogis) 304 | ) %>% 305 | ggplot(aes(x = body_mass_g)) + 306 | geom_dots( 307 | aes(y = as.numeric(sex == "male"), side = sex), 308 | scale = 0.5, 309 | data = gentoo 310 | ) + 311 | stat_lineribbon( 312 | aes(ydist = p_male), alpha = 1/4, fill = "#08306b" 313 | ) + 314 | scale_side_mirrored(guide = "none") + 315 | coord_cartesian(ylim = c(0, 1)) + 316 | labs( 317 | x = "Body mass (g) of Gentoo penguins", 318 | y = "Pr(sex = male)" 319 | ) 320 | 321 | p 322 | ggsave("figs/teaser-logit_dotplots.pdf", device = cairo_pdf) 323 | ``` 324 | 325 | 326 | 327 | ## Setting the stage 328 | 329 | ### A simplified notation for the grammar of graphics 330 | 331 | We're going to use a slightly modified version of the mtcars dataset: 332 | 333 | ```{r cars} 334 | cars = mtcars |> 335 | mutate(weight = wt) 336 | ``` 337 | 338 | We can generate a nice scatterplot of it: 339 | 340 | ```{r 2-mpg_v_weight, fig.height = 2, fig.width = 2.5} 341 | p = cars |> 342 | ggplot(aes(x = weight, y = mpg)) + 343 | geom_point() 344 | p 345 | 346 | ggsave("figs/2-mpg_v_weight.pdf", device = cairo_pdf) 347 | ``` 348 | 349 | ### Uncertainty as she is spoke 350 | 351 | The (mean, sd) approach: 352 | 353 | ```{r 2-mean_sd_interval, fig.height = 1.25, fig.width = 2.5} 354 | p = data.frame(a = dist_normal(0, 1)) |> 355 | ggplot(aes(xdist = a)) + 356 | stat_pointinterval(.width = .95) + 357 | scale_y_continuous(breaks = NULL) + 358 | scale_x_continuous(breaks = NULL, limits = c(-2.95, 2.95)) + 359 | label_(label = "italic(mu)", x = 0, y = 0.19, hjust = 0.5, parse = TRUE) + 360 | bracket_(x = 0, xend = 1, y = -0.18) + 361 | label_(label = "italic(sigma)", x = 0.5, y = -0.34, hjust = 0.5, parse = TRUE) + 362 | labs(y = NULL, x = NULL) 363 | 364 | p 365 | ggsave("figs/2-mean_sd_interval.pdf", device = cairo_pdf) 366 | ``` 367 | 368 | The magic numbers approach: 369 | 370 | ```{r 2-xmin_xmax_interval, fig.height = 1.25, fig.width = 2.5} 371 | p = data.frame(a = dist_normal(0, 1)) |> 372 | ggplot(aes(xdist = a)) + 373 | stat_pointinterval(.width = .95, justification = 0.55) + 374 | scale_y_continuous(breaks = NULL) + 375 | scale_x_continuous(breaks = NULL, limits = c(-2.95, 2.95)) + 376 | label_(label = "italic(mu)", x = 0, y = 0.17, hjust = 0.5, parse = TRUE) + 377 | arrow_(x = -1.96, y = -0.2, yend = -0.06) + 378 | label_(label = "italic(mu - 1.96%.%sigma)", x = -1.96, y = -0.32, hjust = 0.5, parse = TRUE) + 379 | arrow_(x = 1.96, y = -0.2, yend = -0.06) + 380 | label_(label = "italic(mu + 1.96%.%sigma)", x = 1.96, y = -0.32, hjust = 0.5, parse = TRUE) + 381 | labs(y = NULL, x= NULL) 382 | 383 | p 384 | ggsave("figs/2-xmin_xmax_interval.pdf", device = cairo_pdf) 385 | ``` 386 | 387 | ## Distributional vis 388 | 389 | ### Intervals 390 | 391 | Interval with manually-calculated quantile interval: 392 | 393 | ```{r 3-geom_pointinterval_quantiles, fig.height = 1.75, fig.width = 2.5} 394 | p = data.frame(a = dist_normal(0, 1)) |> 395 | ggplot(aes(xdist = a)) + 396 | stat_pointinterval(.width = .95, justification = 0.65) + 397 | scale_y_continuous(breaks = NULL) + 398 | scale_x_continuous(breaks = NULL, limits = c(-2.95, 2.95)) + 399 | label_(label = "median(italic(M))", x = 0, y = 0.15, hjust = 0.5, parse = TRUE) + 400 | arrow_(x = -1.96, y = -0.2, yend = -0.04) + 401 | label_(label = "{italic(F)[italic(M)]^{-1}}~bgroup('[', over(1 - gamma, 2), ']')", x = -1.96, y = -0.42, hjust = 0.5, parse = TRUE) + 402 | arrow_(x = 1.96, y = -0.2, yend = -0.04) + 403 | label_(label = "{italic(F)[italic(M)]^{-1}}~bgroup('[', over(1 + gamma, 2), ']')", x = 1.96, y = -0.42, hjust = 0.5, parse = TRUE) + 404 | labs(y = NULL, x = NULL) 405 | 406 | p 407 | ggsave("figs/3-geom_pointinterval_quantiles.pdf", device = cairo_pdf) 408 | ``` 409 | Two intervals using mass mapped onto linewidth (still manually calculated): 410 | 411 | ```{r 3-stat_pointinterval_linewidth, fig.height = 2.5, fig.width = 2.5} 412 | p = data.frame(a = dist_normal(0, 1)) |> 413 | ggplot(aes(xdist = a)) + 414 | stat_pointinterval() + 415 | scale_y_continuous(breaks = NULL) + 416 | scale_x_continuous(breaks = NULL, limits = c(-2.5, 2.5)) + 417 | bracket_(x = -1.96, xend = 1.96, y = 0.07) + 418 | label_(label = "γ = 0.95", x = -1.72, y = 0.12, hjust = 0, vjust = 0) + 419 | bracket_(x = -0.95, xend = 0.95, y = -0.07) + 420 | label_(label = "γ = 0.66", x = -0.67, y = -0.12, hjust = 0, vjust = 1) + 421 | labs(y = NULL, x = NULL) 422 | 423 | p 424 | ggsave("figs/3-stat_pointinterval_linewidth.pdf", device = cairo_pdf) 425 | ``` 426 | 427 | Three intervals using mass mapped onto color: 428 | 429 | ```{r 3-stat_pointinterval_color, fig.height = 1.25, fig.width = 2.5} 430 | p = data.frame(a = dist_normal(0, 1)) |> 431 | ggplot(aes(xdist = a)) + 432 | stat_pointinterval(aes(interval_color = after_stat(level)), linewidth = 18, .width = c(.5, .8, .95)) + 433 | scale_y_continuous(breaks = NULL) + 434 | scale_x_continuous(breaks = NULL, limits = c(-2.5, 2.5)) + 435 | scale_color_discrete_sequential(palette = "Light Grays", aesthetics = "interval_color", nmax = 4) + 436 | labs(y = NULL, x = NULL, interval_color = "mass") 437 | 438 | p 439 | ggsave("figs/3-stat_pointinterval_color.pdf", device = cairo_pdf) 440 | ``` 441 | Two intervals on distribution $M$: 442 | 443 | ```{r 3-stat_pointinterval_A, fig.height = 1.75, fig.width = 2.5} 444 | p = data.frame(a = dist_normal(0, 1)) |> 445 | ggplot(aes(xdist = a)) + 446 | stat_pointinterval() + 447 | scale_y_continuous(breaks = NULL) + 448 | scale_x_continuous(breaks = NULL, limits = c(-2.5, 2.5)) + 449 | label_(label = "italic(M)", x = 0, y = 0.15, hjust = 0.5, vjust = 1, parse = TRUE) + 450 | labs(y = NULL, x = NULL) 451 | 452 | p 453 | ggsave("figs/3-stat_pointinterval_A.pdf", device = cairo_pdf) 454 | ``` 455 | 456 | Two intervals on distribution $\textrm{Normal}(\mu, \sigma)$: 457 | 458 | ```{r 3-stat_pointinterval_normal, fig.height = 1.75, fig.width = 2.5} 459 | p = data.frame(a = dist_normal(0, 1)) |> 460 | ggplot(aes(xdist = a)) + 461 | stat_pointinterval() + 462 | scale_y_continuous(breaks = NULL) + 463 | scale_x_continuous(breaks = NULL, limits = c(-2.5, 2.5)) + 464 | label_(label = "Normal(italic(mu), italic(sigma))", x = 0, y = 0.17, hjust = 0.5, vjust = 1, parse = TRUE) + 465 | labs(y = NULL, x = NULL) 466 | 467 | p 468 | ggsave("figs/3-stat_pointinterval_normal.pdf", device = cairo_pdf) 469 | ``` 470 | 471 | 472 | ```{r 3-stat_pointinterval_student_t, fig.height = 1, fig.width = 2.5} 473 | p = data.frame(a = dist_student_t(6, 0, 1)) |> 474 | ggplot(aes(xdist = a)) + 475 | stat_pointinterval() + 476 | scale_y_continuous(breaks = NULL) + 477 | scale_x_continuous(breaks = NULL, limits = c(-2.5, 2.5)) + 478 | label_(label = "italic(t[nu])(italic(mu), italic(sigma))", x = 0, y = 0.4, hjust = 0.5, vjust = 1, parse = TRUE) + 479 | labs(y = NULL, x = NULL) 480 | 481 | p 482 | ggsave("figs/3-stat_pointinterval_student_t.pdf", device = cairo_pdf) 483 | ``` 484 | 485 | ### Ribbons 486 | 487 | Build the model: 488 | 489 | ```{r} 490 | m_mpg = brm( 491 | mpg ~ weight, 492 | family = lognormal, 493 | data = cars, 494 | iter = 5000, 495 | cores = 4, 496 | file = "models/m_mpg.rds", 497 | seed = 3142013 498 | ) 499 | ``` 500 | 501 | And generate the predictions: 502 | 503 | ```{r} 504 | set.seed(9304929) 505 | preds = data.frame(weight = seq(min(cars$weight), max(cars$weight), length.out = 100)) 506 | preds = preds |> 507 | mutate(mpg_given_weight = rvar(posterior_predict(m_mpg, preds))) 508 | head(preds) 509 | ``` 510 | 511 | Now the vis: 512 | 513 | ```{r 3-lineribbon, fig.width = 2.5, fig.height = 2} 514 | p = preds |> 515 | ggplot(aes(x = weight)) + 516 | stat_lineribbon(aes(ydist = mpg_given_weight), linewidth = 0.75) + 517 | geom_point(aes(y = mpg), data = cars, color = alpha("black", 0.65), stroke = 0.65, shape = 21, fill = alpha("white", 0.35), size = 1.25) + 518 | scale_fill_discrete_sequential(palette = "Light Grays", nmax = 4) + 519 | guides(fill = "none") 520 | 521 | p 522 | ggsave("figs/3-lineribbon.pdf", device = cairo_pdf) 523 | ``` 524 | 525 | lineribbon fan: 526 | 527 | ```{r 3-lineribbon_fan, fig.width = 2.5, fig.height = 2} 528 | p = preds |> 529 | ggplot(aes(x = weight)) + 530 | stat_lineribbon(aes(ydist = mpg_given_weight, fill = after_stat(.width)), linewidth = 0.75, .width = ppoints(100)) + 531 | geom_point(aes(y = mpg), data = cars, color = alpha("black", 0.65), stroke = 0.65, shape = 21, fill = alpha("white", 0.35), size = 1.25) + 532 | scale_fill_gradient(low = "gray25", high = "white") + 533 | guides(fill = "none") 534 | 535 | p 536 | ggsave("figs/3-lineribbon_fan.pdf", device = cairo_pdf) 537 | ``` 538 | 539 | ### Slabs 540 | 541 | Two density plots: 542 | 543 | ```{r slab_density_two_groups, fig.width = 2.5, fig.height = 2} 544 | two_a = data.frame( 545 | nu = c(8, 60), 546 | mu = c(6, 1), 547 | sigma = c(1.6, 1.1), 548 | group = factor(c("a", "b")) 549 | ) 550 | 551 | p = two_a |> 552 | ggplot(aes(xdist = dist_student_t(nu, mu, sigma), y = group)) + 553 | stat_slab() + 554 | stat_pointinterval(.width = 0.66, linewidth = 0.5, side = "top") + 555 | bracket_(x = 14, y = 2, yend = 2.9) + 556 | bracket_(x = 14, y = 1, yend = 1.9) + 557 | label_(x = 13.5, y = 2.5, label = "thickness", fontface = "italic", hjust = 1, vjust = 0.9) + 558 | label_(x = 13.5, y = c(1.01, 2.01), label = "0", hjust = 1, vjust = 0.2) + 559 | label_(x = 13.5, y = c(1.92, 2.92), label = "max(italic(f[M](x)))", parse = TRUE, hjust = 1, vjust = 0.8) + 560 | scale_x_continuous(breaks = NULL, limits = c(-3, 14)) + 561 | scale_y_discrete(expand = expansion(0.15)) + 562 | labs(x = NULL) 563 | 564 | p 565 | ggsave("figs/3-slab_density_two_groups.pdf", device = cairo_pdf) 566 | ``` 567 | 568 | Color gradient density plots: 569 | 570 | ```{r slab_gradient_two_groups, fig.width = 2.5, fig.height = 1.25} 571 | p = two_a |> 572 | ggplot(aes(xdist = dist_student_t(nu, mu, sigma), y = group)) + 573 | stat_slab(aes(alpha = !!p_(x)), thickness = 1, side = "both", fill_type = "gradient", scale = 0.7) + 574 | stat_pointinterval(.width = 0.66, linewidth = 0.5) + 575 | scale_x_continuous(breaks = NULL, limits = c(-3, 14)) + 576 | scale_y_discrete(expand = expansion(0.15)) + 577 | scale_alpha_continuous(range = c(0, 1), guide = "none") + 578 | labs(x = NULL) 579 | 580 | p 581 | ggsave("figs/3-slab_gradient_two_groups.pdf", device = cairo_pdf) 582 | ``` 583 | 584 | Correll gradients 585 | 586 | ```{r slab_gradient_correll, fig.width = 2.5, fig.height = 1.25} 587 | p = two_a |> 588 | ggplot(aes(xdist = dist_student_t(nu, mu, sigma), y = group)) + 589 | stat_slab(aes(alpha = - pmax(abs(2*!!Pr_(X <= x) - 1), .95)), thickness = 1, side = "both", fill_type = "gradient", scale = 0.7) + 590 | stat_pointinterval(.width = 0.66, linewidth = 0.5) + 591 | scale_x_continuous(breaks = NULL, limits = c(-3, 14)) + 592 | scale_y_discrete(expand = expansion(0.15)) + 593 | scale_alpha_continuous(range = c(0, 1), guide = "none") + 594 | labs(x = NULL) 595 | 596 | p 597 | ggsave("figs/3-slab_gradient_correll.pdf", device = cairo_pdf) 598 | ``` 599 | 600 | Consonance curve 601 | 602 | ```{r slab_consonance, fig.width = 2.5, fig.height = 1.5} 603 | p = two_a |> 604 | filter(group == "a") |> 605 | ggplot(aes(xdist = dist_student_t(nu, mu, sigma), y = 0, thickness = 1 - abs(2*!!Pr_(X < x) - 1))) + 606 | stat_slab(scale = 1) + 607 | stat_pointinterval(aes(thickness = NULL), .width = c(0.5, .95), side = "top", point_size = 0, color = label_color) + 608 | geom_hline(yintercept = c(0.05, 0.5), color = label_color, alpha = 0.25, linetype = "22") + 609 | stat_spike(at = \(x) qi(x, .width = .5), n = 1001, scale = 1, size = 0, color = label_color, alpha = 0.5) + 610 | stat_spike(at = \(x) qi(x, .width = .95), n = 1001, scale = 1, size = 0, color = label_color, alpha = 0.5) + 611 | scale_x_continuous(breaks = NULL, limits = c(-3, 14), expand = expansion(0)) + 612 | scale_y_continuous(expand = expansion(0.05), limits = c(0, 1), breaks = c(0, 1)) + 613 | label_(x = -2.7, y = c(0.05, 0.5) + .04, label = c("0.05", "0.50"), hjust = 0, vjust = 0) + 614 | label_(x = c(9.8,7.3), y = c(0.05, 0.5) + .04, label = c("95% CI", "50% CI"), hjust = 0, vjust = 0) + 615 | scale_thickness_shared() + 616 | labs( 617 | x = NULL, 618 | y = quote(1 - abs(2 * italic(F)[italic(M)](italic(x)) - 1)) 619 | ) + 620 | theme(axis.title.y.left = element_text(family = "serif", color = label_color)) 621 | 622 | p 623 | ggsave("figs/3-slab_consonance.pdf", device = cairo_pdf) 624 | ``` 625 | 626 | Helske violin gradients 627 | 628 | ```{r slab_violin_gradient, fig.width = 2.5, fig.height = 1.5} 629 | p = two_a |> 630 | ggplot(aes(xdist = dist_student_t(nu, mu, sigma), y = group)) + 631 | stat_slab(aes(alpha = - pmax(abs(2*!!Pr_(X <= x) - 1), .85)), side = "both", fill_type = "gradient") + 632 | stat_pointinterval(.width = 0.66, linewidth = 0.5) + 633 | scale_x_continuous(breaks = NULL, limits = c(-3, 14)) + 634 | scale_y_discrete(expand = expansion(0.15)) + 635 | scale_alpha_continuous(range = c(0, 1), guide = "none") + 636 | labs(x = NULL) 637 | 638 | p 639 | ggsave("figs/3-slab_violin_gradient.pdf", device = cairo_pdf) 640 | ``` 641 | 642 | Helske-like violin intervals: 643 | 644 | ```{r slab_violin_interval, fig.width = 2.5, fig.height = 1.5} 645 | p = two_a |> 646 | ggplot(aes(xdist = dist_student_t(nu, mu, sigma), y = group)) + 647 | stat_slab(aes(fill = after_stat(level)), side = "both", .width = c(.5, .8, .95, 1)) + 648 | stat_pointinterval(.width = 0.66, linewidth = 0.5) + 649 | scale_x_continuous(breaks = NULL, limits = c(-3, 14)) + 650 | scale_y_discrete(expand = expansion(0.15)) + 651 | scale_fill_discrete_sequential(palette = "Light Grays", nmax = 6) + 652 | guides(fill = "none") + 653 | labs(x = NULL) 654 | 655 | p 656 | ggsave("figs/3-slab_violin_interval.pdf", device = cairo_pdf) 657 | ``` 658 | 659 | Raindrop plots: 660 | 661 | ```{r slab_raindrop, fig.width = 2.5, fig.height = 1.5} 662 | p = two_a |> 663 | ggplot(aes(xdist = dist_student_t(nu, mu, sigma), y = group)) + 664 | stat_slab(aes(thickness = ifelse(.width <= .95, log(!!p_(x)), NA)), normalize = "groups", .width = .95, linewidth = 0.5, side = "both") + 665 | stat_pointinterval(.width = 0.66, linewidth = 0.5) + 666 | scale_x_continuous(breaks = NULL, limits = c(-3, 14)) + 667 | scale_y_discrete(expand = expansion(0.15)) + 668 | guides(alpha = "none") + 669 | labs(x = NULL) 670 | 671 | p 672 | ggsave("figs/3-slab_raindrop.pdf", device = cairo_pdf) 673 | ``` 674 | 675 | Fuzzygrams: 676 | 677 | ```{r slab_fuzzygram, fig.width = 2.5, fig.height = 1.25} 678 | p = two_a |> 679 | ggplot(aes(xdist = dist_student_t(nu, mu, sigma), y = group)) + 680 | stat_slab(aes(alpha = !!Pr_(X > x)), thickness = 1, side = "both", fill_type = "gradient", scale = 0.7) + 681 | stat_pointinterval(.width = 0.66, linewidth = 0.5) + 682 | scale_x_continuous(breaks = NULL, limits = c(-3, 14), expand = expansion(0)) + 683 | scale_y_discrete(expand = expansion(0.15)) + 684 | scale_alpha_continuous(range = c(0, 1), guide = "none") + 685 | labs(x = NULL) 686 | 687 | p 688 | ggsave("figs/3-slab_fuzzygram.pdf", device = cairo_pdf) 689 | ``` 690 | 691 | Regions of practical equivalence: 692 | 693 | ```{r slab_rope, fig.width = 2.5, fig.height = 2} 694 | two_a_zero = data.frame( 695 | nu = c(5, 60), 696 | mu = c(5, 0), 697 | sigma = c(1.3, 1.1), 698 | group = factor(c("a", "b")) 699 | ) 700 | 701 | p = two_a_zero |> 702 | ggplot(aes(xdist = dist_student_t(nu, mu, sigma), y = group)) + 703 | stat_slab(aes(fill = after_stat(abs(x) < 2))) + 704 | # stat_pointinterval(.width = 0.66, linewidth = 0.5, color = label_color) + 705 | scale_x_continuous(breaks = seq(-2, 14, by = 2)) + 706 | scale_y_discrete(expand = expansion(0.15)) + 707 | scale_fill_manual( 708 | values = c("FALSE" = "gray80", "TRUE" = blue_), 709 | guide = guide_legend(reverse = TRUE, title.hjust = 1) 710 | ) + 711 | labs(x = NULL, fill = "|x| < 2") + 712 | theme(legend.position = c(0.75,0.75)) 713 | 714 | p 715 | ggsave("figs/3-slab_rope.pdf", device = cairo_pdf) 716 | ``` 717 | 718 | ### Dotplots 719 | 720 | Two dotplots: 721 | 722 | ```{r dots_two, fig.width = 2.5, fig.height = 1.65} 723 | p = two_a_zero |> 724 | ggplot(aes(xdist = dist_student_t(nu, mu, sigma), y = group)) + 725 | stat_dots(quantiles = 100) + 726 | scale_x_continuous(breaks = seq(-2, 14, by = 2)) + 727 | scale_y_discrete(expand = expansion(0.15)) + 728 | labs(x = NULL) 729 | 730 | p 731 | ggsave("figs/3-dots_two.pdf", device = cairo_pdf) 732 | ``` 733 | 734 | Dotplots with emoji: 735 | 736 | ```{r dots_emoji, fig.width = 2.5, fig.height = 1.65} 737 | p = two_a_zero |> 738 | filter(group == "b") |> 739 | ggplot(aes(xdist = dist_student_t(nu, mu, sigma))) + 740 | # geom_vline(xintercept = 0, color = "gray85", linewidth = 0.25) + 741 | stat_dots(aes(shape = after_stat(x > 0)), quantiles = 50, stackratio = 1.1, dotsize = 0.9) + 742 | scale_x_continuous(breaks = seq(-4, 4, by = 2), limits = c(-4, 4)) + 743 | scale_y_continuous(breaks = NULL, expand = expansion(0.01)) + 744 | scale_shape_manual( 745 | values = c("FALSE" = "😧", "TRUE" = "🙂"), 746 | guide = guide_legend(reverse = TRUE, title.hjust = 0.92, override.aes = list(linewidth = 3)) 747 | ) + 748 | labs(x = NULL, y = NULL) + 749 | theme( 750 | legend.position = c(0.85,0.8), 751 | legend.spacing.x = unit(4, 'pt'), 752 | legend.spacing.y = unit(4, 'pt'), 753 | legend.key.size = unit(14, "pt") 754 | ) 755 | 756 | p 757 | ggsave("figs/3-dots_emoji.png", device = agg_png, dpi = 900) 758 | ``` 759 | 760 | ## Implementation 761 | 762 | Helske-esque interval-density plots used for the implementation figure: 763 | 764 | ```{r slab_implementation, fig.width = 2.5, fig.height = 1.5} 765 | p = two_a |> 766 | ggplot(aes(xdist = dist_student_t(nu, mu, sigma), y = group)) + 767 | stat_slab(aes(fill = after_stat(level)), .width = c(.5, .8, .95, 1)) + 768 | # scale_x_continuous(breaks = seq(0, 14, by = 3), limits = c(-3, 14)) + 769 | scale_x_continuous(breaks = NULL, limits = c(-3, 14)) + 770 | scale_y_discrete(expand = expansion(0.15)) + 771 | scale_fill_discrete_sequential(palette = "Light Grays", nmax = 6) + 772 | guides(fill = "none") + 773 | labs(x = NULL) 774 | 775 | p 776 | ggsave("figs/4-slab.pdf", device = cairo_pdf) 777 | ``` 778 | 779 | 780 | ## Lessons learned 781 | 782 | ### Jacobians 783 | 784 | Log-normal distribution on the original scale (using `stat_function()`): 785 | 786 | ```{r 3-jacobian-lognorm, fig.width=2.5, fig.height = 1.25} 787 | p = ggplot() + 788 | stat_function(fun = \(x) dlnorm(x, 0, 1), n = 1000, fill = "gray75", geom = "area") + 789 | geom_vline(xintercept = 1, color = label_color, linewidth = 0.5) + 790 | label_(x = 1.4, y = 0.675, label = "median", vjust = 1, hjust = 0) + 791 | scale_x_continuous(limits = c(0, 10), breaks = 0:10) + 792 | scale_y_continuous(breaks = NULL) + 793 | labs(x = NULL, y = NULL) 794 | 795 | p 796 | ggsave("figs/3-jacobian-lognorm.pdf", device = cairo_pdf) 797 | ``` 798 | 799 | Incorrect log-normal distribution on the log scale (using `stat_function()`): 800 | 801 | ```{r 3-jacobian-incorrect, fig.width=2.5, fig.height = 1.25} 802 | p = ggplot() + 803 | stat_function(fun = \(x) dlnorm(x, 0, 1), n = 1000, geom = "area", fill = "gray75") + 804 | geom_vline(xintercept = 1, color = label_color, linewidth = 0.5) + 805 | label_(x = 1.4, y = 0.675, label = "median should\nbe here???", vjust = 1, hjust = 0) + 806 | scale_x_log10(limits = 10^c(-2,2), breaks = 10^(-2:2), labels = as.character) + 807 | scale_y_continuous(breaks = NULL) + 808 | labs(x = NULL, y = NULL) 809 | 810 | p 811 | ggsave("figs/3-jacobian-incorrect.pdf", device = cairo_pdf) 812 | ``` 813 | 814 | Correct log-normal distribution on the log scale (using `stat_slab()`): 815 | 816 | ```{r 3-jacobian-correct, fig.width=2.5, fig.height = 1.25} 817 | p = ggplot() + 818 | stat_slab(aes(xdist = dist_lognormal(0, 1)), scale = 1, fill = "gray75") + 819 | geom_vline(xintercept = 1, color = label_color, linewidth = 0.5) + 820 | label_(x = 1.75, y = 1.1, label = "median is here :)", vjust = 1) + 821 | scale_x_log10(limits = 10^c(-2,2), breaks = 10^(-2:2), labels = as.character) + 822 | scale_y_continuous(breaks = NULL) + 823 | labs(x = NULL, y = NULL) 824 | 825 | p 826 | ggsave("figs/3-jacobian-correct.pdf", device = cairo_pdf) 827 | ``` 828 | 829 | 830 | 831 | ## Session Info 832 | 833 | This file was built with the following setup: 834 | 835 | ```{r session info} 836 | sessionInfo() 837 | ``` 838 | -------------------------------------------------------------------------------- /abbrv-doi-hyperref.bst: -------------------------------------------------------------------------------- 1 | % BibTeX standard bibliography style `abbrv' 2 | % version 0.99a for BibTeX versions 0.99a or later, LaTeX version 2.09. 3 | % Copyright (C) 1985, all rights reserved. 4 | % Copying of this file is authorized only if either 5 | % (1) you make absolutely no changes to your copy, including name, or 6 | % (2) if you do make changes, you name it something other than 7 | % btxbst.doc, plain.bst, unsrt.bst, alpha.bst, and abbrv.bst. 8 | % This restriction helps ensure that all standard styles are identical. 9 | % The file btxbst.doc has the documentation for this style. 10 | 11 | ENTRY 12 | { address 13 | author 14 | booktitle 15 | chapter 16 | edition 17 | editor 18 | howpublished 19 | institution 20 | journal 21 | key 22 | month 23 | note 24 | number 25 | organization 26 | pages 27 | publisher 28 | school 29 | series 30 | title 31 | type 32 | volume 33 | year 34 | url 35 | url2 36 | doi 37 | pdf 38 | postscript 39 | } 40 | {} 41 | { label } 42 | 43 | INTEGERS { output.state before.all mid.sentence after.sentence after.block } 44 | 45 | FUNCTION {init.state.consts} 46 | { #0 'before.all := 47 | #1 'mid.sentence := 48 | #2 'after.sentence := 49 | #3 'after.block := 50 | } 51 | 52 | STRINGS { s t } 53 | 54 | FUNCTION {add.link} % title 55 | { 56 | 't := 57 | t empty$ 58 | { "" } 59 | { doi empty$ 60 | { url empty$ 61 | { pdf empty$ 62 | { postscript empty$ 63 | { url2 empty$ 64 | { t } 65 | { "\href{" url2 * "}{" * t * "}" * } 66 | if$ } 67 | { "\href{" postscript * "}{" * t * "}" * } 68 | if$ } 69 | { "\href{" pdf * "}{" * t * "}" * } 70 | if$ } 71 | { "\href{" url * "}{" * t * "}" * } 72 | if$ } 73 | { 74 | doi #1 #7 substring$ "http://" = 75 | { "\href{" doi * "}{" * t * "}" * } 76 | { "\href{https://doi.org/" doi * "}{" * t * "}" * } 77 | if$ 78 | } 79 | if$ } 80 | if$ 81 | } 82 | 83 | FUNCTION {output.nonnull} 84 | { 's := 85 | output.state mid.sentence = 86 | { ", " * write$ } 87 | { output.state after.block = 88 | { add.period$ write$ 89 | newline$ 90 | "\newblock " write$ 91 | } 92 | { output.state before.all = 93 | 'write$ 94 | { add.period$ " " * write$ } 95 | if$ 96 | } 97 | if$ 98 | mid.sentence 'output.state := 99 | } 100 | if$ 101 | s 102 | %add.link 103 | } 104 | 105 | FUNCTION {output} 106 | { duplicate$ empty$ 107 | 'pop$ 108 | 'output.nonnull 109 | if$ 110 | } 111 | 112 | FUNCTION {output.check} 113 | { 't := 114 | duplicate$ empty$ 115 | { pop$ "empty " t * " in " * cite$ * warning$ } 116 | 'output.nonnull 117 | if$ 118 | } 119 | 120 | FUNCTION {output.bibitem} 121 | { newline$ 122 | "\bibitem{" write$ 123 | cite$ write$ 124 | "}" write$ 125 | newline$ 126 | "" 127 | before.all 'output.state := 128 | } 129 | 130 | STRINGS { d dc pc.str doi.urlstr } 131 | 132 | INTEGERS { nth.dash doi.string.pos doilen } 133 | 134 | FUNCTION {add.doi} 135 | { doi empty$ 136 | { } 137 | { 138 | "\%" #2 #1 substring$ 'pc.str := 139 | doi 'd := 140 | "" 'doi.urlstr := 141 | #0 'nth.dash := 142 | #1 'doi.string.pos := 143 | %% find the url part of the doi 144 | d text.length$ 'doilen := 145 | { nth.dash #3 < } 146 | { 147 | d doi.string.pos #1 substring$ 'dc := 148 | #1 doi.string.pos + 'doi.string.pos := 149 | 150 | dc "/" = 151 | { #1 nth.dash + 'nth.dash := } 152 | {} 153 | if$ 154 | % in case the doi didn't have the http... part 155 | doi.string.pos doilen = 156 | { 157 | #3 'nth.dash := 158 | #1 'doi.string.pos := 159 | "https://doi.org/" 'doi.urlstr := 160 | } 161 | {} 162 | if$ 163 | } 164 | while$ 165 | % check for case with more than one dash in doi part but without doi given (was truncated before) 166 | % in that case the doi.string.pos should not be at the start (!= #1), i.e., truncated 167 | % and the beginning of the whole string should be != http, i.e., the actual doi started at the beginning 168 | doi.string.pos #1 = 169 | {} 170 | { 171 | d #1 #4 substring$ "http" = 172 | {} 173 | { 174 | #1 'doi.string.pos := 175 | "https://doi.org/" 'doi.urlstr := 176 | } 177 | if$ 178 | } 179 | if$ 180 | % actually remove the url part of the doi 181 | d text.length$ 'doilen := 182 | doilen doi.string.pos - #1 + 'doilen := 183 | d doi.string.pos doilen substring$ 'd := 184 | 185 | " \href{" doi.urlstr * doi * "}" * write$ 186 | newline$ 187 | % uses \usepackage{microtype} for \textls and \usepackage{PTSansNarrow} for \textsf 188 | % notice the additional \hspace calls in the replacement of "." 189 | "{doi: {{" pc.str * write$ 190 | %"{doi\raisebox{0.5pt}{\textgreater} \textls[0]{\textsf{" pc.str * write$ 191 | newline$ 192 | 193 | % figure out slash hyphenation 194 | #1 'doi.string.pos := 195 | { doi.string.pos d text.length$ < } 196 | { 197 | d doi.string.pos #1 substring$ 'dc := 198 | #1 doi.string.pos + 'doi.string.pos := 199 | 200 | dc "/" = 201 | { "\discretionary{/}{" pc.str * write$ 202 | newline$ 203 | "}{/}" write$ 204 | } 205 | { 206 | dc "." = 207 | { "\hspace{.1pt}\discretionary{.}{" pc.str * write$ 208 | newline$ 209 | "}{.}\hspace{.4pt}" write$ 210 | } 211 | { 212 | dc "_" = 213 | { "\_" write$ } 214 | { 215 | dc "<" = 216 | { "{\textless}" write$ } 217 | { 218 | dc ">" = 219 | { "{\textgreater}" write$ } 220 | { 221 | dc "-" = 222 | { "\discretionary{" pc.str * write$ 223 | newline$ 224 | "}{-}{-}" write$ 225 | } 226 | { 227 | dc "(" = 228 | { "\discretionary{" pc.str * write$ 229 | newline$ 230 | "}{(}{(}" write$ 231 | } 232 | { 233 | dc ")" = 234 | { "\discretionary{)}{" pc.str * write$ 235 | newline$ 236 | "}{)}" write$ 237 | } 238 | { 239 | dc ":" = 240 | { "\discretionary{:}{" pc.str * write$ 241 | newline$ 242 | "}{:}" write$ 243 | } 244 | { 245 | dc ";" = 246 | { "\discretionary{;}{" pc.str * write$ 247 | newline$ 248 | "}{;}" write$ 249 | } 250 | { dc write$ } 251 | if$ 252 | } 253 | if$ 254 | } 255 | if$ 256 | } 257 | if$ 258 | } 259 | if$ 260 | } 261 | if$ 262 | } 263 | if$ 264 | } 265 | if$ 266 | } 267 | if$ 268 | } 269 | if$ 270 | } 271 | while$ 272 | d doi.string.pos #1 substring$ 'dc := 273 | dc "}}}" * write$ 274 | newline$ 275 | } 276 | if$ 277 | } 278 | 279 | FUNCTION {fin.entry} 280 | { add.period$ 281 | write$ 282 | add.doi 283 | newline$ 284 | } 285 | 286 | FUNCTION {new.block} 287 | { output.state before.all = 288 | 'skip$ 289 | { after.block 'output.state := } 290 | if$ 291 | } 292 | 293 | FUNCTION {new.sentence} 294 | { output.state after.block = 295 | 'skip$ 296 | { output.state before.all = 297 | 'skip$ 298 | { after.sentence 'output.state := } 299 | if$ 300 | } 301 | if$ 302 | } 303 | 304 | FUNCTION {not} 305 | { { #0 } 306 | { #1 } 307 | if$ 308 | } 309 | 310 | FUNCTION {and} 311 | { 'skip$ 312 | { pop$ #0 } 313 | if$ 314 | } 315 | 316 | FUNCTION {or} 317 | { { pop$ #1 } 318 | 'skip$ 319 | if$ 320 | } 321 | 322 | FUNCTION {new.block.checka} 323 | { empty$ 324 | 'skip$ 325 | 'new.block 326 | if$ 327 | } 328 | 329 | FUNCTION {new.block.checkb} 330 | { empty$ 331 | swap$ empty$ 332 | and 333 | 'skip$ 334 | 'new.block 335 | if$ 336 | } 337 | 338 | FUNCTION {new.sentence.checka} 339 | { empty$ 340 | 'skip$ 341 | 'new.sentence 342 | if$ 343 | } 344 | 345 | FUNCTION {new.sentence.checkb} 346 | { empty$ 347 | swap$ empty$ 348 | and 349 | 'skip$ 350 | 'new.sentence 351 | if$ 352 | } 353 | 354 | FUNCTION {field.or.null} 355 | { duplicate$ empty$ 356 | { pop$ "" } 357 | 'skip$ 358 | if$ 359 | } 360 | 361 | FUNCTION {emphasize} 362 | { duplicate$ empty$ 363 | { pop$ "" } 364 | { "{\em " swap$ * "}" * } 365 | if$ 366 | } 367 | 368 | INTEGERS { nameptr namesleft numnames } 369 | 370 | FUNCTION {format.names} 371 | { 's := 372 | #1 'nameptr := 373 | s num.names$ 'numnames := 374 | numnames 'namesleft := 375 | { namesleft #0 > } 376 | { s nameptr "{f.~}{vv~}{ll}{, jj}" format.name$ 't := 377 | nameptr #1 > 378 | { namesleft #1 > 379 | { ", " * t * } 380 | { numnames #2 > 381 | { "," * } 382 | 'skip$ 383 | if$ 384 | t "others" = 385 | { " et~al." * } 386 | { " and " * t * } 387 | if$ 388 | } 389 | if$ 390 | } 391 | 't 392 | if$ 393 | nameptr #1 + 'nameptr := 394 | namesleft #1 - 'namesleft := 395 | } 396 | while$ 397 | } 398 | 399 | FUNCTION {format.authors} 400 | { author empty$ 401 | { "" } 402 | { author format.names } 403 | if$ 404 | } 405 | 406 | FUNCTION {format.editors} 407 | { editor empty$ 408 | { "" } 409 | { editor format.names 410 | editor num.names$ #1 > 411 | { ", eds." * } 412 | { ", ed." * } 413 | if$ 414 | } 415 | if$ 416 | } 417 | 418 | FUNCTION {format.title} 419 | { title empty$ 420 | { "" } 421 | { title "t" change.case$ } 422 | if$ 423 | %add.link 424 | } 425 | 426 | FUNCTION {n.dashify} 427 | { 't := 428 | "" 429 | { t empty$ not } 430 | { t #1 #1 substring$ "-" = 431 | { t #1 #2 substring$ "--" = not 432 | { "--" * 433 | t #2 global.max$ substring$ 't := 434 | } 435 | { { t #1 #1 substring$ "-" = } 436 | { "-" * 437 | t #2 global.max$ substring$ 't := 438 | } 439 | while$ 440 | } 441 | if$ 442 | } 443 | { t #1 #1 substring$ * 444 | t #2 global.max$ substring$ 't := 445 | } 446 | if$ 447 | } 448 | while$ 449 | } 450 | 451 | FUNCTION {format.date} 452 | { year empty$ 453 | { month empty$ 454 | { "" } 455 | { "there's a month but no year in " cite$ * warning$ 456 | month 457 | } 458 | if$ 459 | } 460 | { month empty$ 461 | 'year 462 | { month " " * year * } 463 | if$ 464 | } 465 | if$ 466 | } 467 | 468 | FUNCTION {format.btitle} 469 | { title emphasize 470 | %add.link 471 | } 472 | 473 | FUNCTION {tie.or.space.connect} 474 | { duplicate$ text.length$ #3 < 475 | { "~" } 476 | { " " } 477 | if$ 478 | swap$ * * 479 | } 480 | 481 | FUNCTION {either.or.check} 482 | { empty$ 483 | 'pop$ 484 | { "can't use both " swap$ * " fields in " * cite$ * warning$ } 485 | if$ 486 | } 487 | 488 | FUNCTION {format.bvolume} 489 | { volume empty$ 490 | { "" } 491 | { "vol." volume tie.or.space.connect 492 | series empty$ 493 | 'skip$ 494 | { " of " * series emphasize * } 495 | if$ 496 | "volume and number" number either.or.check 497 | } 498 | if$ 499 | } 500 | 501 | FUNCTION {format.number.series} 502 | { volume empty$ 503 | { number empty$ 504 | { series field.or.null } 505 | { output.state mid.sentence = 506 | { "number" } 507 | { "Number" } 508 | if$ 509 | number tie.or.space.connect 510 | series empty$ 511 | { "there's a number but no series in " cite$ * warning$ } 512 | { " in " * series * } 513 | if$ 514 | } 515 | if$ 516 | } 517 | { "" } 518 | if$ 519 | } 520 | 521 | FUNCTION {format.edition} 522 | { edition empty$ 523 | { "" } 524 | { output.state mid.sentence = 525 | { edition "l" change.case$ " ed." * } 526 | { edition "t" change.case$ " ed." * } 527 | if$ 528 | } 529 | if$ 530 | } 531 | 532 | INTEGERS { multiresult } 533 | 534 | FUNCTION {multi.page.check} 535 | { 't := 536 | #0 'multiresult := 537 | { multiresult not 538 | t empty$ not 539 | and 540 | } 541 | { t #1 #1 substring$ 542 | duplicate$ "-" = 543 | swap$ duplicate$ "," = 544 | swap$ "+" = 545 | or or 546 | { #1 'multiresult := } 547 | { t #2 global.max$ substring$ 't := } 548 | if$ 549 | } 550 | while$ 551 | multiresult 552 | } 553 | 554 | FUNCTION {format.pages} 555 | { pages empty$ 556 | { "" } 557 | { pages multi.page.check 558 | { "pp." pages n.dashify tie.or.space.connect } 559 | { "p." pages tie.or.space.connect } 560 | if$ 561 | } 562 | if$ 563 | } 564 | 565 | FUNCTION {format.vol.num.pages} 566 | { volume field.or.null 567 | number empty$ 568 | 'skip$ 569 | { "(" number * ")" * * 570 | volume empty$ 571 | { "there's a number but no volume in " cite$ * warning$ } 572 | 'skip$ 573 | if$ 574 | } 575 | if$ 576 | pages empty$ 577 | 'skip$ 578 | { duplicate$ empty$ 579 | { pop$ format.pages } 580 | { ":" * pages n.dashify * } 581 | if$ 582 | } 583 | if$ 584 | } 585 | 586 | FUNCTION {format.chapter.pages} 587 | { chapter empty$ 588 | 'format.pages 589 | { type empty$ 590 | { "chap." } 591 | { type "l" change.case$ } 592 | if$ 593 | chapter tie.or.space.connect 594 | pages empty$ 595 | 'skip$ 596 | { ", " * format.pages * } 597 | if$ 598 | } 599 | if$ 600 | } 601 | 602 | FUNCTION {format.in.ed.booktitle} 603 | { booktitle empty$ 604 | { "" } 605 | { editor empty$ 606 | { "In " booktitle emphasize * } 607 | { "In " format.editors * ", " * booktitle emphasize * } 608 | if$ 609 | } 610 | if$ 611 | } 612 | 613 | FUNCTION {empty.misc.check} 614 | { author empty$ title empty$ howpublished empty$ 615 | month empty$ year empty$ note empty$ 616 | and and and and and 617 | key empty$ not and 618 | { "all relevant fields are empty in " cite$ * warning$ } 619 | 'skip$ 620 | if$ 621 | } 622 | 623 | FUNCTION {format.thesis.type} 624 | { type empty$ 625 | 'skip$ 626 | { pop$ 627 | type "t" change.case$ 628 | } 629 | if$ 630 | } 631 | 632 | FUNCTION {format.tr.number} 633 | { type empty$ 634 | { "Technical Report" } 635 | 'type 636 | if$ 637 | number empty$ 638 | { "t" change.case$ } 639 | { number tie.or.space.connect } 640 | if$ 641 | } 642 | 643 | FUNCTION {format.article.crossref} 644 | { key empty$ 645 | { journal empty$ 646 | { "need key or journal for " cite$ * " to crossref " * crossref * 647 | warning$ 648 | "" 649 | } 650 | { "In {\em " journal * "\/}" * } 651 | if$ 652 | } 653 | { "In " key * } 654 | if$ 655 | " \cite{" * crossref * "}" * 656 | } 657 | 658 | FUNCTION {format.crossref.editor} 659 | { editor #1 "{vv~}{ll}" format.name$ 660 | editor num.names$ duplicate$ 661 | #2 > 662 | { pop$ " et~al." * } 663 | { #2 < 664 | 'skip$ 665 | { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = 666 | { " et~al." * } 667 | { " and " * editor #2 "{vv~}{ll}" format.name$ * } 668 | if$ 669 | } 670 | if$ 671 | } 672 | if$ 673 | } 674 | 675 | FUNCTION {format.book.crossref} 676 | { volume empty$ 677 | { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ 678 | "In " 679 | } 680 | { "Vol." volume tie.or.space.connect 681 | " of " * 682 | } 683 | if$ 684 | editor empty$ 685 | editor field.or.null author field.or.null = 686 | or 687 | { key empty$ 688 | { series empty$ 689 | { "need editor, key, or series for " cite$ * " to crossref " * 690 | crossref * warning$ 691 | "" * 692 | } 693 | { "{\em " * series * "\/}" * } 694 | if$ 695 | } 696 | { key * } 697 | if$ 698 | } 699 | { format.crossref.editor * } 700 | if$ 701 | " \cite{" * crossref * "}" * 702 | } 703 | 704 | FUNCTION {format.incoll.inproc.crossref} 705 | { editor empty$ 706 | editor field.or.null author field.or.null = 707 | or 708 | { key empty$ 709 | { booktitle empty$ 710 | { "need editor, key, or booktitle for " cite$ * " to crossref " * 711 | crossref * warning$ 712 | "" 713 | } 714 | { "In {\em " booktitle * "\/}" * } 715 | if$ 716 | } 717 | { "In " key * } 718 | if$ 719 | } 720 | { "In " format.crossref.editor * } 721 | if$ 722 | " \cite{" * crossref * "}" * 723 | } 724 | 725 | FUNCTION {article} 726 | { output.bibitem 727 | format.authors "author" output.check 728 | new.block 729 | format.title "title" output.check 730 | new.block 731 | crossref missing$ 732 | { journal emphasize "journal" output.check 733 | format.vol.num.pages output 734 | format.date "year" output.check 735 | } 736 | { format.article.crossref output.nonnull 737 | format.pages output 738 | } 739 | if$ 740 | new.block 741 | note output 742 | fin.entry 743 | } 744 | 745 | FUNCTION {book} 746 | { output.bibitem 747 | author empty$ 748 | { format.editors "author and editor" output.check } 749 | { format.authors output.nonnull 750 | crossref missing$ 751 | { "author and editor" editor either.or.check } 752 | 'skip$ 753 | if$ 754 | } 755 | if$ 756 | new.block 757 | format.btitle "title" output.check 758 | crossref missing$ 759 | { format.bvolume output 760 | new.block 761 | format.number.series output 762 | new.sentence 763 | publisher "publisher" output.check 764 | address output 765 | } 766 | { new.block 767 | format.book.crossref output.nonnull 768 | } 769 | if$ 770 | format.edition output 771 | format.date "year" output.check 772 | new.block 773 | note output 774 | fin.entry 775 | } 776 | 777 | FUNCTION {booklet} 778 | { output.bibitem 779 | format.authors output 780 | new.block 781 | format.title "title" output.check 782 | howpublished address new.block.checkb 783 | howpublished output 784 | address output 785 | format.date output 786 | new.block 787 | note output 788 | fin.entry 789 | } 790 | 791 | FUNCTION {inbook} 792 | { output.bibitem 793 | author empty$ 794 | { format.editors "author and editor" output.check } 795 | { format.authors output.nonnull 796 | crossref missing$ 797 | { "author and editor" editor either.or.check } 798 | 'skip$ 799 | if$ 800 | } 801 | if$ 802 | new.block 803 | format.btitle "title" output.check 804 | crossref missing$ 805 | { format.bvolume output 806 | format.chapter.pages "chapter and pages" output.check 807 | new.block 808 | format.number.series output 809 | new.sentence 810 | publisher "publisher" output.check 811 | address output 812 | } 813 | { format.chapter.pages "chapter and pages" output.check 814 | new.block 815 | format.book.crossref output.nonnull 816 | } 817 | if$ 818 | format.edition output 819 | format.date "year" output.check 820 | new.block 821 | note output 822 | fin.entry 823 | } 824 | 825 | FUNCTION {incollection} 826 | { output.bibitem 827 | format.authors "author" output.check 828 | new.block 829 | format.title "title" output.check 830 | new.block 831 | crossref missing$ 832 | { format.in.ed.booktitle "booktitle" output.check 833 | format.bvolume output 834 | format.number.series output 835 | format.chapter.pages output 836 | new.sentence 837 | publisher "publisher" output.check 838 | address output 839 | format.edition output 840 | format.date "year" output.check 841 | } 842 | { format.incoll.inproc.crossref output.nonnull 843 | format.chapter.pages output 844 | } 845 | if$ 846 | new.block 847 | note output 848 | fin.entry 849 | } 850 | 851 | FUNCTION {inproceedings} 852 | { output.bibitem 853 | format.authors "author" output.check 854 | new.block 855 | format.title "title" output.check 856 | new.block 857 | crossref missing$ 858 | { format.in.ed.booktitle "booktitle" output.check 859 | format.bvolume output 860 | format.number.series output 861 | format.pages output 862 | address empty$ 863 | { organization publisher new.sentence.checkb 864 | organization output 865 | publisher output 866 | format.date "year" output.check 867 | } 868 | { new.sentence 869 | organization output 870 | publisher output 871 | address output.nonnull 872 | format.date "year" output.check 873 | } 874 | if$ 875 | } 876 | { format.incoll.inproc.crossref output.nonnull 877 | format.pages output 878 | } 879 | if$ 880 | new.block 881 | note output 882 | fin.entry 883 | } 884 | 885 | FUNCTION {conference} { inproceedings } 886 | 887 | FUNCTION {manual} 888 | { output.bibitem 889 | author empty$ 890 | { organization empty$ 891 | 'skip$ 892 | { organization output.nonnull 893 | address output 894 | } 895 | if$ 896 | } 897 | { format.authors output.nonnull } 898 | if$ 899 | new.block 900 | format.btitle "title" output.check 901 | author empty$ 902 | { organization empty$ 903 | { address new.block.checka 904 | address output 905 | } 906 | 'skip$ 907 | if$ 908 | } 909 | { organization address new.block.checkb 910 | organization output 911 | address output 912 | } 913 | if$ 914 | format.edition output 915 | format.date output 916 | new.block 917 | note output 918 | fin.entry 919 | } 920 | 921 | FUNCTION {mastersthesis} 922 | { output.bibitem 923 | format.authors "author" output.check 924 | new.block 925 | format.title "title" output.check 926 | new.block 927 | "Master's thesis" format.thesis.type output.nonnull 928 | school "school" output.check 929 | address output 930 | format.date "year" output.check 931 | new.block 932 | note output 933 | fin.entry 934 | } 935 | 936 | FUNCTION {misc} 937 | { output.bibitem 938 | format.authors output 939 | title howpublished new.block.checkb 940 | format.title output 941 | howpublished new.block.checka 942 | howpublished output 943 | format.date output 944 | new.block 945 | note output 946 | fin.entry 947 | empty.misc.check 948 | } 949 | 950 | FUNCTION {phdthesis} 951 | { output.bibitem 952 | format.authors "author" output.check 953 | new.block 954 | format.btitle "title" output.check 955 | new.block 956 | "PhD thesis" format.thesis.type output.nonnull 957 | school "school" output.check 958 | address output 959 | format.date "year" output.check 960 | new.block 961 | note output 962 | fin.entry 963 | } 964 | 965 | FUNCTION {proceedings} 966 | { output.bibitem 967 | editor empty$ 968 | { organization output } 969 | { format.editors output.nonnull } 970 | if$ 971 | new.block 972 | format.btitle "title" output.check 973 | format.bvolume output 974 | format.number.series output 975 | address empty$ 976 | { editor empty$ 977 | { publisher new.sentence.checka } 978 | { organization publisher new.sentence.checkb 979 | organization output 980 | } 981 | if$ 982 | publisher output 983 | format.date "year" output.check 984 | } 985 | { new.sentence 986 | editor empty$ 987 | 'skip$ 988 | { organization output } 989 | if$ 990 | publisher output 991 | address output.nonnull 992 | format.date "year" output.check 993 | } 994 | if$ 995 | new.block 996 | note output 997 | fin.entry 998 | } 999 | 1000 | FUNCTION {techreport} 1001 | { output.bibitem 1002 | format.authors "author" output.check 1003 | new.block 1004 | format.title "title" output.check 1005 | new.block 1006 | format.tr.number output.nonnull 1007 | institution "institution" output.check 1008 | address output 1009 | format.date "year" output.check 1010 | new.block 1011 | note output 1012 | fin.entry 1013 | } 1014 | 1015 | FUNCTION {unpublished} 1016 | { output.bibitem 1017 | format.authors "author" output.check 1018 | new.block 1019 | format.title "title" output.check 1020 | new.block 1021 | note "note" output.check 1022 | format.date output 1023 | fin.entry 1024 | } 1025 | 1026 | FUNCTION {default.type} { misc } 1027 | 1028 | MACRO {jan} {"Jan."} 1029 | 1030 | MACRO {feb} {"Feb."} 1031 | 1032 | MACRO {mar} {"Mar."} 1033 | 1034 | MACRO {apr} {"Apr."} 1035 | 1036 | MACRO {may} {"May"} 1037 | 1038 | MACRO {jun} {"June"} 1039 | 1040 | MACRO {jul} {"July"} 1041 | 1042 | MACRO {aug} {"Aug."} 1043 | 1044 | MACRO {sep} {"Sept."} 1045 | 1046 | MACRO {oct} {"Oct."} 1047 | 1048 | MACRO {nov} {"Nov."} 1049 | 1050 | MACRO {dec} {"Dec."} 1051 | 1052 | MACRO {acmcs} {"ACM Comput. Surv."} 1053 | 1054 | MACRO {acta} {"Acta Inf."} 1055 | 1056 | MACRO {cacm} {"Commun. ACM"} 1057 | 1058 | MACRO {ibmjrd} {"IBM J. Res. Dev."} 1059 | 1060 | MACRO {ibmsj} {"IBM Syst.~J."} 1061 | 1062 | MACRO {ieeese} {"IEEE Trans. Softw. Eng."} 1063 | 1064 | MACRO {ieeetc} {"IEEE Trans. Comput."} 1065 | 1066 | MACRO {ieeetcad} 1067 | {"IEEE Trans. Comput.-Aided Design Integrated Circuits"} 1068 | 1069 | MACRO {ipl} {"Inf. Process. Lett."} 1070 | 1071 | MACRO {jacm} {"J.~ACM"} 1072 | 1073 | MACRO {jcss} {"J.~Comput. Syst. Sci."} 1074 | 1075 | MACRO {scp} {"Sci. Comput. Programming"} 1076 | 1077 | MACRO {sicomp} {"SIAM J. Comput."} 1078 | 1079 | MACRO {tocs} {"ACM Trans. Comput. Syst."} 1080 | 1081 | MACRO {tods} {"ACM Trans. Database Syst."} 1082 | 1083 | MACRO {tog} {"ACM Trans. Gr."} 1084 | 1085 | MACRO {toms} {"ACM Trans. Math. Softw."} 1086 | 1087 | MACRO {toois} {"ACM Trans. Office Inf. Syst."} 1088 | 1089 | MACRO {toplas} {"ACM Trans. Prog. Lang. Syst."} 1090 | 1091 | MACRO {tcs} {"Theoretical Comput. Sci."} 1092 | 1093 | READ 1094 | 1095 | FUNCTION {sortify} 1096 | { purify$ 1097 | "l" change.case$ 1098 | } 1099 | 1100 | INTEGERS { len } 1101 | 1102 | FUNCTION {chop.word} 1103 | { 's := 1104 | 'len := 1105 | s #1 len substring$ = 1106 | { s len #1 + global.max$ substring$ } 1107 | 's 1108 | if$ 1109 | } 1110 | 1111 | FUNCTION {sort.format.names} 1112 | { 's := 1113 | #1 'nameptr := 1114 | "" 1115 | s num.names$ 'numnames := 1116 | numnames 'namesleft := 1117 | { namesleft #0 > } 1118 | { nameptr #1 > 1119 | { " " * } 1120 | 'skip$ 1121 | if$ 1122 | s nameptr "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" format.name$ 't := 1123 | nameptr numnames = t "others" = and 1124 | { "et al" * } 1125 | { t sortify * } 1126 | if$ 1127 | nameptr #1 + 'nameptr := 1128 | namesleft #1 - 'namesleft := 1129 | } 1130 | while$ 1131 | } 1132 | 1133 | FUNCTION {sort.format.title} 1134 | { 't := 1135 | "A " #2 1136 | "An " #3 1137 | "The " #4 t chop.word 1138 | chop.word 1139 | chop.word 1140 | sortify 1141 | #1 global.max$ substring$ 1142 | } 1143 | 1144 | FUNCTION {author.sort} 1145 | { author empty$ 1146 | { key empty$ 1147 | { "to sort, need author or key in " cite$ * warning$ 1148 | "" 1149 | } 1150 | { key sortify } 1151 | if$ 1152 | } 1153 | { author sort.format.names } 1154 | if$ 1155 | } 1156 | 1157 | FUNCTION {author.editor.sort} 1158 | { author empty$ 1159 | { editor empty$ 1160 | { key empty$ 1161 | { "to sort, need author, editor, or key in " cite$ * warning$ 1162 | "" 1163 | } 1164 | { key sortify } 1165 | if$ 1166 | } 1167 | { editor sort.format.names } 1168 | if$ 1169 | } 1170 | { author sort.format.names } 1171 | if$ 1172 | } 1173 | 1174 | FUNCTION {author.organization.sort} 1175 | { author empty$ 1176 | { organization empty$ 1177 | { key empty$ 1178 | { "to sort, need author, organization, or key in " cite$ * warning$ 1179 | "" 1180 | } 1181 | { key sortify } 1182 | if$ 1183 | } 1184 | { "The " #4 organization chop.word sortify } 1185 | if$ 1186 | } 1187 | { author sort.format.names } 1188 | if$ 1189 | } 1190 | 1191 | FUNCTION {editor.organization.sort} 1192 | { editor empty$ 1193 | { organization empty$ 1194 | { key empty$ 1195 | { "to sort, need editor, organization, or key in " cite$ * warning$ 1196 | "" 1197 | } 1198 | { key sortify } 1199 | if$ 1200 | } 1201 | { "The " #4 organization chop.word sortify } 1202 | if$ 1203 | } 1204 | { editor sort.format.names } 1205 | if$ 1206 | } 1207 | 1208 | FUNCTION {presort} 1209 | { type$ "book" = 1210 | type$ "inbook" = 1211 | or 1212 | 'author.editor.sort 1213 | { type$ "proceedings" = 1214 | 'editor.organization.sort 1215 | { type$ "manual" = 1216 | 'author.organization.sort 1217 | 'author.sort 1218 | if$ 1219 | } 1220 | if$ 1221 | } 1222 | if$ 1223 | " " 1224 | * 1225 | year field.or.null sortify 1226 | * 1227 | " " 1228 | * 1229 | title field.or.null 1230 | sort.format.title 1231 | * 1232 | #1 entry.max$ substring$ 1233 | 'sort.key$ := 1234 | } 1235 | 1236 | ITERATE {presort} 1237 | 1238 | SORT 1239 | 1240 | STRINGS { longest.label } 1241 | 1242 | INTEGERS { number.label longest.label.width } 1243 | 1244 | FUNCTION {initialize.longest.label} 1245 | { "" 'longest.label := 1246 | #1 'number.label := 1247 | #0 'longest.label.width := 1248 | } 1249 | 1250 | FUNCTION {longest.label.pass} 1251 | { number.label int.to.str$ 'label := 1252 | number.label #1 + 'number.label := 1253 | label width$ longest.label.width > 1254 | { label 'longest.label := 1255 | label width$ 'longest.label.width := 1256 | } 1257 | 'skip$ 1258 | if$ 1259 | } 1260 | 1261 | EXECUTE {initialize.longest.label} 1262 | 1263 | ITERATE {longest.label.pass} 1264 | 1265 | FUNCTION {begin.bib} 1266 | { preamble$ empty$ 1267 | 'skip$ 1268 | { preamble$ write$ newline$ } 1269 | if$ 1270 | "\begin{thebibliography}{" longest.label * "}" * write$ newline$ 1271 | % "\renewcommand*{\sfdefault}{PTSansNarrow-TLF}" write$ newline$ 1272 | } 1273 | 1274 | EXECUTE {begin.bib} 1275 | 1276 | EXECUTE {init.state.consts} 1277 | 1278 | ITERATE {call.type$} 1279 | 1280 | FUNCTION {end.bib} 1281 | { newline$ 1282 | "\end{thebibliography}" write$ newline$ 1283 | } 1284 | 1285 | EXECUTE {end.bib} 1286 | -------------------------------------------------------------------------------- /abbrv-doi.bst: -------------------------------------------------------------------------------- 1 | % BibTeX standard bibliography style `abbrv' 2 | % version 0.99a for BibTeX versions 0.99a or later, LaTeX version 2.09. 3 | % Copyright (C) 1985, all rights reserved. 4 | % Copying of this file is authorized only if either 5 | % (1) you make absolutely no changes to your copy, including name, or 6 | % (2) if you do make changes, you name it something other than 7 | % btxbst.doc, plain.bst, unsrt.bst, alpha.bst, and abbrv.bst. 8 | % This restriction helps ensure that all standard styles are identical. 9 | % The file btxbst.doc has the documentation for this style. 10 | 11 | ENTRY 12 | { address 13 | author 14 | booktitle 15 | chapter 16 | edition 17 | editor 18 | howpublished 19 | institution 20 | journal 21 | key 22 | month 23 | note 24 | number 25 | organization 26 | pages 27 | publisher 28 | school 29 | series 30 | title 31 | type 32 | volume 33 | year 34 | url 35 | url2 36 | doi 37 | pdf 38 | postscript 39 | } 40 | {} 41 | { label } 42 | 43 | INTEGERS { output.state before.all mid.sentence after.sentence after.block } 44 | 45 | FUNCTION {init.state.consts} 46 | { #0 'before.all := 47 | #1 'mid.sentence := 48 | #2 'after.sentence := 49 | #3 'after.block := 50 | } 51 | 52 | STRINGS { s t } 53 | 54 | FUNCTION {add.link} % title 55 | { 56 | 't := 57 | t empty$ 58 | { "" } 59 | { doi empty$ 60 | { url empty$ 61 | { pdf empty$ 62 | { postscript empty$ 63 | { url2 empty$ 64 | { t } 65 | { "\href{" url2 * "}{" * t * "}" * } 66 | if$ } 67 | { "\href{" postscript * "}{" * t * "}" * } 68 | if$ } 69 | { "\href{" pdf * "}{" * t * "}" * } 70 | if$ } 71 | { "\href{" url * "}{" * t * "}" * } 72 | if$ } 73 | { 74 | doi #1 #7 substring$ "http://" = 75 | { "\href{" doi * "}{" * t * "}" * } 76 | { "\href{http://dx.doi.org/" doi * "}{" * t * "}" * } 77 | if$ 78 | } 79 | if$ } 80 | if$ 81 | } 82 | 83 | FUNCTION {output.nonnull} 84 | { 's := 85 | output.state mid.sentence = 86 | { ", " * write$ } 87 | { output.state after.block = 88 | { add.period$ write$ 89 | newline$ 90 | "\newblock " write$ 91 | } 92 | { output.state before.all = 93 | 'write$ 94 | { add.period$ " " * write$ } 95 | if$ 96 | } 97 | if$ 98 | mid.sentence 'output.state := 99 | } 100 | if$ 101 | s 102 | %add.link 103 | } 104 | 105 | FUNCTION {output} 106 | { duplicate$ empty$ 107 | 'pop$ 108 | 'output.nonnull 109 | if$ 110 | } 111 | 112 | FUNCTION {output.check} 113 | { 't := 114 | duplicate$ empty$ 115 | { pop$ "empty " t * " in " * cite$ * warning$ } 116 | 'output.nonnull 117 | if$ 118 | } 119 | 120 | FUNCTION {output.bibitem} 121 | { newline$ 122 | "\bibitem{" write$ 123 | cite$ write$ 124 | "}" write$ 125 | newline$ 126 | "" 127 | before.all 'output.state := 128 | } 129 | 130 | STRINGS { d dc pc.str doi.urlstr } 131 | 132 | INTEGERS { nth.dash doi.string.pos doilen } 133 | 134 | FUNCTION {add.doi} 135 | { doi empty$ 136 | { } 137 | { 138 | "\%" #2 #1 substring$ 'pc.str := 139 | doi 'd := 140 | "" 'doi.urlstr := 141 | #0 'nth.dash := 142 | #1 'doi.string.pos := 143 | %% find the url part of the doi 144 | d text.length$ 'doilen := 145 | { nth.dash #3 < } 146 | { 147 | d doi.string.pos #1 substring$ 'dc := 148 | #1 doi.string.pos + 'doi.string.pos := 149 | 150 | dc "/" = 151 | { #1 nth.dash + 'nth.dash := } 152 | {} 153 | if$ 154 | % in case the doi didn't have the http... part 155 | doi.string.pos doilen = 156 | { 157 | #3 'nth.dash := 158 | #1 'doi.string.pos := 159 | "https://dx.doi.org/" 'doi.urlstr := 160 | } 161 | {} 162 | if$ 163 | } 164 | while$ 165 | % check for case with more than one dash in doi part but without doi given (was truncated before) 166 | % in that case the doi.string.pos should not be at the start (!= #1), i.e., truncated 167 | % and the beginning of the whole string should be != http, i.e., the actual doi started at the beginning 168 | doi.string.pos #1 = 169 | {} 170 | { 171 | d #1 #4 substring$ "http" = 172 | {} 173 | { 174 | #1 'doi.string.pos := 175 | "https://dx.doi.org/" 'doi.urlstr := 176 | } 177 | if$ 178 | } 179 | if$ 180 | % actually remove the url part of the doi 181 | d text.length$ 'doilen := 182 | doilen doi.string.pos - #1 + 'doilen := 183 | d doi.string.pos doilen substring$ 'd := 184 | 185 | %" \href{" doi.urlstr * doi * "}" * write$ 186 | %newline$ 187 | % uses \usepackage{microtype} for \textls and \usepackage{PTSansNarrow} for \textsf 188 | % notice the additional \hspace calls in the replacement of "." 189 | " doi: {{" pc.str * write$ 190 | %"{doi\raisebox{0.5pt}{\textgreater} \textls[0]{\textsf{" pc.str * write$ 191 | newline$ 192 | 193 | % figure out slash hyphenation 194 | #1 'doi.string.pos := 195 | { doi.string.pos d text.length$ < } 196 | { 197 | d doi.string.pos #1 substring$ 'dc := 198 | #1 doi.string.pos + 'doi.string.pos := 199 | 200 | dc "/" = 201 | { "\discretionary{/}{" pc.str * write$ 202 | newline$ 203 | "}{/}" write$ 204 | } 205 | { 206 | dc "." = 207 | { "\hspace{.1pt}\discretionary{.}{" pc.str * write$ 208 | newline$ 209 | "}{.}\hspace{.4pt}" write$ 210 | } 211 | { 212 | dc "_" = 213 | { "\_" write$ } 214 | { 215 | dc "<" = 216 | { "{\textless}" write$ } 217 | { 218 | dc ">" = 219 | { "{\textgreater}" write$ } 220 | { 221 | dc "-" = 222 | { "\discretionary{" pc.str * write$ 223 | newline$ 224 | "}{-}{-}" write$ 225 | } 226 | { 227 | dc "(" = 228 | { "\discretionary{" pc.str * write$ 229 | newline$ 230 | "}{(}{(}" write$ 231 | } 232 | { 233 | dc ")" = 234 | { "\discretionary{)}{" pc.str * write$ 235 | newline$ 236 | "}{)}" write$ 237 | } 238 | { 239 | dc ":" = 240 | { "\discretionary{:}{" pc.str * write$ 241 | newline$ 242 | "}{:}" write$ 243 | } 244 | { 245 | dc ";" = 246 | { "\discretionary{;}{" pc.str * write$ 247 | newline$ 248 | "}{;}" write$ 249 | } 250 | { dc write$ } 251 | if$ 252 | } 253 | if$ 254 | } 255 | if$ 256 | } 257 | if$ 258 | } 259 | if$ 260 | } 261 | if$ 262 | } 263 | if$ 264 | } 265 | if$ 266 | } 267 | if$ 268 | } 269 | if$ 270 | } 271 | while$ 272 | d doi.string.pos #1 substring$ 'dc := 273 | dc "}}" * write$ 274 | newline$ 275 | } 276 | if$ 277 | } 278 | 279 | FUNCTION {fin.entry} 280 | { add.period$ 281 | write$ 282 | add.doi 283 | newline$ 284 | } 285 | 286 | FUNCTION {new.block} 287 | { output.state before.all = 288 | 'skip$ 289 | { after.block 'output.state := } 290 | if$ 291 | } 292 | 293 | FUNCTION {new.sentence} 294 | { output.state after.block = 295 | 'skip$ 296 | { output.state before.all = 297 | 'skip$ 298 | { after.sentence 'output.state := } 299 | if$ 300 | } 301 | if$ 302 | } 303 | 304 | FUNCTION {not} 305 | { { #0 } 306 | { #1 } 307 | if$ 308 | } 309 | 310 | FUNCTION {and} 311 | { 'skip$ 312 | { pop$ #0 } 313 | if$ 314 | } 315 | 316 | FUNCTION {or} 317 | { { pop$ #1 } 318 | 'skip$ 319 | if$ 320 | } 321 | 322 | FUNCTION {new.block.checka} 323 | { empty$ 324 | 'skip$ 325 | 'new.block 326 | if$ 327 | } 328 | 329 | FUNCTION {new.block.checkb} 330 | { empty$ 331 | swap$ empty$ 332 | and 333 | 'skip$ 334 | 'new.block 335 | if$ 336 | } 337 | 338 | FUNCTION {new.sentence.checka} 339 | { empty$ 340 | 'skip$ 341 | 'new.sentence 342 | if$ 343 | } 344 | 345 | FUNCTION {new.sentence.checkb} 346 | { empty$ 347 | swap$ empty$ 348 | and 349 | 'skip$ 350 | 'new.sentence 351 | if$ 352 | } 353 | 354 | FUNCTION {field.or.null} 355 | { duplicate$ empty$ 356 | { pop$ "" } 357 | 'skip$ 358 | if$ 359 | } 360 | 361 | FUNCTION {emphasize} 362 | { duplicate$ empty$ 363 | { pop$ "" } 364 | { "{\em " swap$ * "}" * } 365 | if$ 366 | } 367 | 368 | INTEGERS { nameptr namesleft numnames } 369 | 370 | FUNCTION {format.names} 371 | { 's := 372 | #1 'nameptr := 373 | s num.names$ 'numnames := 374 | numnames 'namesleft := 375 | { namesleft #0 > } 376 | { s nameptr "{f.~}{vv~}{ll}{, jj}" format.name$ 't := 377 | nameptr #1 > 378 | { namesleft #1 > 379 | { ", " * t * } 380 | { numnames #2 > 381 | { "," * } 382 | 'skip$ 383 | if$ 384 | t "others" = 385 | { " et~al." * } 386 | { " and " * t * } 387 | if$ 388 | } 389 | if$ 390 | } 391 | 't 392 | if$ 393 | nameptr #1 + 'nameptr := 394 | namesleft #1 - 'namesleft := 395 | } 396 | while$ 397 | } 398 | 399 | FUNCTION {format.authors} 400 | { author empty$ 401 | { "" } 402 | { author format.names } 403 | if$ 404 | } 405 | 406 | FUNCTION {format.editors} 407 | { editor empty$ 408 | { "" } 409 | { editor format.names 410 | editor num.names$ #1 > 411 | { ", eds." * } 412 | { ", ed." * } 413 | if$ 414 | } 415 | if$ 416 | } 417 | 418 | FUNCTION {format.title} 419 | { title empty$ 420 | { "" } 421 | { title "t" change.case$ } 422 | if$ 423 | %add.link 424 | } 425 | 426 | FUNCTION {n.dashify} 427 | { 't := 428 | "" 429 | { t empty$ not } 430 | { t #1 #1 substring$ "-" = 431 | { t #1 #2 substring$ "--" = not 432 | { "--" * 433 | t #2 global.max$ substring$ 't := 434 | } 435 | { { t #1 #1 substring$ "-" = } 436 | { "-" * 437 | t #2 global.max$ substring$ 't := 438 | } 439 | while$ 440 | } 441 | if$ 442 | } 443 | { t #1 #1 substring$ * 444 | t #2 global.max$ substring$ 't := 445 | } 446 | if$ 447 | } 448 | while$ 449 | } 450 | 451 | FUNCTION {format.date} 452 | { year empty$ 453 | { month empty$ 454 | { "" } 455 | { "there's a month but no year in " cite$ * warning$ 456 | month 457 | } 458 | if$ 459 | } 460 | { month empty$ 461 | 'year 462 | { month " " * year * } 463 | if$ 464 | } 465 | if$ 466 | } 467 | 468 | FUNCTION {format.btitle} 469 | { title emphasize 470 | %add.link 471 | } 472 | 473 | FUNCTION {tie.or.space.connect} 474 | { duplicate$ text.length$ #3 < 475 | { "~" } 476 | { " " } 477 | if$ 478 | swap$ * * 479 | } 480 | 481 | FUNCTION {either.or.check} 482 | { empty$ 483 | 'pop$ 484 | { "can't use both " swap$ * " fields in " * cite$ * warning$ } 485 | if$ 486 | } 487 | 488 | FUNCTION {format.bvolume} 489 | { volume empty$ 490 | { "" } 491 | { "vol." volume tie.or.space.connect 492 | series empty$ 493 | 'skip$ 494 | { " of " * series emphasize * } 495 | if$ 496 | "volume and number" number either.or.check 497 | } 498 | if$ 499 | } 500 | 501 | FUNCTION {format.number.series} 502 | { volume empty$ 503 | { number empty$ 504 | { series field.or.null } 505 | { output.state mid.sentence = 506 | { "number" } 507 | { "Number" } 508 | if$ 509 | number tie.or.space.connect 510 | series empty$ 511 | { "there's a number but no series in " cite$ * warning$ } 512 | { " in " * series * } 513 | if$ 514 | } 515 | if$ 516 | } 517 | { "" } 518 | if$ 519 | } 520 | 521 | FUNCTION {format.edition} 522 | { edition empty$ 523 | { "" } 524 | { output.state mid.sentence = 525 | { edition "l" change.case$ " ed." * } 526 | { edition "t" change.case$ " ed." * } 527 | if$ 528 | } 529 | if$ 530 | } 531 | 532 | INTEGERS { multiresult } 533 | 534 | FUNCTION {multi.page.check} 535 | { 't := 536 | #0 'multiresult := 537 | { multiresult not 538 | t empty$ not 539 | and 540 | } 541 | { t #1 #1 substring$ 542 | duplicate$ "-" = 543 | swap$ duplicate$ "," = 544 | swap$ "+" = 545 | or or 546 | { #1 'multiresult := } 547 | { t #2 global.max$ substring$ 't := } 548 | if$ 549 | } 550 | while$ 551 | multiresult 552 | } 553 | 554 | FUNCTION {format.pages} 555 | { pages empty$ 556 | { "" } 557 | { pages multi.page.check 558 | { "pp." pages n.dashify tie.or.space.connect } 559 | { "p." pages tie.or.space.connect } 560 | if$ 561 | } 562 | if$ 563 | } 564 | 565 | FUNCTION {format.vol.num.pages} 566 | { volume field.or.null 567 | number empty$ 568 | 'skip$ 569 | { "(" number * ")" * * 570 | volume empty$ 571 | { "there's a number but no volume in " cite$ * warning$ } 572 | 'skip$ 573 | if$ 574 | } 575 | if$ 576 | pages empty$ 577 | 'skip$ 578 | { duplicate$ empty$ 579 | { pop$ format.pages } 580 | { ":" * pages n.dashify * } 581 | if$ 582 | } 583 | if$ 584 | } 585 | 586 | FUNCTION {format.chapter.pages} 587 | { chapter empty$ 588 | 'format.pages 589 | { type empty$ 590 | { "chap." } 591 | { type "l" change.case$ } 592 | if$ 593 | chapter tie.or.space.connect 594 | pages empty$ 595 | 'skip$ 596 | { ", " * format.pages * } 597 | if$ 598 | } 599 | if$ 600 | } 601 | 602 | FUNCTION {format.in.ed.booktitle} 603 | { booktitle empty$ 604 | { "" } 605 | { editor empty$ 606 | { "In " booktitle emphasize * } 607 | { "In " format.editors * ", " * booktitle emphasize * } 608 | if$ 609 | } 610 | if$ 611 | } 612 | 613 | FUNCTION {empty.misc.check} 614 | { author empty$ title empty$ howpublished empty$ 615 | month empty$ year empty$ note empty$ 616 | and and and and and 617 | key empty$ not and 618 | { "all relevant fields are empty in " cite$ * warning$ } 619 | 'skip$ 620 | if$ 621 | } 622 | 623 | FUNCTION {format.thesis.type} 624 | { type empty$ 625 | 'skip$ 626 | { pop$ 627 | type "t" change.case$ 628 | } 629 | if$ 630 | } 631 | 632 | FUNCTION {format.tr.number} 633 | { type empty$ 634 | { "Technical Report" } 635 | 'type 636 | if$ 637 | number empty$ 638 | { "t" change.case$ } 639 | { number tie.or.space.connect } 640 | if$ 641 | } 642 | 643 | FUNCTION {format.article.crossref} 644 | { key empty$ 645 | { journal empty$ 646 | { "need key or journal for " cite$ * " to crossref " * crossref * 647 | warning$ 648 | "" 649 | } 650 | { "In {\em " journal * "\/}" * } 651 | if$ 652 | } 653 | { "In " key * } 654 | if$ 655 | " \cite{" * crossref * "}" * 656 | } 657 | 658 | FUNCTION {format.crossref.editor} 659 | { editor #1 "{vv~}{ll}" format.name$ 660 | editor num.names$ duplicate$ 661 | #2 > 662 | { pop$ " et~al." * } 663 | { #2 < 664 | 'skip$ 665 | { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = 666 | { " et~al." * } 667 | { " and " * editor #2 "{vv~}{ll}" format.name$ * } 668 | if$ 669 | } 670 | if$ 671 | } 672 | if$ 673 | } 674 | 675 | FUNCTION {format.book.crossref} 676 | { volume empty$ 677 | { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ 678 | "In " 679 | } 680 | { "Vol." volume tie.or.space.connect 681 | " of " * 682 | } 683 | if$ 684 | editor empty$ 685 | editor field.or.null author field.or.null = 686 | or 687 | { key empty$ 688 | { series empty$ 689 | { "need editor, key, or series for " cite$ * " to crossref " * 690 | crossref * warning$ 691 | "" * 692 | } 693 | { "{\em " * series * "\/}" * } 694 | if$ 695 | } 696 | { key * } 697 | if$ 698 | } 699 | { format.crossref.editor * } 700 | if$ 701 | " \cite{" * crossref * "}" * 702 | } 703 | 704 | FUNCTION {format.incoll.inproc.crossref} 705 | { editor empty$ 706 | editor field.or.null author field.or.null = 707 | or 708 | { key empty$ 709 | { booktitle empty$ 710 | { "need editor, key, or booktitle for " cite$ * " to crossref " * 711 | crossref * warning$ 712 | "" 713 | } 714 | { "In {\em " booktitle * "\/}" * } 715 | if$ 716 | } 717 | { "In " key * } 718 | if$ 719 | } 720 | { "In " format.crossref.editor * } 721 | if$ 722 | " \cite{" * crossref * "}" * 723 | } 724 | 725 | FUNCTION {article} 726 | { output.bibitem 727 | format.authors "author" output.check 728 | new.block 729 | format.title "title" output.check 730 | new.block 731 | crossref missing$ 732 | { journal emphasize "journal" output.check 733 | format.vol.num.pages output 734 | format.date "year" output.check 735 | } 736 | { format.article.crossref output.nonnull 737 | format.pages output 738 | } 739 | if$ 740 | new.block 741 | note output 742 | fin.entry 743 | } 744 | 745 | FUNCTION {book} 746 | { output.bibitem 747 | author empty$ 748 | { format.editors "author and editor" output.check } 749 | { format.authors output.nonnull 750 | crossref missing$ 751 | { "author and editor" editor either.or.check } 752 | 'skip$ 753 | if$ 754 | } 755 | if$ 756 | new.block 757 | format.btitle "title" output.check 758 | crossref missing$ 759 | { format.bvolume output 760 | new.block 761 | format.number.series output 762 | new.sentence 763 | publisher "publisher" output.check 764 | address output 765 | } 766 | { new.block 767 | format.book.crossref output.nonnull 768 | } 769 | if$ 770 | format.edition output 771 | format.date "year" output.check 772 | new.block 773 | note output 774 | fin.entry 775 | } 776 | 777 | FUNCTION {booklet} 778 | { output.bibitem 779 | format.authors output 780 | new.block 781 | format.title "title" output.check 782 | howpublished address new.block.checkb 783 | howpublished output 784 | address output 785 | format.date output 786 | new.block 787 | note output 788 | fin.entry 789 | } 790 | 791 | FUNCTION {inbook} 792 | { output.bibitem 793 | author empty$ 794 | { format.editors "author and editor" output.check } 795 | { format.authors output.nonnull 796 | crossref missing$ 797 | { "author and editor" editor either.or.check } 798 | 'skip$ 799 | if$ 800 | } 801 | if$ 802 | new.block 803 | format.btitle "title" output.check 804 | crossref missing$ 805 | { format.bvolume output 806 | format.chapter.pages "chapter and pages" output.check 807 | new.block 808 | format.number.series output 809 | new.sentence 810 | publisher "publisher" output.check 811 | address output 812 | } 813 | { format.chapter.pages "chapter and pages" output.check 814 | new.block 815 | format.book.crossref output.nonnull 816 | } 817 | if$ 818 | format.edition output 819 | format.date "year" output.check 820 | new.block 821 | note output 822 | fin.entry 823 | } 824 | 825 | FUNCTION {incollection} 826 | { output.bibitem 827 | format.authors "author" output.check 828 | new.block 829 | format.title "title" output.check 830 | new.block 831 | crossref missing$ 832 | { format.in.ed.booktitle "booktitle" output.check 833 | format.bvolume output 834 | format.number.series output 835 | format.chapter.pages output 836 | new.sentence 837 | publisher "publisher" output.check 838 | address output 839 | format.edition output 840 | format.date "year" output.check 841 | } 842 | { format.incoll.inproc.crossref output.nonnull 843 | format.chapter.pages output 844 | } 845 | if$ 846 | new.block 847 | note output 848 | fin.entry 849 | } 850 | 851 | FUNCTION {inproceedings} 852 | { output.bibitem 853 | format.authors "author" output.check 854 | new.block 855 | format.title "title" output.check 856 | new.block 857 | crossref missing$ 858 | { format.in.ed.booktitle "booktitle" output.check 859 | format.bvolume output 860 | format.number.series output 861 | format.pages output 862 | address empty$ 863 | { organization publisher new.sentence.checkb 864 | organization output 865 | publisher output 866 | format.date "year" output.check 867 | } 868 | { new.sentence 869 | organization output 870 | publisher output 871 | address output.nonnull 872 | format.date "year" output.check 873 | } 874 | if$ 875 | } 876 | { format.incoll.inproc.crossref output.nonnull 877 | format.pages output 878 | } 879 | if$ 880 | new.block 881 | note output 882 | fin.entry 883 | } 884 | 885 | FUNCTION {conference} { inproceedings } 886 | 887 | FUNCTION {manual} 888 | { output.bibitem 889 | author empty$ 890 | { organization empty$ 891 | 'skip$ 892 | { organization output.nonnull 893 | address output 894 | } 895 | if$ 896 | } 897 | { format.authors output.nonnull } 898 | if$ 899 | new.block 900 | format.btitle "title" output.check 901 | author empty$ 902 | { organization empty$ 903 | { address new.block.checka 904 | address output 905 | } 906 | 'skip$ 907 | if$ 908 | } 909 | { organization address new.block.checkb 910 | organization output 911 | address output 912 | } 913 | if$ 914 | format.edition output 915 | format.date output 916 | new.block 917 | note output 918 | fin.entry 919 | } 920 | 921 | FUNCTION {mastersthesis} 922 | { output.bibitem 923 | format.authors "author" output.check 924 | new.block 925 | format.title "title" output.check 926 | new.block 927 | "Master's thesis" format.thesis.type output.nonnull 928 | school "school" output.check 929 | address output 930 | format.date "year" output.check 931 | new.block 932 | note output 933 | fin.entry 934 | } 935 | 936 | FUNCTION {misc} 937 | { output.bibitem 938 | format.authors output 939 | title howpublished new.block.checkb 940 | format.title output 941 | howpublished new.block.checka 942 | howpublished output 943 | format.date output 944 | new.block 945 | note output 946 | fin.entry 947 | empty.misc.check 948 | } 949 | 950 | FUNCTION {phdthesis} 951 | { output.bibitem 952 | format.authors "author" output.check 953 | new.block 954 | format.btitle "title" output.check 955 | new.block 956 | "PhD thesis" format.thesis.type output.nonnull 957 | school "school" output.check 958 | address output 959 | format.date "year" output.check 960 | new.block 961 | note output 962 | fin.entry 963 | } 964 | 965 | FUNCTION {proceedings} 966 | { output.bibitem 967 | editor empty$ 968 | { organization output } 969 | { format.editors output.nonnull } 970 | if$ 971 | new.block 972 | format.btitle "title" output.check 973 | format.bvolume output 974 | format.number.series output 975 | address empty$ 976 | { editor empty$ 977 | { publisher new.sentence.checka } 978 | { organization publisher new.sentence.checkb 979 | organization output 980 | } 981 | if$ 982 | publisher output 983 | format.date "year" output.check 984 | } 985 | { new.sentence 986 | editor empty$ 987 | 'skip$ 988 | { organization output } 989 | if$ 990 | publisher output 991 | address output.nonnull 992 | format.date "year" output.check 993 | } 994 | if$ 995 | new.block 996 | note output 997 | fin.entry 998 | } 999 | 1000 | FUNCTION {techreport} 1001 | { output.bibitem 1002 | format.authors "author" output.check 1003 | new.block 1004 | format.title "title" output.check 1005 | new.block 1006 | format.tr.number output.nonnull 1007 | institution "institution" output.check 1008 | address output 1009 | format.date "year" output.check 1010 | new.block 1011 | note output 1012 | fin.entry 1013 | } 1014 | 1015 | FUNCTION {unpublished} 1016 | { output.bibitem 1017 | format.authors "author" output.check 1018 | new.block 1019 | format.title "title" output.check 1020 | new.block 1021 | note "note" output.check 1022 | format.date output 1023 | fin.entry 1024 | } 1025 | 1026 | FUNCTION {default.type} { misc } 1027 | 1028 | MACRO {jan} {"Jan."} 1029 | 1030 | MACRO {feb} {"Feb."} 1031 | 1032 | MACRO {mar} {"Mar."} 1033 | 1034 | MACRO {apr} {"Apr."} 1035 | 1036 | MACRO {may} {"May"} 1037 | 1038 | MACRO {jun} {"June"} 1039 | 1040 | MACRO {jul} {"July"} 1041 | 1042 | MACRO {aug} {"Aug."} 1043 | 1044 | MACRO {sep} {"Sept."} 1045 | 1046 | MACRO {oct} {"Oct."} 1047 | 1048 | MACRO {nov} {"Nov."} 1049 | 1050 | MACRO {dec} {"Dec."} 1051 | 1052 | MACRO {acmcs} {"ACM Comput. Surv."} 1053 | 1054 | MACRO {acta} {"Acta Inf."} 1055 | 1056 | MACRO {cacm} {"Commun. ACM"} 1057 | 1058 | MACRO {ibmjrd} {"IBM J. Res. Dev."} 1059 | 1060 | MACRO {ibmsj} {"IBM Syst.~J."} 1061 | 1062 | MACRO {ieeese} {"IEEE Trans. Softw. Eng."} 1063 | 1064 | MACRO {ieeetc} {"IEEE Trans. Comput."} 1065 | 1066 | MACRO {ieeetcad} 1067 | {"IEEE Trans. Comput.-Aided Design Integrated Circuits"} 1068 | 1069 | MACRO {ipl} {"Inf. Process. Lett."} 1070 | 1071 | MACRO {jacm} {"J.~ACM"} 1072 | 1073 | MACRO {jcss} {"J.~Comput. Syst. Sci."} 1074 | 1075 | MACRO {scp} {"Sci. Comput. Programming"} 1076 | 1077 | MACRO {sicomp} {"SIAM J. Comput."} 1078 | 1079 | MACRO {tocs} {"ACM Trans. Comput. Syst."} 1080 | 1081 | MACRO {tods} {"ACM Trans. Database Syst."} 1082 | 1083 | MACRO {tog} {"ACM Trans. Gr."} 1084 | 1085 | MACRO {toms} {"ACM Trans. Math. Softw."} 1086 | 1087 | MACRO {toois} {"ACM Trans. Office Inf. Syst."} 1088 | 1089 | MACRO {toplas} {"ACM Trans. Prog. Lang. Syst."} 1090 | 1091 | MACRO {tcs} {"Theoretical Comput. Sci."} 1092 | 1093 | READ 1094 | 1095 | FUNCTION {sortify} 1096 | { purify$ 1097 | "l" change.case$ 1098 | } 1099 | 1100 | INTEGERS { len } 1101 | 1102 | FUNCTION {chop.word} 1103 | { 's := 1104 | 'len := 1105 | s #1 len substring$ = 1106 | { s len #1 + global.max$ substring$ } 1107 | 's 1108 | if$ 1109 | } 1110 | 1111 | FUNCTION {sort.format.names} 1112 | { 's := 1113 | #1 'nameptr := 1114 | "" 1115 | s num.names$ 'numnames := 1116 | numnames 'namesleft := 1117 | { namesleft #0 > } 1118 | { nameptr #1 > 1119 | { " " * } 1120 | 'skip$ 1121 | if$ 1122 | s nameptr "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" format.name$ 't := 1123 | nameptr numnames = t "others" = and 1124 | { "et al" * } 1125 | { t sortify * } 1126 | if$ 1127 | nameptr #1 + 'nameptr := 1128 | namesleft #1 - 'namesleft := 1129 | } 1130 | while$ 1131 | } 1132 | 1133 | FUNCTION {sort.format.title} 1134 | { 't := 1135 | "A " #2 1136 | "An " #3 1137 | "The " #4 t chop.word 1138 | chop.word 1139 | chop.word 1140 | sortify 1141 | #1 global.max$ substring$ 1142 | } 1143 | 1144 | FUNCTION {author.sort} 1145 | { author empty$ 1146 | { key empty$ 1147 | { "to sort, need author or key in " cite$ * warning$ 1148 | "" 1149 | } 1150 | { key sortify } 1151 | if$ 1152 | } 1153 | { author sort.format.names } 1154 | if$ 1155 | } 1156 | 1157 | FUNCTION {author.editor.sort} 1158 | { author empty$ 1159 | { editor empty$ 1160 | { key empty$ 1161 | { "to sort, need author, editor, or key in " cite$ * warning$ 1162 | "" 1163 | } 1164 | { key sortify } 1165 | if$ 1166 | } 1167 | { editor sort.format.names } 1168 | if$ 1169 | } 1170 | { author sort.format.names } 1171 | if$ 1172 | } 1173 | 1174 | FUNCTION {author.organization.sort} 1175 | { author empty$ 1176 | { organization empty$ 1177 | { key empty$ 1178 | { "to sort, need author, organization, or key in " cite$ * warning$ 1179 | "" 1180 | } 1181 | { key sortify } 1182 | if$ 1183 | } 1184 | { "The " #4 organization chop.word sortify } 1185 | if$ 1186 | } 1187 | { author sort.format.names } 1188 | if$ 1189 | } 1190 | 1191 | FUNCTION {editor.organization.sort} 1192 | { editor empty$ 1193 | { organization empty$ 1194 | { key empty$ 1195 | { "to sort, need editor, organization, or key in " cite$ * warning$ 1196 | "" 1197 | } 1198 | { key sortify } 1199 | if$ 1200 | } 1201 | { "The " #4 organization chop.word sortify } 1202 | if$ 1203 | } 1204 | { editor sort.format.names } 1205 | if$ 1206 | } 1207 | 1208 | FUNCTION {presort} 1209 | { type$ "book" = 1210 | type$ "inbook" = 1211 | or 1212 | 'author.editor.sort 1213 | { type$ "proceedings" = 1214 | 'editor.organization.sort 1215 | { type$ "manual" = 1216 | 'author.organization.sort 1217 | 'author.sort 1218 | if$ 1219 | } 1220 | if$ 1221 | } 1222 | if$ 1223 | " " 1224 | * 1225 | year field.or.null sortify 1226 | * 1227 | " " 1228 | * 1229 | title field.or.null 1230 | sort.format.title 1231 | * 1232 | #1 entry.max$ substring$ 1233 | 'sort.key$ := 1234 | } 1235 | 1236 | ITERATE {presort} 1237 | 1238 | SORT 1239 | 1240 | STRINGS { longest.label } 1241 | 1242 | INTEGERS { number.label longest.label.width } 1243 | 1244 | FUNCTION {initialize.longest.label} 1245 | { "" 'longest.label := 1246 | #1 'number.label := 1247 | #0 'longest.label.width := 1248 | } 1249 | 1250 | FUNCTION {longest.label.pass} 1251 | { number.label int.to.str$ 'label := 1252 | number.label #1 + 'number.label := 1253 | label width$ longest.label.width > 1254 | { label 'longest.label := 1255 | label width$ 'longest.label.width := 1256 | } 1257 | 'skip$ 1258 | if$ 1259 | } 1260 | 1261 | EXECUTE {initialize.longest.label} 1262 | 1263 | ITERATE {longest.label.pass} 1264 | 1265 | FUNCTION {begin.bib} 1266 | { preamble$ empty$ 1267 | 'skip$ 1268 | { preamble$ write$ newline$ } 1269 | if$ 1270 | "\begin{thebibliography}{" longest.label * "}" * write$ newline$ 1271 | %"\renewcommand*{\sfdefault}{PTSansNarrow-TLF}" write$ newline$ 1272 | } 1273 | 1274 | EXECUTE {begin.bib} 1275 | 1276 | EXECUTE {init.state.consts} 1277 | 1278 | ITERATE {call.type$} 1279 | 1280 | FUNCTION {end.bib} 1281 | { newline$ 1282 | "\end{thebibliography}" write$ newline$ 1283 | } 1284 | 1285 | EXECUTE {end.bib} 1286 | -------------------------------------------------------------------------------- /abbrv-doi-hyperref-narrow.bst: -------------------------------------------------------------------------------- 1 | % BibTeX standard bibliography style `abbrv' 2 | % version 0.99a for BibTeX versions 0.99a or later, LaTeX version 2.09. 3 | % Copyright (C) 1985, all rights reserved. 4 | % Copying of this file is authorized only if either 5 | % (1) you make absolutely no changes to your copy, including name, or 6 | % (2) if you do make changes, you name it something other than 7 | % btxbst.doc, plain.bst, unsrt.bst, alpha.bst, and abbrv.bst. 8 | % This restriction helps ensure that all standard styles are identical. 9 | % The file btxbst.doc has the documentation for this style. 10 | 11 | ENTRY 12 | { address 13 | author 14 | booktitle 15 | chapter 16 | edition 17 | editor 18 | howpublished 19 | institution 20 | journal 21 | key 22 | month 23 | note 24 | number 25 | organization 26 | pages 27 | publisher 28 | school 29 | series 30 | title 31 | type 32 | volume 33 | year 34 | url 35 | url2 36 | doi 37 | pdf 38 | postscript 39 | } 40 | {} 41 | { label } 42 | 43 | INTEGERS { output.state before.all mid.sentence after.sentence after.block } 44 | 45 | FUNCTION {init.state.consts} 46 | { #0 'before.all := 47 | #1 'mid.sentence := 48 | #2 'after.sentence := 49 | #3 'after.block := 50 | } 51 | 52 | STRINGS { s t } 53 | 54 | FUNCTION {add.link} % title 55 | { 56 | 't := 57 | t empty$ 58 | { "" } 59 | { doi empty$ 60 | { url empty$ 61 | { pdf empty$ 62 | { postscript empty$ 63 | { url2 empty$ 64 | { t } 65 | { "\href{" url2 * "}{" * t * "}" * } 66 | if$ } 67 | { "\href{" postscript * "}{" * t * "}" * } 68 | if$ } 69 | { "\href{" pdf * "}{" * t * "}" * } 70 | if$ } 71 | { "\href{" url * "}{" * t * "}" * } 72 | if$ } 73 | { 74 | doi #1 #7 substring$ "http://" = 75 | { "\href{" doi * "}{" * t * "}" * } 76 | { "\href{https://doi.org/" doi * "}{" * t * "}" * } 77 | if$ 78 | } 79 | if$ } 80 | if$ 81 | } 82 | 83 | FUNCTION {output.nonnull} 84 | { 's := 85 | output.state mid.sentence = 86 | { ", " * write$ } 87 | { output.state after.block = 88 | { add.period$ write$ 89 | newline$ 90 | "\newblock " write$ 91 | } 92 | { output.state before.all = 93 | 'write$ 94 | { add.period$ " " * write$ } 95 | if$ 96 | } 97 | if$ 98 | mid.sentence 'output.state := 99 | } 100 | if$ 101 | s 102 | %add.link 103 | } 104 | 105 | FUNCTION {output} 106 | { duplicate$ empty$ 107 | 'pop$ 108 | 'output.nonnull 109 | if$ 110 | } 111 | 112 | FUNCTION {output.check} 113 | { 't := 114 | duplicate$ empty$ 115 | { pop$ "empty " t * " in " * cite$ * warning$ } 116 | 'output.nonnull 117 | if$ 118 | } 119 | 120 | FUNCTION {output.bibitem} 121 | { newline$ 122 | "\bibitem{" write$ 123 | cite$ write$ 124 | "}" write$ 125 | newline$ 126 | "" 127 | before.all 'output.state := 128 | } 129 | 130 | STRINGS { d dc pc.str doi.urlstr } 131 | 132 | INTEGERS { nth.dash doi.string.pos doilen } 133 | 134 | FUNCTION {add.doi} 135 | { doi empty$ 136 | { } 137 | { 138 | "\%" #2 #1 substring$ 'pc.str := 139 | doi 'd := 140 | "" 'doi.urlstr := 141 | #0 'nth.dash := 142 | #1 'doi.string.pos := 143 | %% find the url part of the doi 144 | d text.length$ 'doilen := 145 | { nth.dash #3 < } 146 | { 147 | d doi.string.pos #1 substring$ 'dc := 148 | #1 doi.string.pos + 'doi.string.pos := 149 | 150 | dc "/" = 151 | { #1 nth.dash + 'nth.dash := } 152 | {} 153 | if$ 154 | % in case the doi didn't have the http... part 155 | doi.string.pos doilen = 156 | { 157 | #3 'nth.dash := 158 | #1 'doi.string.pos := 159 | "https://doi.org/" 'doi.urlstr := 160 | } 161 | {} 162 | if$ 163 | } 164 | while$ 165 | % check for case with more than one dash in doi part but without doi given (was truncated before) 166 | % in that case the doi.string.pos should not be at the start (!= #1), i.e., truncated 167 | % and the beginning of the whole string should be != http, i.e., the actual doi started at the beginning 168 | doi.string.pos #1 = 169 | {} 170 | { 171 | d #1 #4 substring$ "http" = 172 | {} 173 | { 174 | #1 'doi.string.pos := 175 | "https://doi.org/" 'doi.urlstr := 176 | } 177 | if$ 178 | } 179 | if$ 180 | % actually remove the url part of the doi 181 | d text.length$ 'doilen := 182 | doilen doi.string.pos - #1 + 'doilen := 183 | d doi.string.pos doilen substring$ 'd := 184 | 185 | " \href{" doi.urlstr * doi * "}" * write$ 186 | newline$ 187 | % uses \usepackage{microtype} for \textls and \usepackage{PTSansNarrow} for \textsf 188 | % notice the additional \hspace calls in the replacement of "." 189 | "{doi: \textsf{" pc.str * write$ 190 | %"{doi: \textls[-45]{\textsf{" pc.str * write$ 191 | %"{doi\raisebox{0.5pt}{\textgreater} \textls[0]{\textsf{" pc.str * write$ 192 | newline$ 193 | 194 | % figure out slash hyphenation 195 | #1 'doi.string.pos := 196 | { doi.string.pos d text.length$ < } 197 | { 198 | d doi.string.pos #1 substring$ 'dc := 199 | #1 doi.string.pos + 'doi.string.pos := 200 | 201 | dc "/" = 202 | { "\discretionary{/}{" pc.str * write$ 203 | newline$ 204 | "}{/}" write$ 205 | } 206 | { 207 | dc "." = 208 | { "\hspace{.1pt}\discretionary{.}{" pc.str * write$ 209 | newline$ 210 | "}{.}\hspace{.4pt}" write$ 211 | } 212 | { 213 | dc "_" = 214 | { "\_" write$ } 215 | { 216 | dc "<" = 217 | { "{\textless}" write$ } 218 | { 219 | dc ">" = 220 | { "{\textgreater}" write$ } 221 | { 222 | dc "-" = 223 | { "\discretionary{" pc.str * write$ 224 | newline$ 225 | "}{-}{-}" write$ 226 | } 227 | { 228 | dc "(" = 229 | { "\discretionary{" pc.str * write$ 230 | newline$ 231 | "}{(}{(}" write$ 232 | } 233 | { 234 | dc ")" = 235 | { "\discretionary{)}{" pc.str * write$ 236 | newline$ 237 | "}{)}" write$ 238 | } 239 | { 240 | dc ":" = 241 | { "\discretionary{:}{" pc.str * write$ 242 | newline$ 243 | "}{:}" write$ 244 | } 245 | { 246 | dc ";" = 247 | { "\discretionary{;}{" pc.str * write$ 248 | newline$ 249 | "}{;}" write$ 250 | } 251 | { dc write$ } 252 | if$ 253 | } 254 | if$ 255 | } 256 | if$ 257 | } 258 | if$ 259 | } 260 | if$ 261 | } 262 | if$ 263 | } 264 | if$ 265 | } 266 | if$ 267 | } 268 | if$ 269 | } 270 | if$ 271 | } 272 | while$ 273 | d doi.string.pos #1 substring$ 'dc := 274 | dc "}}" * write$ 275 | newline$ 276 | } 277 | if$ 278 | } 279 | 280 | FUNCTION {fin.entry} 281 | { add.period$ 282 | write$ 283 | add.doi 284 | newline$ 285 | } 286 | 287 | FUNCTION {new.block} 288 | { output.state before.all = 289 | 'skip$ 290 | { after.block 'output.state := } 291 | if$ 292 | } 293 | 294 | FUNCTION {new.sentence} 295 | { output.state after.block = 296 | 'skip$ 297 | { output.state before.all = 298 | 'skip$ 299 | { after.sentence 'output.state := } 300 | if$ 301 | } 302 | if$ 303 | } 304 | 305 | FUNCTION {not} 306 | { { #0 } 307 | { #1 } 308 | if$ 309 | } 310 | 311 | FUNCTION {and} 312 | { 'skip$ 313 | { pop$ #0 } 314 | if$ 315 | } 316 | 317 | FUNCTION {or} 318 | { { pop$ #1 } 319 | 'skip$ 320 | if$ 321 | } 322 | 323 | FUNCTION {new.block.checka} 324 | { empty$ 325 | 'skip$ 326 | 'new.block 327 | if$ 328 | } 329 | 330 | FUNCTION {new.block.checkb} 331 | { empty$ 332 | swap$ empty$ 333 | and 334 | 'skip$ 335 | 'new.block 336 | if$ 337 | } 338 | 339 | FUNCTION {new.sentence.checka} 340 | { empty$ 341 | 'skip$ 342 | 'new.sentence 343 | if$ 344 | } 345 | 346 | FUNCTION {new.sentence.checkb} 347 | { empty$ 348 | swap$ empty$ 349 | and 350 | 'skip$ 351 | 'new.sentence 352 | if$ 353 | } 354 | 355 | FUNCTION {field.or.null} 356 | { duplicate$ empty$ 357 | { pop$ "" } 358 | 'skip$ 359 | if$ 360 | } 361 | 362 | FUNCTION {emphasize} 363 | { duplicate$ empty$ 364 | { pop$ "" } 365 | { "{\em " swap$ * "}" * } 366 | if$ 367 | } 368 | 369 | INTEGERS { nameptr namesleft numnames } 370 | 371 | FUNCTION {format.names} 372 | { 's := 373 | #1 'nameptr := 374 | s num.names$ 'numnames := 375 | numnames 'namesleft := 376 | { namesleft #0 > } 377 | { s nameptr "{f.~}{vv~}{ll}{, jj}" format.name$ 't := 378 | nameptr #1 > 379 | { namesleft #1 > 380 | { ", " * t * } 381 | { numnames #2 > 382 | { "," * } 383 | 'skip$ 384 | if$ 385 | t "others" = 386 | { " et~al." * } 387 | { " and " * t * } 388 | if$ 389 | } 390 | if$ 391 | } 392 | 't 393 | if$ 394 | nameptr #1 + 'nameptr := 395 | namesleft #1 - 'namesleft := 396 | } 397 | while$ 398 | } 399 | 400 | FUNCTION {format.authors} 401 | { author empty$ 402 | { "" } 403 | { author format.names } 404 | if$ 405 | } 406 | 407 | FUNCTION {format.editors} 408 | { editor empty$ 409 | { "" } 410 | { editor format.names 411 | editor num.names$ #1 > 412 | { ", eds." * } 413 | { ", ed." * } 414 | if$ 415 | } 416 | if$ 417 | } 418 | 419 | FUNCTION {format.title} 420 | { title empty$ 421 | { "" } 422 | { title "t" change.case$ } 423 | if$ 424 | %add.link 425 | } 426 | 427 | FUNCTION {n.dashify} 428 | { 't := 429 | "" 430 | { t empty$ not } 431 | { t #1 #1 substring$ "-" = 432 | { t #1 #2 substring$ "--" = not 433 | { "--" * 434 | t #2 global.max$ substring$ 't := 435 | } 436 | { { t #1 #1 substring$ "-" = } 437 | { "-" * 438 | t #2 global.max$ substring$ 't := 439 | } 440 | while$ 441 | } 442 | if$ 443 | } 444 | { t #1 #1 substring$ * 445 | t #2 global.max$ substring$ 't := 446 | } 447 | if$ 448 | } 449 | while$ 450 | } 451 | 452 | FUNCTION {format.date} 453 | { year empty$ 454 | { month empty$ 455 | { "" } 456 | { "there's a month but no year in " cite$ * warning$ 457 | month 458 | } 459 | if$ 460 | } 461 | { month empty$ 462 | 'year 463 | { month " " * year * } 464 | if$ 465 | } 466 | if$ 467 | } 468 | 469 | FUNCTION {format.btitle} 470 | { title emphasize 471 | %add.link 472 | } 473 | 474 | FUNCTION {tie.or.space.connect} 475 | { duplicate$ text.length$ #3 < 476 | { "~" } 477 | { " " } 478 | if$ 479 | swap$ * * 480 | } 481 | 482 | FUNCTION {either.or.check} 483 | { empty$ 484 | 'pop$ 485 | { "can't use both " swap$ * " fields in " * cite$ * warning$ } 486 | if$ 487 | } 488 | 489 | FUNCTION {format.bvolume} 490 | { volume empty$ 491 | { "" } 492 | { "vol." volume tie.or.space.connect 493 | series empty$ 494 | 'skip$ 495 | { " of " * series emphasize * } 496 | if$ 497 | "volume and number" number either.or.check 498 | } 499 | if$ 500 | } 501 | 502 | FUNCTION {format.number.series} 503 | { volume empty$ 504 | { number empty$ 505 | { series field.or.null } 506 | { output.state mid.sentence = 507 | { "number" } 508 | { "Number" } 509 | if$ 510 | number tie.or.space.connect 511 | series empty$ 512 | { "there's a number but no series in " cite$ * warning$ } 513 | { " in " * series * } 514 | if$ 515 | } 516 | if$ 517 | } 518 | { "" } 519 | if$ 520 | } 521 | 522 | FUNCTION {format.edition} 523 | { edition empty$ 524 | { "" } 525 | { output.state mid.sentence = 526 | { edition "l" change.case$ " ed." * } 527 | { edition "t" change.case$ " ed." * } 528 | if$ 529 | } 530 | if$ 531 | } 532 | 533 | INTEGERS { multiresult } 534 | 535 | FUNCTION {multi.page.check} 536 | { 't := 537 | #0 'multiresult := 538 | { multiresult not 539 | t empty$ not 540 | and 541 | } 542 | { t #1 #1 substring$ 543 | duplicate$ "-" = 544 | swap$ duplicate$ "," = 545 | swap$ "+" = 546 | or or 547 | { #1 'multiresult := } 548 | { t #2 global.max$ substring$ 't := } 549 | if$ 550 | } 551 | while$ 552 | multiresult 553 | } 554 | 555 | FUNCTION {format.pages} 556 | { pages empty$ 557 | { "" } 558 | { pages multi.page.check 559 | { "pp." pages n.dashify tie.or.space.connect } 560 | { "p." pages tie.or.space.connect } 561 | if$ 562 | } 563 | if$ 564 | } 565 | 566 | FUNCTION {format.vol.num.pages} 567 | { volume field.or.null 568 | number empty$ 569 | 'skip$ 570 | { "(" number * ")" * * 571 | volume empty$ 572 | { "there's a number but no volume in " cite$ * warning$ } 573 | 'skip$ 574 | if$ 575 | } 576 | if$ 577 | pages empty$ 578 | 'skip$ 579 | { duplicate$ empty$ 580 | { pop$ format.pages } 581 | { ":" * pages n.dashify * } 582 | if$ 583 | } 584 | if$ 585 | } 586 | 587 | FUNCTION {format.chapter.pages} 588 | { chapter empty$ 589 | 'format.pages 590 | { type empty$ 591 | { "chap." } 592 | { type "l" change.case$ } 593 | if$ 594 | chapter tie.or.space.connect 595 | pages empty$ 596 | 'skip$ 597 | { ", " * format.pages * } 598 | if$ 599 | } 600 | if$ 601 | } 602 | 603 | FUNCTION {format.in.ed.booktitle} 604 | { booktitle empty$ 605 | { "" } 606 | { editor empty$ 607 | { "In " booktitle emphasize * } 608 | { "In " format.editors * ", " * booktitle emphasize * } 609 | if$ 610 | } 611 | if$ 612 | } 613 | 614 | FUNCTION {empty.misc.check} 615 | { author empty$ title empty$ howpublished empty$ 616 | month empty$ year empty$ note empty$ 617 | and and and and and 618 | key empty$ not and 619 | { "all relevant fields are empty in " cite$ * warning$ } 620 | 'skip$ 621 | if$ 622 | } 623 | 624 | FUNCTION {format.thesis.type} 625 | { type empty$ 626 | 'skip$ 627 | { pop$ 628 | type "t" change.case$ 629 | } 630 | if$ 631 | } 632 | 633 | FUNCTION {format.tr.number} 634 | { type empty$ 635 | { "Technical Report" } 636 | 'type 637 | if$ 638 | number empty$ 639 | { "t" change.case$ } 640 | { number tie.or.space.connect } 641 | if$ 642 | } 643 | 644 | FUNCTION {format.article.crossref} 645 | { key empty$ 646 | { journal empty$ 647 | { "need key or journal for " cite$ * " to crossref " * crossref * 648 | warning$ 649 | "" 650 | } 651 | { "In {\em " journal * "\/}" * } 652 | if$ 653 | } 654 | { "In " key * } 655 | if$ 656 | " \cite{" * crossref * "}" * 657 | } 658 | 659 | FUNCTION {format.crossref.editor} 660 | { editor #1 "{vv~}{ll}" format.name$ 661 | editor num.names$ duplicate$ 662 | #2 > 663 | { pop$ " et~al." * } 664 | { #2 < 665 | 'skip$ 666 | { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = 667 | { " et~al." * } 668 | { " and " * editor #2 "{vv~}{ll}" format.name$ * } 669 | if$ 670 | } 671 | if$ 672 | } 673 | if$ 674 | } 675 | 676 | FUNCTION {format.book.crossref} 677 | { volume empty$ 678 | { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ 679 | "In " 680 | } 681 | { "Vol." volume tie.or.space.connect 682 | " of " * 683 | } 684 | if$ 685 | editor empty$ 686 | editor field.or.null author field.or.null = 687 | or 688 | { key empty$ 689 | { series empty$ 690 | { "need editor, key, or series for " cite$ * " to crossref " * 691 | crossref * warning$ 692 | "" * 693 | } 694 | { "{\em " * series * "\/}" * } 695 | if$ 696 | } 697 | { key * } 698 | if$ 699 | } 700 | { format.crossref.editor * } 701 | if$ 702 | " \cite{" * crossref * "}" * 703 | } 704 | 705 | FUNCTION {format.incoll.inproc.crossref} 706 | { editor empty$ 707 | editor field.or.null author field.or.null = 708 | or 709 | { key empty$ 710 | { booktitle empty$ 711 | { "need editor, key, or booktitle for " cite$ * " to crossref " * 712 | crossref * warning$ 713 | "" 714 | } 715 | { "In {\em " booktitle * "\/}" * } 716 | if$ 717 | } 718 | { "In " key * } 719 | if$ 720 | } 721 | { "In " format.crossref.editor * } 722 | if$ 723 | " \cite{" * crossref * "}" * 724 | } 725 | 726 | FUNCTION {article} 727 | { output.bibitem 728 | format.authors "author" output.check 729 | new.block 730 | format.title "title" output.check 731 | new.block 732 | crossref missing$ 733 | { journal emphasize "journal" output.check 734 | format.vol.num.pages output 735 | format.date "year" output.check 736 | } 737 | { format.article.crossref output.nonnull 738 | format.pages output 739 | } 740 | if$ 741 | new.block 742 | note output 743 | fin.entry 744 | } 745 | 746 | FUNCTION {book} 747 | { output.bibitem 748 | author empty$ 749 | { format.editors "author and editor" output.check } 750 | { format.authors output.nonnull 751 | crossref missing$ 752 | { "author and editor" editor either.or.check } 753 | 'skip$ 754 | if$ 755 | } 756 | if$ 757 | new.block 758 | format.btitle "title" output.check 759 | crossref missing$ 760 | { format.bvolume output 761 | new.block 762 | format.number.series output 763 | new.sentence 764 | publisher "publisher" output.check 765 | address output 766 | } 767 | { new.block 768 | format.book.crossref output.nonnull 769 | } 770 | if$ 771 | format.edition output 772 | format.date "year" output.check 773 | new.block 774 | note output 775 | fin.entry 776 | } 777 | 778 | FUNCTION {booklet} 779 | { output.bibitem 780 | format.authors output 781 | new.block 782 | format.title "title" output.check 783 | howpublished address new.block.checkb 784 | howpublished output 785 | address output 786 | format.date output 787 | new.block 788 | note output 789 | fin.entry 790 | } 791 | 792 | FUNCTION {inbook} 793 | { output.bibitem 794 | author empty$ 795 | { format.editors "author and editor" output.check } 796 | { format.authors output.nonnull 797 | crossref missing$ 798 | { "author and editor" editor either.or.check } 799 | 'skip$ 800 | if$ 801 | } 802 | if$ 803 | new.block 804 | format.btitle "title" output.check 805 | crossref missing$ 806 | { format.bvolume output 807 | format.chapter.pages "chapter and pages" output.check 808 | new.block 809 | format.number.series output 810 | new.sentence 811 | publisher "publisher" output.check 812 | address output 813 | } 814 | { format.chapter.pages "chapter and pages" output.check 815 | new.block 816 | format.book.crossref output.nonnull 817 | } 818 | if$ 819 | format.edition output 820 | format.date "year" output.check 821 | new.block 822 | note output 823 | fin.entry 824 | } 825 | 826 | FUNCTION {incollection} 827 | { output.bibitem 828 | format.authors "author" output.check 829 | new.block 830 | format.title "title" output.check 831 | new.block 832 | crossref missing$ 833 | { format.in.ed.booktitle "booktitle" output.check 834 | format.bvolume output 835 | format.number.series output 836 | format.chapter.pages output 837 | new.sentence 838 | publisher "publisher" output.check 839 | address output 840 | format.edition output 841 | format.date "year" output.check 842 | } 843 | { format.incoll.inproc.crossref output.nonnull 844 | format.chapter.pages output 845 | } 846 | if$ 847 | new.block 848 | note output 849 | fin.entry 850 | } 851 | 852 | FUNCTION {inproceedings} 853 | { output.bibitem 854 | format.authors "author" output.check 855 | new.block 856 | format.title "title" output.check 857 | new.block 858 | crossref missing$ 859 | { format.in.ed.booktitle "booktitle" output.check 860 | format.bvolume output 861 | format.number.series output 862 | format.pages output 863 | address empty$ 864 | { organization publisher new.sentence.checkb 865 | organization output 866 | publisher output 867 | format.date "year" output.check 868 | } 869 | { new.sentence 870 | organization output 871 | publisher output 872 | address output.nonnull 873 | format.date "year" output.check 874 | } 875 | if$ 876 | } 877 | { format.incoll.inproc.crossref output.nonnull 878 | format.pages output 879 | } 880 | if$ 881 | new.block 882 | note output 883 | fin.entry 884 | } 885 | 886 | FUNCTION {conference} { inproceedings } 887 | 888 | FUNCTION {manual} 889 | { output.bibitem 890 | author empty$ 891 | { organization empty$ 892 | 'skip$ 893 | { organization output.nonnull 894 | address output 895 | } 896 | if$ 897 | } 898 | { format.authors output.nonnull } 899 | if$ 900 | new.block 901 | format.btitle "title" output.check 902 | author empty$ 903 | { organization empty$ 904 | { address new.block.checka 905 | address output 906 | } 907 | 'skip$ 908 | if$ 909 | } 910 | { organization address new.block.checkb 911 | organization output 912 | address output 913 | } 914 | if$ 915 | format.edition output 916 | format.date output 917 | new.block 918 | note output 919 | fin.entry 920 | } 921 | 922 | FUNCTION {mastersthesis} 923 | { output.bibitem 924 | format.authors "author" output.check 925 | new.block 926 | format.title "title" output.check 927 | new.block 928 | "Master's thesis" format.thesis.type output.nonnull 929 | school "school" output.check 930 | address output 931 | format.date "year" output.check 932 | new.block 933 | note output 934 | fin.entry 935 | } 936 | 937 | FUNCTION {misc} 938 | { output.bibitem 939 | format.authors output 940 | title howpublished new.block.checkb 941 | format.title output 942 | howpublished new.block.checka 943 | howpublished output 944 | format.date output 945 | new.block 946 | note output 947 | fin.entry 948 | empty.misc.check 949 | } 950 | 951 | FUNCTION {phdthesis} 952 | { output.bibitem 953 | format.authors "author" output.check 954 | new.block 955 | format.btitle "title" output.check 956 | new.block 957 | "PhD thesis" format.thesis.type output.nonnull 958 | school "school" output.check 959 | address output 960 | format.date "year" output.check 961 | new.block 962 | note output 963 | fin.entry 964 | } 965 | 966 | FUNCTION {proceedings} 967 | { output.bibitem 968 | editor empty$ 969 | { organization output } 970 | { format.editors output.nonnull } 971 | if$ 972 | new.block 973 | format.btitle "title" output.check 974 | format.bvolume output 975 | format.number.series output 976 | address empty$ 977 | { editor empty$ 978 | { publisher new.sentence.checka } 979 | { organization publisher new.sentence.checkb 980 | organization output 981 | } 982 | if$ 983 | publisher output 984 | format.date "year" output.check 985 | } 986 | { new.sentence 987 | editor empty$ 988 | 'skip$ 989 | { organization output } 990 | if$ 991 | publisher output 992 | address output.nonnull 993 | format.date "year" output.check 994 | } 995 | if$ 996 | new.block 997 | note output 998 | fin.entry 999 | } 1000 | 1001 | FUNCTION {techreport} 1002 | { output.bibitem 1003 | format.authors "author" output.check 1004 | new.block 1005 | format.title "title" output.check 1006 | new.block 1007 | format.tr.number output.nonnull 1008 | institution "institution" output.check 1009 | address output 1010 | format.date "year" output.check 1011 | new.block 1012 | note output 1013 | fin.entry 1014 | } 1015 | 1016 | FUNCTION {unpublished} 1017 | { output.bibitem 1018 | format.authors "author" output.check 1019 | new.block 1020 | format.title "title" output.check 1021 | new.block 1022 | note "note" output.check 1023 | format.date output 1024 | fin.entry 1025 | } 1026 | 1027 | FUNCTION {default.type} { misc } 1028 | 1029 | MACRO {jan} {"Jan."} 1030 | 1031 | MACRO {feb} {"Feb."} 1032 | 1033 | MACRO {mar} {"Mar."} 1034 | 1035 | MACRO {apr} {"Apr."} 1036 | 1037 | MACRO {may} {"May"} 1038 | 1039 | MACRO {jun} {"June"} 1040 | 1041 | MACRO {jul} {"July"} 1042 | 1043 | MACRO {aug} {"Aug."} 1044 | 1045 | MACRO {sep} {"Sept."} 1046 | 1047 | MACRO {oct} {"Oct."} 1048 | 1049 | MACRO {nov} {"Nov."} 1050 | 1051 | MACRO {dec} {"Dec."} 1052 | 1053 | MACRO {acmcs} {"ACM Comput. Surv."} 1054 | 1055 | MACRO {acta} {"Acta Inf."} 1056 | 1057 | MACRO {cacm} {"Commun. ACM"} 1058 | 1059 | MACRO {ibmjrd} {"IBM J. Res. Dev."} 1060 | 1061 | MACRO {ibmsj} {"IBM Syst.~J."} 1062 | 1063 | MACRO {ieeese} {"IEEE Trans. Softw. Eng."} 1064 | 1065 | MACRO {ieeetc} {"IEEE Trans. Comput."} 1066 | 1067 | MACRO {ieeetcad} 1068 | {"IEEE Trans. Comput.-Aided Design Integrated Circuits"} 1069 | 1070 | MACRO {ipl} {"Inf. Process. Lett."} 1071 | 1072 | MACRO {jacm} {"J.~ACM"} 1073 | 1074 | MACRO {jcss} {"J.~Comput. Syst. Sci."} 1075 | 1076 | MACRO {scp} {"Sci. Comput. Programming"} 1077 | 1078 | MACRO {sicomp} {"SIAM J. Comput."} 1079 | 1080 | MACRO {tocs} {"ACM Trans. Comput. Syst."} 1081 | 1082 | MACRO {tods} {"ACM Trans. Database Syst."} 1083 | 1084 | MACRO {tog} {"ACM Trans. Gr."} 1085 | 1086 | MACRO {toms} {"ACM Trans. Math. Softw."} 1087 | 1088 | MACRO {toois} {"ACM Trans. Office Inf. Syst."} 1089 | 1090 | MACRO {toplas} {"ACM Trans. Prog. Lang. Syst."} 1091 | 1092 | MACRO {tcs} {"Theoretical Comput. Sci."} 1093 | 1094 | READ 1095 | 1096 | FUNCTION {sortify} 1097 | { purify$ 1098 | "l" change.case$ 1099 | } 1100 | 1101 | INTEGERS { len } 1102 | 1103 | FUNCTION {chop.word} 1104 | { 's := 1105 | 'len := 1106 | s #1 len substring$ = 1107 | { s len #1 + global.max$ substring$ } 1108 | 's 1109 | if$ 1110 | } 1111 | 1112 | FUNCTION {sort.format.names} 1113 | { 's := 1114 | #1 'nameptr := 1115 | "" 1116 | s num.names$ 'numnames := 1117 | numnames 'namesleft := 1118 | { namesleft #0 > } 1119 | { nameptr #1 > 1120 | { " " * } 1121 | 'skip$ 1122 | if$ 1123 | s nameptr "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" format.name$ 't := 1124 | nameptr numnames = t "others" = and 1125 | { "et al" * } 1126 | { t sortify * } 1127 | if$ 1128 | nameptr #1 + 'nameptr := 1129 | namesleft #1 - 'namesleft := 1130 | } 1131 | while$ 1132 | } 1133 | 1134 | FUNCTION {sort.format.title} 1135 | { 't := 1136 | "A " #2 1137 | "An " #3 1138 | "The " #4 t chop.word 1139 | chop.word 1140 | chop.word 1141 | sortify 1142 | #1 global.max$ substring$ 1143 | } 1144 | 1145 | FUNCTION {author.sort} 1146 | { author empty$ 1147 | { key empty$ 1148 | { "to sort, need author or key in " cite$ * warning$ 1149 | "" 1150 | } 1151 | { key sortify } 1152 | if$ 1153 | } 1154 | { author sort.format.names } 1155 | if$ 1156 | } 1157 | 1158 | FUNCTION {author.editor.sort} 1159 | { author empty$ 1160 | { editor empty$ 1161 | { key empty$ 1162 | { "to sort, need author, editor, or key in " cite$ * warning$ 1163 | "" 1164 | } 1165 | { key sortify } 1166 | if$ 1167 | } 1168 | { editor sort.format.names } 1169 | if$ 1170 | } 1171 | { author sort.format.names } 1172 | if$ 1173 | } 1174 | 1175 | FUNCTION {author.organization.sort} 1176 | { author empty$ 1177 | { organization empty$ 1178 | { key empty$ 1179 | { "to sort, need author, organization, or key in " cite$ * warning$ 1180 | "" 1181 | } 1182 | { key sortify } 1183 | if$ 1184 | } 1185 | { "The " #4 organization chop.word sortify } 1186 | if$ 1187 | } 1188 | { author sort.format.names } 1189 | if$ 1190 | } 1191 | 1192 | FUNCTION {editor.organization.sort} 1193 | { editor empty$ 1194 | { organization empty$ 1195 | { key empty$ 1196 | { "to sort, need editor, organization, or key in " cite$ * warning$ 1197 | "" 1198 | } 1199 | { key sortify } 1200 | if$ 1201 | } 1202 | { "The " #4 organization chop.word sortify } 1203 | if$ 1204 | } 1205 | { editor sort.format.names } 1206 | if$ 1207 | } 1208 | 1209 | FUNCTION {presort} 1210 | { type$ "book" = 1211 | type$ "inbook" = 1212 | or 1213 | 'author.editor.sort 1214 | { type$ "proceedings" = 1215 | 'editor.organization.sort 1216 | { type$ "manual" = 1217 | 'author.organization.sort 1218 | 'author.sort 1219 | if$ 1220 | } 1221 | if$ 1222 | } 1223 | if$ 1224 | " " 1225 | * 1226 | year field.or.null sortify 1227 | * 1228 | " " 1229 | * 1230 | title field.or.null 1231 | sort.format.title 1232 | * 1233 | #1 entry.max$ substring$ 1234 | 'sort.key$ := 1235 | } 1236 | 1237 | ITERATE {presort} 1238 | 1239 | SORT 1240 | 1241 | STRINGS { longest.label } 1242 | 1243 | INTEGERS { number.label longest.label.width } 1244 | 1245 | FUNCTION {initialize.longest.label} 1246 | { "" 'longest.label := 1247 | #1 'number.label := 1248 | #0 'longest.label.width := 1249 | } 1250 | 1251 | FUNCTION {longest.label.pass} 1252 | { number.label int.to.str$ 'label := 1253 | number.label #1 + 'number.label := 1254 | label width$ longest.label.width > 1255 | { label 'longest.label := 1256 | label width$ 'longest.label.width := 1257 | } 1258 | 'skip$ 1259 | if$ 1260 | } 1261 | 1262 | EXECUTE {initialize.longest.label} 1263 | 1264 | ITERATE {longest.label.pass} 1265 | 1266 | FUNCTION {begin.bib} 1267 | { preamble$ empty$ 1268 | 'skip$ 1269 | { preamble$ write$ newline$ } 1270 | if$ 1271 | "\begin{thebibliography}{" longest.label * "}" * write$ newline$ 1272 | "\renewcommand*{\sfdefault}{PTSansNarrow-TLF}" write$ newline$ 1273 | } 1274 | 1275 | EXECUTE {begin.bib} 1276 | 1277 | EXECUTE {init.state.consts} 1278 | 1279 | ITERATE {call.type$} 1280 | 1281 | FUNCTION {end.bib} 1282 | { newline$ 1283 | "\end{thebibliography}" write$ newline$ 1284 | } 1285 | 1286 | EXECUTE {end.bib} 1287 | --------------------------------------------------------------------------------