├── .Rbuildignore ├── .gitignore ├── DESCRIPTION ├── LICENSE ├── LICENSE.md ├── NAMESPACE ├── R └── betterposter.R ├── README.md ├── betterposter.Rproj ├── inst ├── resources │ ├── betterposter.css │ ├── betterposter.html │ └── qrcode.min.js └── rmarkdown │ └── templates │ └── betterposter │ ├── skeleton │ └── skeleton.Rmd │ └── template.yaml └── man ├── figures └── betterposter-example.png └── poster_better.Rd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^LICENSE\.md$ 2 | ^betterposter\.Rproj$ 3 | ^\.Rproj\.user$ 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ---- Default .gitignore From grkmisc ---- 2 | .Rproj.user 3 | .Rhistory 4 | .RData 5 | .DS_Store 6 | 7 | # Directories that start with _ 8 | _*/ 9 | 10 | ## https://github.com/github/gitignore/blob/master/R.gitignore 11 | # History files 12 | .Rhistory 13 | .Rapp.history 14 | 15 | # Session Data files 16 | .RData 17 | 18 | # Example code in package build process 19 | *-Ex.R 20 | 21 | # Output files from R CMD build 22 | /*.tar.gz 23 | 24 | # Output files from R CMD check 25 | /*.Rcheck/ 26 | 27 | # RStudio files 28 | .Rproj.user/ 29 | 30 | # produced vignettes 31 | vignettes/*.html 32 | vignettes/*.pdf 33 | 34 | # OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3 35 | .httr-oauth 36 | 37 | # knitr and R markdown default cache directories 38 | /*_cache/ 39 | /cache/ 40 | 41 | # Temporary files created by R markdown 42 | *.utf8.md 43 | *.knit.md 44 | 45 | # Shiny token, see https://shiny.rstudio.com/articles/shinyapps.html 46 | rsconnect/ 47 | 48 | ## https://github.com/github/gitignore/blob/master/Global/macOS.gitignore 49 | # General 50 | .DS_Store 51 | .AppleDouble 52 | .LSOverride 53 | 54 | # Icon must end with two \r 55 | Icon 56 | 57 | 58 | # Thumbnails 59 | ._* 60 | 61 | # Files that might appear in the root of a volume 62 | .DocumentRevisions-V100 63 | .fseventsd 64 | .Spotlight-V100 65 | .TemporaryItems 66 | .Trashes 67 | .VolumeIcon.icns 68 | .com.apple.timemachine.donotpresent 69 | 70 | # Directories potentially created on remote AFP share 71 | .AppleDB 72 | .AppleDesktop 73 | Network Trash Folder 74 | Temporary Items 75 | .apdisk 76 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: betterposter 2 | Title: A Better Scientific Poster 3 | Version: 0.0.1 4 | Authors@R: 5 | person(given = "Garrick", 6 | family = "Aden-Buie", 7 | role = c("aut", "cre"), 8 | email = "garrick@adenbuie.com") 9 | Description: A better scientific poster using the best markdown 10 | technology available. 11 | License: MIT + file LICENSE 12 | Imports: 13 | htmltools, 14 | pagedown, 15 | utils 16 | Encoding: UTF-8 17 | LazyData: true 18 | Roxygen: list(markdown = TRUE) 19 | RoxygenNote: 6.1.1 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2019 2 | COPYRIGHT HOLDER: Garrick Aden-Buie 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2019 Garrick Aden-Buie 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(poster_better) 4 | export(qrcode_options) 5 | -------------------------------------------------------------------------------- /R/betterposter.R: -------------------------------------------------------------------------------- 1 | #' Create a Better Poster in HTML 2 | #' 3 | #' @return An R Markdown output format. 4 | #' @export 5 | poster_better <- function( 6 | ..., 7 | css = NULL, 8 | height = NULL, 9 | width = NULL, 10 | hero_background = NULL, 11 | hero_color = NULL, 12 | qrcode = NULL, 13 | logo = NULL, 14 | accent_color = NULL, 15 | mathjax = FALSE, 16 | pandoc_args = NULL 17 | ) { 18 | template <- pkg_resource("betterposter.html") 19 | 20 | if (!is.null(qrcode)) { 21 | if (inherits(qrcode, "list")) { 22 | if (!"color_background" %in% names(qrcode) && !is.null(hero_background)) { 23 | qrcode$color_background <- hero_background 24 | } 25 | if (!"color" %in% names(qrcode) && !is.null(hero_color)) { 26 | qrcode$color <- hero_color 27 | } 28 | qrcode <- do.call("qrcode_options", qrcode) 29 | } else if (is.character(qrcode) && length(qrcode) == 1) { 30 | qrcode <- qrcode_options(qrcode, color_background = hero_background) 31 | } 32 | if (!inherits(qrcode, "qrcode")) { 33 | stop("Please use qrcode_options() to set qrcode") 34 | } 35 | } 36 | 37 | pandoc_args <- c(pandoc_args, pandoc_arg(c( 38 | height = if (!is.null(height)) paste0(height, "in"), 39 | width = if (!is.null(width)) paste0(width, "in"), 40 | hero_background = hero_background, 41 | hero_color = hero_color, 42 | logo = logo, 43 | accent_color = accent_color 44 | ))) 45 | 46 | if (mathjax) pandoc_args <- c(pandoc_args, "--mathjax") 47 | 48 | pagedown::poster_relaxed(..., css = css, template = template, 49 | .dependencies = betterposter_dependencies(), 50 | pandoc_args = c(pandoc_args, qrcode), 51 | md_extensions = "-autolink_bare_uris", 52 | number_sections = FALSE) 53 | } 54 | 55 | #' @export 56 | qrcode_options <- function( 57 | text, 58 | color_background = "#00000000", 59 | color = "#FFFFFF", 60 | size = "250", 61 | as_yaml = FALSE 62 | ) { 63 | stopifnot(is.character(text)) 64 | stopifnot(is.character(color_background)) 65 | stopifnot(is.character(color)) 66 | stopifnot(is.character(size)) 67 | 68 | # if color_background is not a hex color then set to inherit 69 | color_background <- trimws(color_background) 70 | if (sub("#[a-fA-F0-9]{4,6}", "", color_background) != "") { 71 | warning("Ignoring non-hex QR code background in `color_background`") 72 | color_background <- "#00000000" 73 | } 74 | 75 | if (as_yaml) { 76 | x <- paste0( 77 | "\nqrcode:", 78 | '\n text: "', text, '"', 79 | '\n color_background: "', color_background, '"', 80 | '\n color: "', color, '"', 81 | '\n size: "', size, '"' 82 | ) 83 | cat(x) 84 | return(invisible(x)) 85 | } 86 | 87 | x <- pandoc_arg(c( 88 | "qrcode_text" = text, 89 | "qrcode_color_background" = color_background, 90 | "qrcode_color" = color, 91 | "qrcode_size" = size 92 | )) 93 | class(x) <- c("qrcode", class(x)) 94 | x 95 | } 96 | 97 | 98 | 99 | # Utils ------------------------------------------------------------------- 100 | pkg_resource = function(...) { 101 | system.file('resources', ..., package = 'betterposter', mustWork = TRUE) 102 | } 103 | 104 | pandoc_arg <- function(values) { 105 | if (is.null(values) || length(values) == 0) return(NULL) 106 | stopifnot(!is.null(names(values))) 107 | ret <- c() 108 | for (name in names(values)) { 109 | ret <- c( 110 | ret, 111 | "--variable", 112 | paste0(name, "=", values[name]) 113 | ) 114 | } 115 | ret 116 | } 117 | 118 | betterposter_dependencies <- function() { 119 | list( 120 | htmltools::htmlDependency( 121 | "betterposter", 122 | packageVersion("betterposter"), 123 | src = pkg_resource(), 124 | stylesheet = "betterposter.css" 125 | ), 126 | htmltools::htmlDependency( 127 | "qrcode", 128 | "0.0.0", 129 | src = pkg_resource(), 130 | script = "qrcode.min.js" 131 | ) 132 | ) 133 | } 134 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # betterposter 2 | 3 | ### Another Better Scientific Poster Using R Markdown and pagedown 4 | 5 | 6 | 7 | 8 | [mikemorrison-betterposter]: https://osf.io/ef53g/ 9 | [posterdown]: https://brentthorne.github.io/posterdown_html_showcase/ 10 | 11 | ⚠️ *This is a work in progress and is not fully documented yet* ⚠️ 12 | 13 | A better scientific poster, inspired by [Mike Morrison's Better Poster Template][mikemorrison-betterposter]. 14 | 15 | ## Installation 16 | 17 | You can install the in-development version of **betterposter** from GitHub with: 18 | 19 | ``` r 20 | # install.packages("devtools") 21 | devtools::install_github("gerkelab/betterposter") 22 | ``` 23 | 24 | ## Usage 25 | 26 | Use `betterposter::poster_better()` to get an awesome poster generated from R Markdown! 27 | 28 | ![](man/figures/betterposter-example.png) 29 | 30 | ## Features 31 | 32 | Like many others, we saw Mike's [How to create a better research poster in less time](https://youtu.be/1RwJbhkCA58) video on Twitter and loved it. Like others, we thought: "let's bring that to R Markdown!". This is our version, but you may want to check out [posterdown] by Brent Thorne, where another version of the Better Scientific Poster can be found (including a portrait version). 33 | 34 | The main features of this implementation are 35 | 36 | 1. The QR Code is fully customizable and generated in the browser (no external API calls!). 37 | Use `qrcode_options()` to set the `qrcode` argument in `poster_better()`. 38 | 39 | 1. Great default typography built using Roboto and Robot slab for highly readable text and headers, with Source Sans Pro for the main hero text and Source Code Pro for source code (naturally). 40 | 41 | 1. Customizable colors via `hero_background`, `hero_color` and `accent_color`. 42 | 43 | 1. All variables for customizing the poster are listed and (will be) documented in `better_poster()`. 44 | -------------------------------------------------------------------------------- /betterposter.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 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: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageRoxygenize: rd,collate,namespace 22 | -------------------------------------------------------------------------------- /inst/resources/betterposter.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Roboto%7CRoboto+Slab:700%7CSource+Code+Pro%7CSource+Sans+Pro:300,700'); 2 | 3 | @page { 4 | width: 46.8in; 5 | height: 33.1in; 6 | margin: 0; 7 | } 8 | html, body { 9 | background: #fff; 10 | } 11 | html { 12 | font-family: "Roboto"; 13 | font-size: 24px; 14 | color: #333; 15 | width: 46.8in; 16 | height: 33.09669in; 17 | } 18 | body { 19 | margin: 0; 20 | width: 46.3in; 21 | height: 32.59669in; 22 | display: grid; 23 | grid-gap: 0.25in; 24 | grid-template-columns: 60px 60px; 25 | padding: 0.25in !important; 26 | } 27 | 28 | /* ---- Grid ---- */ 29 | body { 30 | grid-template-areas: 31 | "T H R" 32 | "L H R" 33 | "L H F"; 34 | grid-template-columns: 1fr 3fr 1fr; 35 | grid-template-rows: 1fr 5fr 1fr; 36 | } 37 | 38 | #hero { 39 | grid-area: H; 40 | } 41 | 42 | #left-bar { 43 | grid-area: L; 44 | } 45 | 46 | #right-bar { 47 | grid-area: R; 48 | } 49 | #title-container { 50 | grid-area: T; 51 | } 52 | #references { 53 | grid-area: F; 54 | } 55 | 56 | img { 57 | max-width: 100%; 58 | } 59 | 60 | /* ---- General ---- */ 61 | h1, h2, h3, h4 { 62 | margin-block-end: 0; 63 | font-family: "Roboto Slab", Arial, sans-serif; 64 | } 65 | p { 66 | margin-block-start: 0.25em; 67 | } 68 | pre, pre.sourceCode { 69 | font-size: 0.8em; 70 | margin: 1em 0; 71 | padding: 0.5em 0.5em; 72 | } 73 | code { 74 | font-family: "Source Code Pro", Monaco, monospace; 75 | } 76 | blockquote { 77 | font-style: italic; 78 | padding-left: 1em; 79 | border-left: 5pt solid #dadada; 80 | margin-left: 0; 81 | } 82 | sup { 83 | font-size: 0.75em; 84 | font-style: normal; 85 | margin-left: 4pt; 86 | } 87 | 88 | /* ---- Hero ---- */ 89 | #hero { 90 | position: relative; 91 | background: #0F5D4F; 92 | color: #fff; 93 | font-family: "Source Sans Pro", "Helvetica Neue", Arial, sans-serif; 94 | padding: 10%; 95 | font-size: 48px; 96 | } 97 | 98 | #hero h1 { 99 | font-family: "Source Sans Pro", "Helvetica Neue", Arial, sans-serif; 100 | font-size: 3.25em; 101 | font-weight: 400; 102 | padding-top: %; 103 | } 104 | 105 | #hero h1 strong { 106 | font-weight: 700; 107 | } 108 | 109 | #hero p { 110 | padding: 10pt 0; 111 | } 112 | 113 | #hero > p:first-of-type { 114 | padding-top: 6em; 115 | } 116 | 117 | #hero img.qrcode { 118 | position: absolute; 119 | bottom: 5%; 120 | } 121 | 122 | #qrcode { 123 | position: absolute; 124 | bottom: 5%; 125 | left: 10%; 126 | } 127 | 128 | /* ---- Social ---- */ 129 | 130 | /* ---- Title ---- */ 131 | #title-container { 132 | padding: 5% 5% 0 5%; 133 | background: none; 134 | } 135 | 136 | #title-container .author, #title-container .affiliation { 137 | color: #888; 138 | font-family: "Roboto", "Helvetica Neue", Arial, sans-serif; 139 | } 140 | #title-container .author { 141 | font-style: italic; 142 | font-size: 1.25em; 143 | } 144 | #title-container .affiliation { 145 | font-weight: normal; 146 | } 147 | 148 | /* ---- Silent Bar (Left Bar) ---- */ 149 | #left-bar { 150 | background: none; 151 | padding: 0 5%; 152 | } 153 | 154 | /* ---- Ammo Bar (Right Bar) ---- */ 155 | #right-bar { 156 | background: #fff; 157 | padding: 5%; 158 | } 159 | 160 | /* ---- References ---- */ 161 | #references { 162 | padding: 0 5%; 163 | } 164 | #references p, #references ul, #references ol { 165 | font-size: 0.6em; 166 | } 167 | 168 | /* ---- Tables ---- */ 169 | table { 170 | border-collapse: collapse; 171 | border-spacing: 0; 172 | text-align: left; 173 | width: 100%; 174 | border: .05rem solid #dadada; 175 | } 176 | table thead { 177 | background: #dadada; 178 | } 179 | table td, 180 | table th { 181 | padding: .1rem .2rem; 182 | font-size: small; 183 | } 184 | 185 | table th { 186 | border-bottom-width: .1rem; 187 | } 188 | -------------------------------------------------------------------------------- /inst/resources/betterposter.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | $for(author-meta)$$endfor$ 10 | $if(date-meta)$$endif$ 11 | $if(title-prefix)$$title-prefix$ - $endif$$pagetitle$ 12 | 13 | $for(header-includes)$ 14 | $header-includes$ 15 | $endfor$ 16 | 17 | $if(highlightjs)$ 18 | 19 | 20 | 21 | $endif$ 22 | 23 | $if(highlighting-css)$$endif$ 24 | 25 | $for(css)$ 26 | 27 | $endfor$ 28 | 29 | 74 | 75 | 76 | 77 | 78 | $for(include-before)$ 79 | $include-before$ 80 | $endfor$ 81 | 82 | $if(title)$ 83 |
84 |

