

{"id":13533,"date":"2022-08-19T09:13:12","date_gmt":"2022-08-19T14:13:12","guid":{"rendered":"https:\/\/rud.is\/b\/?p=13533"},"modified":"2022-08-19T14:20:17","modified_gmt":"2022-08-19T19:20:17","slug":"bootstrapping-an-ojs-quarto-document-with-an-observable-notebook","status":"publish","type":"post","link":"https:\/\/rud.is\/b\/2022\/08\/19\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\/","title":{"rendered":"Bootstrapping An {ojs} Quarto Document With An Observable Notebook"},"content":{"rendered":"<p>Quarto is amazing! And, it&#8217;s eating the world! OK. Perhaps not the <em>entire<\/em> world. But it&#8217;s still <em>amazing<\/em>!<\/p>\n<p>If you browse around the <a href=\"https:\/\/observablehq.com\/\">HQ<\/a>, you&#8217;ll find many interesting notebooks. You may even have a few yourself! Wouldn&#8217;t it be great if you could just import an Observable notebook right into Quarto? Well, now you can.<\/p>\n<pre><code class=\"language-r\">#' Transform an Observable Notebook into a Quarto project\n#' \n#' This will yank the cells from a live Observable notebook and turn it into a Quarto project,\n#' downloading all the `FileAttachments` as well.\n#' \n#' @param ohq_ref either a short ref (e.g. `@@hrbrmstr\/just-one-more-thing`) or a full\n#'     URL to a published Observable notebook\n#' @param output_dir quarto project directory (will be created if not already present)\n#' @param quarto_filename if `NULL` (the default) the name will be the slug (e.g. `just-one-more-thing`\n#'     as in the `ohq_ref` param eample) with `.qmd` suffix\n#' @param echo set `echo` to `true` or `false` in the YAML\nohq_to_quarto &lt;- function(ohq_ref, output_dir, quarto_filename = NULL, echo = FALSE) {\n\n  ohq_ref &lt;- ohq_ref[1]\n  if (grepl(\"^@\", ohq_ref)) ohq_ref &lt;- sprintf(\"https:\/\/observablehq.com\/%s\", ohq_ref)\n\n  output_dir &lt;- output_dir[1]\n  if (!dir.exists(output_dir)) dir.create(output_dir)\n\n  quarto_filename &lt;- quarto_filename[1]\n\n  pg &lt;- rvest::read_html(ohq_ref)\n\n  pg |&gt; \n    html_nodes(\"script#__NEXT_DATA__\") |&gt; \n    html_text() |&gt; \n    jsonlite::fromJSON() -&gt; x\n\n  meta &lt;- x$props$pageProps$initialNotebook\n  nodes &lt;- x$props$pageProps$initialNotebook$nodes\n\n  if (is.null(quarto_filename)) quarto_filename &lt;- sprintf(\"%.qmd\", meta$slug)\n\n  c(\n    \"---\", \n    sprintf(\"title: '%s'\", meta$title), \n    \"format: html\", \n    if (echo) \"echo: true\" else \"echo: false\",\n    \"---\",\n    \"\",\n    purrr::map2(nodes$value, nodes$mode, ~{\n      c(\n\n        \"```{ojs}\",\n        dplyr::case_when(\n          .y == \"md\" ~ sprintf(\"md`%s`\", .x),\n          .y == \"html\" ~ sprintf(\"html`%s`\", .x),\n          TRUE ~ .x\n        ),\n        \"```\",\n        \"\"\n      )\n\n    })\n  ) |&gt; \n    purrr::flatten_chr() |&gt; \n    cat(\n      file = file.path(output_dir, quarto_filename), \n      sep = \"\\n\"\n    )\n\n  if (length(meta$files)) {\n    if (nrow(meta$files) &gt; 0) {\n      purrr::walk2(\n        meta$files$download_url,\n        meta$files$name, ~{\n          download.file(\n            url = .x,\n            destfile = file.path(output_dir, .y),\n            quiet = TRUE\n          )\n        }\n      )\n    }\n  }\n\n}\n<\/code><\/pre>\n<p>You can try that out with my <a href=\"https:\/\/observablehq.com\/@hrbrmstr\/just-one-more-thing\">Columbo notebook<\/a>:<\/p>\n<pre><code class=\"language-r\">ohq_to_quarto(\n  ohq_ref = \"@hrbrmstr\/just-one-more-thing\", \n  output_dir = \"~\/Development\/columbo\",\n  quarto_filename = \"columbo.qmd\",\n  echo = FALSE\n)\n<\/code><\/pre>\n<p>That will download the CSV file into the specified directory and convert the cells to a <code>.qmd<\/code>. You can <a href=\"https:\/\/rud.is\/dl\/columbo.qmd\">download that example file<\/a>, but you&#8217;ll need the data to run it (or just run the converter).<\/p>\n<p>This is what the directory tree looks like after the script is run and the document is rendered:<\/p>\n<pre><code class=\"language-shell\">columbo\/\n\u251c\u2500\u2500 columbo.html\n\u251c\u2500\u2500 columbo.qmd\n\u251c\u2500\u2500 columbo_data.csv\n\u2514\u2500\u2500 columbo_files\n    \u2514\u2500\u2500 libs\n        \u251c\u2500\u2500 bootstrap\n        \u2502\u00a0\u00a0 \u251c\u2500\u2500 bootstrap-icons.css\n        \u2502\u00a0\u00a0 \u251c\u2500\u2500 bootstrap-icons.woff\n        \u2502\u00a0\u00a0 \u251c\u2500\u2500 bootstrap.min.css\n        \u2502\u00a0\u00a0 \u2514\u2500\u2500 bootstrap.min.js\n        \u251c\u2500\u2500 clipboard\n        \u2502\u00a0\u00a0 \u2514\u2500\u2500 clipboard.min.js\n        \u251c\u2500\u2500 quarto-html\n        \u2502\u00a0\u00a0 \u251c\u2500\u2500 anchor.min.js\n        \u2502\u00a0\u00a0 \u251c\u2500\u2500 popper.min.js\n        \u2502\u00a0\u00a0 \u251c\u2500\u2500 quarto-syntax-highlighting.css\n        \u2502\u00a0\u00a0 \u251c\u2500\u2500 quarto.js\n        \u2502\u00a0\u00a0 \u251c\u2500\u2500 tippy.css\n        \u2502\u00a0\u00a0 \u2514\u2500\u2500 tippy.umd.min.js\n        \u2514\u2500\u2500 quarto-ojs\n            \u251c\u2500\u2500 quarto-ojs-runtime.js\n            \u2514\u2500\u2500 quarto-ojs.css\n<\/code><\/pre>\n<p>The function has not been battle tested, and it&#8217;s limited to the current functionality, but it should do what it says on the tin.<\/p>\n<p><strike>I&#8217;ll turn this into a Rust binary so it&#8217;s more usable outside of the R ecosystem.<\/strike><\/p>\n<p>You can try out a fledgling Rust version <a href=\"https:\/\/github.com\/hrbrmstr\/ohq2quarto\">here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Quarto is amazing! And, it&#8217;s eating the world! OK. Perhaps not the entire world. But it&#8217;s still amazing! If you browse around the HQ, you&#8217;ll find many interesting notebooks. You may even have a few yourself! Wouldn&#8217;t it be great if you could just import an Observable notebook right into Quarto? Well, now you can. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":3,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":""},"categories":[860,91],"tags":[],"class_list":["post-13533","post","type-post","status-publish","format-standard","hentry","category-quarto","category-r"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Bootstrapping An {ojs} Quarto Document With An Observable Notebook - rud.is<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/rud.is\/b\/2022\/08\/19\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Bootstrapping An {ojs} Quarto Document With An Observable Notebook - rud.is\" \/>\n<meta property=\"og:description\" content=\"Quarto is amazing! And, it&#8217;s eating the world! OK. Perhaps not the entire world. But it&#8217;s still amazing! If you browse around the HQ, you&#8217;ll find many interesting notebooks. You may even have a few yourself! Wouldn&#8217;t it be great if you could just import an Observable notebook right into Quarto? Well, now you can. [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/rud.is\/b\/2022\/08\/19\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\/\" \/>\n<meta property=\"og:site_name\" content=\"rud.is\" \/>\n<meta property=\"article:published_time\" content=\"2022-08-19T14:13:12+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-08-19T19:20:17+00:00\" \/>\n<meta name=\"author\" content=\"hrbrmstr\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"hrbrmstr\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2022\\\/08\\\/19\\\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2022\\\/08\\\/19\\\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\\\/\"},\"author\":{\"name\":\"hrbrmstr\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\"},\"headline\":\"Bootstrapping An {ojs} Quarto Document With An Observable Notebook\",\"datePublished\":\"2022-08-19T14:13:12+00:00\",\"dateModified\":\"2022-08-19T19:20:17+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2022\\\/08\\\/19\\\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\\\/\"},\"wordCount\":183,\"commentCount\":4,\"publisher\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\"},\"articleSection\":[\"Quarto\",\"R\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/rud.is\\\/b\\\/2022\\\/08\\\/19\\\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2022\\\/08\\\/19\\\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\\\/\",\"url\":\"https:\\\/\\\/rud.is\\\/b\\\/2022\\\/08\\\/19\\\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\\\/\",\"name\":\"Bootstrapping An {ojs} Quarto Document With An Observable Notebook - rud.is\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#website\"},\"datePublished\":\"2022-08-19T14:13:12+00:00\",\"dateModified\":\"2022-08-19T19:20:17+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2022\\\/08\\\/19\\\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/rud.is\\\/b\\\/2022\\\/08\\\/19\\\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2022\\\/08\\\/19\\\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/rud.is\\\/b\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Bootstrapping An {ojs} Quarto Document With An Observable Notebook\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#website\",\"url\":\"https:\\\/\\\/rud.is\\\/b\\\/\",\"name\":\"rud.is\",\"description\":\"&quot;In God we trust. All others must bring data&quot;\",\"publisher\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/rud.is\\\/b\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\",\"name\":\"hrbrmstr\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\",\"width\":460,\"height\":460,\"caption\":\"hrbrmstr\"},\"logo\":{\"@id\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\"},\"description\":\"Don't look at me\u2026I do what he does \u2014 just slower. #rstats avuncular \u2022 ?Resistance Fighter \u2022 Cook \u2022 Christian \u2022 [Master] Chef des Donn\u00e9es de S\u00e9curit\u00e9 @ @rapid7\",\"sameAs\":[\"http:\\\/\\\/rud.is\"],\"url\":\"https:\\\/\\\/rud.is\\\/b\\\/author\\\/hrbrmstr\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Bootstrapping An {ojs} Quarto Document With An Observable Notebook - rud.is","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/rud.is\/b\/2022\/08\/19\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\/","og_locale":"en_US","og_type":"article","og_title":"Bootstrapping An {ojs} Quarto Document With An Observable Notebook - rud.is","og_description":"Quarto is amazing! And, it&#8217;s eating the world! OK. Perhaps not the entire world. But it&#8217;s still amazing! If you browse around the HQ, you&#8217;ll find many interesting notebooks. You may even have a few yourself! Wouldn&#8217;t it be great if you could just import an Observable notebook right into Quarto? Well, now you can. [&hellip;]","og_url":"https:\/\/rud.is\/b\/2022\/08\/19\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\/","og_site_name":"rud.is","article_published_time":"2022-08-19T14:13:12+00:00","article_modified_time":"2022-08-19T19:20:17+00:00","author":"hrbrmstr","twitter_card":"summary_large_image","twitter_misc":{"Written by":"hrbrmstr","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/rud.is\/b\/2022\/08\/19\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\/#article","isPartOf":{"@id":"https:\/\/rud.is\/b\/2022\/08\/19\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\/"},"author":{"name":"hrbrmstr","@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"headline":"Bootstrapping An {ojs} Quarto Document With An Observable Notebook","datePublished":"2022-08-19T14:13:12+00:00","dateModified":"2022-08-19T19:20:17+00:00","mainEntityOfPage":{"@id":"https:\/\/rud.is\/b\/2022\/08\/19\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\/"},"wordCount":183,"commentCount":4,"publisher":{"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"articleSection":["Quarto","R"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/rud.is\/b\/2022\/08\/19\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/rud.is\/b\/2022\/08\/19\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\/","url":"https:\/\/rud.is\/b\/2022\/08\/19\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\/","name":"Bootstrapping An {ojs} Quarto Document With An Observable Notebook - rud.is","isPartOf":{"@id":"https:\/\/rud.is\/b\/#website"},"datePublished":"2022-08-19T14:13:12+00:00","dateModified":"2022-08-19T19:20:17+00:00","breadcrumb":{"@id":"https:\/\/rud.is\/b\/2022\/08\/19\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/rud.is\/b\/2022\/08\/19\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/rud.is\/b\/2022\/08\/19\/bootstrapping-an-ojs-quarto-document-with-an-observable-notebook\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/rud.is\/b\/"},{"@type":"ListItem","position":2,"name":"Bootstrapping An {ojs} Quarto Document With An Observable Notebook"}]},{"@type":"WebSite","@id":"https:\/\/rud.is\/b\/#website","url":"https:\/\/rud.is\/b\/","name":"rud.is","description":"&quot;In God we trust. All others must bring data&quot;","publisher":{"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/rud.is\/b\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886","name":"hrbrmstr","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","url":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","contentUrl":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","width":460,"height":460,"caption":"hrbrmstr"},"logo":{"@id":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1"},"description":"Don't look at me\u2026I do what he does \u2014 just slower. #rstats avuncular \u2022 ?Resistance Fighter \u2022 Cook \u2022 Christian \u2022 [Master] Chef des Donn\u00e9es de S\u00e9curit\u00e9 @ @rapid7","sameAs":["http:\/\/rud.is"],"url":"https:\/\/rud.is\/b\/author\/hrbrmstr\/"}]}},"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p23idr-3wh","jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":13554,"url":"https:\/\/rud.is\/b\/2022\/08\/22\/new-chrome-extension-to-turn-observable-notebooks-into-quarto-projects\/","url_meta":{"origin":13533,"position":0},"title":"New Chrome Extension To Turn Observable Notebooks Into Quarto Projects","author":"hrbrmstr","date":"2022-08-22","format":false,"excerpt":"My previous post announced a Rust-based command line tool for generating Quarto projects from Observable Notebooks. Some folks may not want to use yet-another command line tool, and it dawned on me that it'd be more convenient to just do the conversion in-browser when one is already on a Notebook\u2026","rel":"","context":"In &quot;Chrome&quot;","block_context":{"text":"Chrome","link":"https:\/\/rud.is\/b\/category\/chrome\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":13549,"url":"https:\/\/rud.is\/b\/2022\/08\/20\/ohq2quarto-rust-based-cli-for-turning-observable-notebooks-into-quarto-projects\/","url_meta":{"origin":13533,"position":1},"title":"ohq2quarto \u2014 Rust-Based CLI For Turning Observable Notebooks Into Quarto Projects","author":"hrbrmstr","date":"2022-08-20","format":false,"excerpt":"The previous post had some hacky R code to grab seekrit JSON data in ObservableHQ (OHQ) Notebooks and spit out a directory with a Quarto qmd and any associated FileAttachments. Holding firm to my \"no more generic public R packages\" decree, that's as far as the R code for that\u2026","rel":"","context":"In &quot;Quarto&quot;","block_context":{"text":"Quarto","link":"https:\/\/rud.is\/b\/category\/quarto\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":13569,"url":"https:\/\/rud.is\/b\/2022\/09\/09\/fall-foliage-javascript-ojs-edition\/","url_meta":{"origin":13533,"position":2},"title":"Fall Foliage: JavaScript\/OJS Edition","author":"hrbrmstr","date":"2022-09-09","format":false,"excerpt":"I've been (mostly) keeping up with annual updates for my R\/{sf} U.S. foliage post which you can find on GH. This year, we have Quarto, and it comes with so many batteries included that you'd think it was Christmas. One of those batteries is full support for the Observable runtime.\u2026","rel":"","context":"In &quot;d3&quot;","block_context":{"text":"d3","link":"https:\/\/rud.is\/b\/category\/d3\/"},"img":{"alt_text":"foliage map","src":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2022\/09\/foliage.png?fit=1200%2C1040&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2022\/09\/foliage.png?fit=1200%2C1040&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2022\/09\/foliage.png?fit=1200%2C1040&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2022\/09\/foliage.png?fit=1200%2C1040&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2022\/09\/foliage.png?fit=1200%2C1040&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":14337,"url":"https:\/\/rud.is\/b\/2023\/09\/09\/foliage-2023\/","url_meta":{"origin":13533,"position":3},"title":"Foliage 2023","author":"hrbrmstr","date":"2023-09-09","format":false,"excerpt":"2023-09-10 UPDATE: Art Steinmetz took me up on the Shiny challenge (at the end of the post) and did a fantastic job! The days are getting shorter and when we were visiting Down East Maine the other week, there was just a hint of some trees starting to change up\u2026","rel":"","context":"In &quot;data wrangling&quot;","block_context":{"text":"data wrangling","link":"https:\/\/rud.is\/b\/category\/data-wrangling\/"},"img":{"alt_text":"conus foliage map 2023","src":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/09\/lit-plot.png?fit=1200%2C1137&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/09\/lit-plot.png?fit=1200%2C1137&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/09\/lit-plot.png?fit=1200%2C1137&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/09\/lit-plot.png?fit=1200%2C1137&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/09\/lit-plot.png?fit=1200%2C1137&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":14001,"url":"https:\/\/rud.is\/b\/2023\/04\/29\/supreme-annotations-plot-redux-an-ojs-plot%e2%86%94ggplot2-rosetta-stone\/","url_meta":{"origin":13533,"position":4},"title":"Supreme Annotations Plot Redux &#038; An OJS Plot\u2194ggplot2 Rosetta Stone","author":"hrbrmstr","date":"2023-04-29","format":false,"excerpt":"Back in 2016, I did a post on {ggplot2} text annotations because it was a tad more challenging to do some of the things in that post back in the day. Since I've been moving back and forth between R and Observable (and JavaScript in general), I decided to recreate\u2026","rel":"","context":"In &quot;Observable&quot;","block_context":{"text":"Observable","link":"https:\/\/rud.is\/b\/category\/observable\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":13060,"url":"https:\/\/rud.is\/b\/2021\/05\/06\/covid-19-u-s-county-vaccination-tracker-with-an-observable-notebook-using-datasettes-and-plot\/","url_meta":{"origin":13533,"position":5},"title":"COVID-19 U.S. County Vaccination Tracker With An Observable Notebook Using Datasettes and {Plot}","author":"hrbrmstr","date":"2021-05-06","format":false,"excerpt":"Rather than continue to generate daily images with R, I threw together an Observable notebook that takes advantage of the CDC COVID-19 county data datasette (provided by Simon Willison) and the new {Plot} library (by the @ObservableHQ team) that enables users to interactively see the daily county resident vaccination \"series\u2026","rel":"","context":"In &quot;DataVis&quot;","block_context":{"text":"DataVis","link":"https:\/\/rud.is\/b\/category\/datavis-2\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts\/13533","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/comments?post=13533"}],"version-history":[{"count":0,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts\/13533\/revisions"}],"wp:attachment":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/media?parent=13533"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/categories?post=13533"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/tags?post=13533"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}