$title$

85 | $if(author)$ 86 |
87 | $for(author)$$author.name$$if(author.affiliation)$$author.affiliation$$endif$$if(author.extra)$ ($for(author.extra)$$author.extra$$sep$, $endfor$)$endif$$sep$, $endfor$ 88 |
89 | $endif$ 90 | $if(affiliation)$ 91 |
92 |
    93 | $for(affiliation)$ 94 |
  1. $affiliation$
  2. 95 | $endfor$ 96 |
97 |
98 | $endif$ 99 |
100 | $endif$ 101 | 102 | $body$ 103 | 104 | 114 | 115 | $if(math)$ 116 | 117 | 129 | $endif$ 130 | 131 | $if(qrcode_text)$ 132 | 149 | $endif$ 150 | 151 | $for(include-after)$ 152 | $include-after$ 153 | $endfor$ 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /inst/resources/qrcode.min.js: -------------------------------------------------------------------------------- 1 | var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this.parsedData=[];for(var b=[],d=0,e=this.data.length;e>d;d++){var f=this.data.charCodeAt(d);f>65536?(b[0]=240|(1835008&f)>>>18,b[1]=128|(258048&f)>>>12,b[2]=128|(4032&f)>>>6,b[3]=128|63&f):f>2048?(b[0]=224|(61440&f)>>>12,b[1]=128|(4032&f)>>>6,b[2]=128|63&f):f>128?(b[0]=192|(1984&f)>>>6,b[1]=128|63&f):b[0]=f,this.parsedData=this.parsedData.concat(b)}this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function b(a,b){this.typeNumber=a,this.errorCorrectLevel=b,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}function i(a,b){if(void 0==a.length)throw new Error(a.length+"/"+b);for(var c=0;c=f;f++){var h=0;switch(b){case d.L:h=l[f][0];break;case d.M:h=l[f][1];break;case d.Q:h=l[f][2];break;case d.H:h=l[f][3]}if(h>=e)break;c++}if(c>l.length)throw new Error("Too long data");return c}function s(a){var b=encodeURI(a).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return b.length+(b.length!=a?3:0)}a.prototype={getLength:function(){return this.parsedData.length},write:function(a){for(var b=0,c=this.parsedData.length;c>b;b++)a.put(this.parsedData[b],8)}},b.prototype={addData:function(b){var c=new a(b);this.dataList.push(c),this.dataCache=null},isDark:function(a,b){if(0>a||this.moduleCount<=a||0>b||this.moduleCount<=b)throw new Error(a+","+b);return this.modules[a][b]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var d=0;d=7&&this.setupTypeNumber(a),null==this.dataCache&&(this.dataCache=b.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,b){for(var c=-1;7>=c;c++)if(!(-1>=a+c||this.moduleCount<=a+c))for(var d=-1;7>=d;d++)-1>=b+d||this.moduleCount<=b+d||(this.modules[a+c][b+d]=c>=0&&6>=c&&(0==d||6==d)||d>=0&&6>=d&&(0==c||6==c)||c>=2&&4>=c&&d>=2&&4>=d?!0:!1)},getBestMaskPattern:function(){for(var a=0,b=0,c=0;8>c;c++){this.makeImpl(!0,c);var d=f.getLostPoint(this);(0==c||a>d)&&(a=d,b=c)}return b},createMovieClip:function(a,b,c){var d=a.createEmptyMovieClip(b,c),e=1;this.make();for(var f=0;f=g;g++)for(var h=-2;2>=h;h++)this.modules[d+g][e+h]=-2==g||2==g||-2==h||2==h||0==g&&0==h?!0:!1}},setupTypeNumber:function(a){for(var b=f.getBCHTypeNumber(this.typeNumber),c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[Math.floor(c/3)][c%3+this.moduleCount-8-3]=d}for(var c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[c%3+this.moduleCount-8-3][Math.floor(c/3)]=d}},setupTypeInfo:function(a,b){for(var c=this.errorCorrectLevel<<3|b,d=f.getBCHTypeInfo(c),e=0;15>e;e++){var g=!a&&1==(1&d>>e);6>e?this.modules[e][8]=g:8>e?this.modules[e+1][8]=g:this.modules[this.moduleCount-15+e][8]=g}for(var e=0;15>e;e++){var g=!a&&1==(1&d>>e);8>e?this.modules[8][this.moduleCount-e-1]=g:9>e?this.modules[8][15-e-1+1]=g:this.modules[8][15-e-1]=g}this.modules[this.moduleCount-8][8]=!a},mapData:function(a,b){for(var c=-1,d=this.moduleCount-1,e=7,g=0,h=this.moduleCount-1;h>0;h-=2)for(6==h&&h--;;){for(var i=0;2>i;i++)if(null==this.modules[d][h-i]){var j=!1;g>>e));var k=f.getMask(b,d,h-i);k&&(j=!j),this.modules[d][h-i]=j,e--,-1==e&&(g++,e=7)}if(d+=c,0>d||this.moduleCount<=d){d-=c,c=-c;break}}}},b.PAD0=236,b.PAD1=17,b.createData=function(a,c,d){for(var e=j.getRSBlocks(a,c),g=new k,h=0;h8*l)throw new Error("code length overflow. ("+g.getLengthInBits()+">"+8*l+")");for(g.getLengthInBits()+4<=8*l&&g.put(0,4);0!=g.getLengthInBits()%8;)g.putBit(!1);for(;;){if(g.getLengthInBits()>=8*l)break;if(g.put(b.PAD0,8),g.getLengthInBits()>=8*l)break;g.put(b.PAD1,8)}return b.createBytes(g,e)},b.createBytes=function(a,b){for(var c=0,d=0,e=0,g=new Array(b.length),h=new Array(b.length),j=0;j=0?p.get(q):0}}for(var r=0,m=0;mm;m++)for(var j=0;jm;m++)for(var j=0;j=0;)b^=f.G15<=0;)b^=f.G18<>>=1;return b},getPatternPosition:function(a){return f.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,b,c){switch(a){case e.PATTERN000:return 0==(b+c)%2;case e.PATTERN001:return 0==b%2;case e.PATTERN010:return 0==c%3;case e.PATTERN011:return 0==(b+c)%3;case e.PATTERN100:return 0==(Math.floor(b/2)+Math.floor(c/3))%2;case e.PATTERN101:return 0==b*c%2+b*c%3;case e.PATTERN110:return 0==(b*c%2+b*c%3)%2;case e.PATTERN111:return 0==(b*c%3+(b+c)%2)%2;default:throw new Error("bad maskPattern:"+a)}},getErrorCorrectPolynomial:function(a){for(var b=new i([1],0),c=0;a>c;c++)b=b.multiply(new i([1,g.gexp(c)],0));return b},getLengthInBits:function(a,b){if(b>=1&&10>b)switch(a){case c.MODE_NUMBER:return 10;case c.MODE_ALPHA_NUM:return 9;case c.MODE_8BIT_BYTE:return 8;case c.MODE_KANJI:return 8;default:throw new Error("mode:"+a)}else if(27>b)switch(a){case c.MODE_NUMBER:return 12;case c.MODE_ALPHA_NUM:return 11;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 10;default:throw new Error("mode:"+a)}else{if(!(41>b))throw new Error("type:"+b);switch(a){case c.MODE_NUMBER:return 14;case c.MODE_ALPHA_NUM:return 13;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 12;default:throw new Error("mode:"+a)}}},getLostPoint:function(a){for(var b=a.getModuleCount(),c=0,d=0;b>d;d++)for(var e=0;b>e;e++){for(var f=0,g=a.isDark(d,e),h=-1;1>=h;h++)if(!(0>d+h||d+h>=b))for(var i=-1;1>=i;i++)0>e+i||e+i>=b||(0!=h||0!=i)&&g==a.isDark(d+h,e+i)&&f++;f>5&&(c+=3+f-5)}for(var d=0;b-1>d;d++)for(var e=0;b-1>e;e++){var j=0;a.isDark(d,e)&&j++,a.isDark(d+1,e)&&j++,a.isDark(d,e+1)&&j++,a.isDark(d+1,e+1)&&j++,(0==j||4==j)&&(c+=3)}for(var d=0;b>d;d++)for(var e=0;b-6>e;e++)a.isDark(d,e)&&!a.isDark(d,e+1)&&a.isDark(d,e+2)&&a.isDark(d,e+3)&&a.isDark(d,e+4)&&!a.isDark(d,e+5)&&a.isDark(d,e+6)&&(c+=40);for(var e=0;b>e;e++)for(var d=0;b-6>d;d++)a.isDark(d,e)&&!a.isDark(d+1,e)&&a.isDark(d+2,e)&&a.isDark(d+3,e)&&a.isDark(d+4,e)&&!a.isDark(d+5,e)&&a.isDark(d+6,e)&&(c+=40);for(var k=0,e=0;b>e;e++)for(var d=0;b>d;d++)a.isDark(d,e)&&k++;var l=Math.abs(100*k/b/b-50)/5;return c+=10*l}},g={glog:function(a){if(1>a)throw new Error("glog("+a+")");return g.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;a>=256;)a-=255;return g.EXP_TABLE[a]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},h=0;8>h;h++)g.EXP_TABLE[h]=1<h;h++)g.EXP_TABLE[h]=g.EXP_TABLE[h-4]^g.EXP_TABLE[h-5]^g.EXP_TABLE[h-6]^g.EXP_TABLE[h-8];for(var h=0;255>h;h++)g.LOG_TABLE[g.EXP_TABLE[h]]=h;i.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var b=new Array(this.getLength()+a.getLength()-1),c=0;cf;f++)for(var g=c[3*f+0],h=c[3*f+1],i=c[3*f+2],k=0;g>k;k++)e.push(new j(h,i));return e},j.getRsBlockTable=function(a,b){switch(b){case d.L:return j.RS_BLOCK_TABLE[4*(a-1)+0];case d.M:return j.RS_BLOCK_TABLE[4*(a-1)+1];case d.Q:return j.RS_BLOCK_TABLE[4*(a-1)+2];case d.H:return j.RS_BLOCK_TABLE[4*(a-1)+3];default:return void 0}},k.prototype={get:function(a){var b=Math.floor(a/8);return 1==(1&this.buffer[b]>>>7-a%8)},put:function(a,b){for(var c=0;b>c;c++)this.putBit(1==(1&a>>>b-c-1))},getLengthInBits:function(){return this.length},putBit:function(a){var b=Math.floor(this.length/8);this.buffer.length<=b&&this.buffer.push(0),a&&(this.buffer[b]|=128>>>this.length%8),this.length++}};var l=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],o=function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){function g(a,b){var c=document.createElementNS("http://www.w3.org/2000/svg",a);for(var d in b)b.hasOwnProperty(d)&&c.setAttribute(d,b[d]);return c}var b=this._htOption,c=this._el,d=a.getModuleCount();Math.floor(b.width/d),Math.floor(b.height/d),this.clear();var h=g("svg",{viewBox:"0 0 "+String(d)+" "+String(d),width:"100%",height:"100%",fill:b.colorLight});h.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),c.appendChild(h),h.appendChild(g("rect",{fill:b.colorDark,width:"1",height:"1",id:"template"}));for(var i=0;d>i;i++)for(var j=0;d>j;j++)if(a.isDark(i,j)){var k=g("use",{x:String(i),y:String(j)});k.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),h.appendChild(k)}},a.prototype.clear=function(){for(;this._el.hasChildNodes();)this._el.removeChild(this._el.lastChild)},a}(),p="svg"===document.documentElement.tagName.toLowerCase(),q=p?o:m()?function(){function a(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}function d(a,b){var c=this;if(c._fFail=b,c._fSuccess=a,null===c._bSupportDataURI){var d=document.createElement("img"),e=function(){c._bSupportDataURI=!1,c._fFail&&_fFail.call(c)},f=function(){c._bSupportDataURI=!0,c._fSuccess&&c._fSuccess.call(c)};return d.onabort=e,d.onerror=e,d.onload=f,d.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}c._bSupportDataURI===!0&&c._fSuccess?c._fSuccess.call(c):c._bSupportDataURI===!1&&c._fFail&&c._fFail.call(c)}if(this._android&&this._android<=2.1){var b=1/window.devicePixelRatio,c=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(a,d,e,f,g,h,i,j){if("nodeName"in a&&/img/i.test(a.nodeName))for(var l=arguments.length-1;l>=1;l--)arguments[l]=arguments[l]*b;else"undefined"==typeof j&&(arguments[1]*=b,arguments[2]*=b,arguments[3]*=b,arguments[4]*=b);c.apply(this,arguments)}}var e=function(a,b){this._bIsPainted=!1,this._android=n(),this._htOption=b,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=b.width,this._elCanvas.height=b.height,a.appendChild(this._elCanvas),this._el=a,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return e.prototype.draw=function(a){var b=this._elImage,c=this._oContext,d=this._htOption,e=a.getModuleCount(),f=d.width/e,g=d.height/e,h=Math.round(f),i=Math.round(g);b.style.display="none",this.clear();for(var j=0;e>j;j++)for(var k=0;e>k;k++){var l=a.isDark(j,k),m=k*f,n=j*g;c.strokeStyle=l?d.colorDark:d.colorLight,c.lineWidth=1,c.fillStyle=l?d.colorDark:d.colorLight,c.fillRect(m,n,f,g),c.strokeRect(Math.floor(m)+.5,Math.floor(n)+.5,h,i),c.strokeRect(Math.ceil(m)-.5,Math.ceil(n)-.5,h,i)}this._bIsPainted=!0},e.prototype.makeImage=function(){this._bIsPainted&&d.call(this,a)},e.prototype.isPainted=function(){return this._bIsPainted},e.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height),this._bIsPainted=!1},e.prototype.round=function(a){return a?Math.floor(1e3*a)/1e3:a},e}():function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){for(var b=this._htOption,c=this._el,d=a.getModuleCount(),e=Math.floor(b.width/d),f=Math.floor(b.height/d),g=[''],h=0;d>h;h++){g.push("");for(var i=0;d>i;i++)g.push('');g.push("")}g.push("
"),c.innerHTML=g.join("");var j=c.childNodes[0],k=(b.width-j.offsetWidth)/2,l=(b.height-j.offsetHeight)/2;k>0&&l>0&&(j.style.margin=l+"px "+k+"px")},a.prototype.clear=function(){this._el.innerHTML=""},a}();QRCode=function(a,b){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:d.H},"string"==typeof b&&(b={text:b}),b)for(var c in b)this._htOption[c]=b[c];"string"==typeof a&&(a=document.getElementById(a)),this._android=n(),this._el=a,this._oQRCode=null,this._oDrawing=new q(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},QRCode.prototype.makeCode=function(a){this._oQRCode=new b(r(a,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(a),this._oQRCode.make(),this._el.title=a,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=d}(); -------------------------------------------------------------------------------- /inst/rmarkdown/templates/betterposter/skeleton/skeleton.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: > 3 | Another Better Scientific Poster Using R Markdown and pagedown 4 | author: 5 | - name: Garrick Aden-Buie 6 | affiliation: 1 7 | extra: 8 | - "garrick@adenbuie.com" 9 | - "@grrrck" 10 | - name: Mike Morrison 11 | affiliation: 2 12 | - name: Brent Thorne 13 | affiliation: 3 14 | - name: Yihui Xie 15 | affiliation: 4 16 | affiliation: 17 | - Gerke Lab, Moffitt Cancer Center, Tampa, FL 18 | - Michigan State University 19 | - Author and maintainer of [posterdown](https://github.com/brentthorne/posterdown) 20 | - Author of [pagedown](https://github.com/rstudio/pagedown) and much, much more! 21 | date: "`r Sys.Date()`" 22 | output: 23 | betterposter::poster_better: 24 | # Optional styling arguments 25 | hero_background: "#0F5D4F" 26 | accent_color: "#444444" 27 | hero_color: "#FFFFFF" 28 | logo: "http://bit.ly/2UFWcbr" 29 | # See betterposter::qrcode_options() for help 30 | qrcode: 31 | text: "https://github.com/gadenbuie/betterposter" 32 | size: "350" 33 | mathjax: false 34 | # Generic rmarkdown arguments 35 | highlight: tango 36 | self_contained: true 37 | references: 38 | - id: fenner2012a 39 | title: One-click science marketing 40 | author: 41 | - family: Fenner 42 | given: Martin 43 | container-title: Nature Materials 44 | volume: 11 45 | URL: 'http://dx.doi.org/10.1038/nmat3283' 46 | DOI: 10.1038/nmat3283 47 | issue: 4 48 | publisher: Nature Publishing Group 49 | page: 261-263 50 | type: article-journal 51 | issued: 52 | year: 2012 53 | month: 3 54 | --- 55 | 56 | ```{css echo=FALSE} 57 | /* Adjust space at top of #hero (center panel) */ 58 | #hero { 59 | padding-top: 33%; 60 | } 61 | ``` 62 | 63 | 64 |
65 | 71 | 72 | # **Main finding** goes here, translated into **plain english**. **Emphasize** the important words. 73 | 74 | *Additional text and content can be added here if you really want.* 75 | 76 | 77 |
78 | 79 | 80 | 81 |
82 | 83 | 84 | ## Abstract 85 | 86 | In recent years, much research has been devoted to the emulation of DHCP; on the other hand, few have explored the construction of journaling file systems. 87 | The inability to effect complexity theory of this has been encouraging. The notion that cryptographers synchronize with game-theoretic configurations is largely adamantly opposed [@fenner2012a]. 88 | 89 | 90 | ## Methods 91 | 92 | 1. IPv6 can be made autonomous, concurrent, and client-server 93 | 94 | 2. 7-month-long trace showing that our design is feasible 95 | 96 | 3. Suffix trees and the Ethernet are entirely incompatible. 97 | 98 | 4. Model for our methodology: 99 | - fiber-optic cables 100 | - simulated annealing 101 | - superblocks 102 | - multicast algorithms 103 | 104 | ## Implementation 105 | 106 | After several days of difficult implementing, we finally have a working implementation of our heuristic. 107 | BEVY is composed of a **hacked operating system**, a codebase of **61** Lisp files, and a **hand-optimized compiler**. 108 | 109 | ![](https://upload.wikimedia.org/wikipedia/commons/f/fa/Conventional_ETL_Diagram.jpg) 110 | 111 | ## Evaluation 112 | 113 | Is it possible to justify having paid little attention to our implementation and experimental setup? 114 | Yes, but only in theory. 115 | 116 | We ran four novel experiments: 117 | 118 | 1. Deployed 35 Macintosh SEs underwater and compared our suffix trees accordingly 119 | 2. Compared effective time since 1967 on the Sprite, L4 and Multics operating systems 120 | 3. Measured _tape drive throughput_ as a function of _hard disk space_ on an `Apple ][` 121 | 4. Deployed 36 `Apple ][`es across the 100-node network and tested again 122 | 123 | ## Results 124 | 125 | In conclusion, in our research we described **BEVY**, a novel heuristic for the analysis of link-level acknowledgements. 126 | We proved that simplicity in our heuristic is not a question. 127 | Our framework for developing the analysis of thin clients is famously excellent. 128 | 129 | This text brought to you by [SCIgen](https://pdos.csail.mit.edu/archive/scigen/), an Automatic CS Paper Generator. 130 | 131 |
132 | 133 | 134 | 135 |
136 | 137 | 138 | # Extra Tables & Figures 139 | 140 | ## Cars are fast 141 | 142 | ```{r eval=TRUE, echo=TRUE, warning=FALSE, message=FALSE} 143 | library(dplyr) 144 | library(ggplot2) 145 | 146 | mtcars %>% 147 | skimr::skim_to_wide() %>% 148 | select(variable, n, mean, sd, p0, p50, p100) %>% 149 | knitr::kable(format = "html") 150 | ``` 151 | 152 | ## Diamonds are foreveer 153 | 154 | ```{r, fig.width=6, fig.height = 3, out.width="100%"} 155 | ggplot(diamonds) + 156 | aes(clarity, price) + 157 | geom_point() 158 | ``` 159 | 160 | ## Starwars has characters 161 | 162 | ```{r echo=TRUE} 163 | starwars %>% 164 | mutate(n_films = sapply(films, length)) %>% 165 | select(name, hair_color, height, species, n_films) %>% 166 | arrange(desc(n_films)) %>% 167 | head(10) %>% 168 | knitr::kable(caption = paste( 169 | "Characters with most", 170 | "appearances in Star Wars movies.")) 171 | ``` 172 | 173 | ## Heavy cars are inefficient 174 | 175 | ```{r, fig.width=6, fig.height = 3, out.width="100%"} 176 | ggplot(mtcars) + 177 | aes(wt, mpg) + 178 | geom_smooth(method = "lm") + 179 | geom_point() + 180 | labs(title = "Something something cars", 181 | subtitle = "A boring regression", 182 | caption = "Source: {mtcars} of course", 183 | x = "Weight of the car", 184 | y = "Fuel efficiency (mpg)") 185 | ``` 186 | 187 |
188 | 189 | # References 190 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/betterposter/template.yaml: -------------------------------------------------------------------------------- 1 | name: HTML Better Poster 2 | description: > 3 | Create a poster in HTML with the Better Poster style. 4 | create_dir: FALSE 5 | -------------------------------------------------------------------------------- /man/figures/betterposter-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GerkeLab/betterposter/f14d1432116ceb8c709e4ecccae06c36c88c2788/man/figures/betterposter-example.png -------------------------------------------------------------------------------- /man/poster_better.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/betterposter.R 3 | \name{poster_better} 4 | \alias{poster_better} 5 | \title{Create a Better Poster in HTML} 6 | \usage{ 7 | poster_better(..., css = NULL, hero_background = NULL, 8 | hero_color = NULL, qrcode = NULL, logo = NULL, 9 | accent_color = NULL, mathjax = FALSE, pandoc_args = NULL) 10 | } 11 | \value{ 12 | An R Markdown output format. 13 | } 14 | \description{ 15 | Create a Better Poster in HTML 16 | } 17 | --------------------------------------------------------------------------------