|
| 1 | +-- Version-aware shortcodes for prerelease content. |
| 2 | +-- |
| 3 | +-- prerelease-docs-url: |
| 4 | +-- {{< prerelease-docs-url 1.9 >}} |
| 5 | +-- Returns "prerelease." when the referenced version's docs live on |
| 6 | +-- prerelease.quarto.org, or "" when they're on quarto.org. |
| 7 | +-- |
| 8 | +-- prerelease-callout: |
| 9 | +-- {{< prerelease-callout 1.9 >}} |
| 10 | +-- Shows a "Pre-release Feature" callout when the referenced version is |
| 11 | +-- unreleased. Shows nothing once the version is released. |
| 12 | +-- |
| 13 | +-- {{< prerelease-callout 1.9 type="blog" >}} |
| 14 | +-- Blog mode: shows "Pre-release Feature" callout when unreleased, |
| 15 | +-- switches to "Quarto X.Y Feature" callout once released. |
| 16 | +-- |
| 17 | +-- Both shortcodes use the `version` key from _quarto.yml metadata and |
| 18 | +-- the `prerelease-docs` profile to determine whether a version is released. |
| 19 | + |
| 20 | +--- Strip surrounding quotes from a shortcode argument. |
| 21 | +local function strip_quotes(s) |
| 22 | + return s:gsub('^"(.*)"$', '%1'):gsub("^'(.*)'$", '%1') |
| 23 | +end |
| 24 | + |
| 25 | +--- Parse the version argument and site version metadata. |
| 26 | +-- Returns ref_version, branch_version (as pandoc.types.Version), or |
| 27 | +-- nil plus an error Blocks/Inlines on failure. |
| 28 | +local function parse_versions(shortcode_name, args, meta, context) |
| 29 | + local ref_str = quarto.shortcode.read_arg(args, 1) |
| 30 | + if ref_str == nil then |
| 31 | + return nil, nil, quarto.shortcode.error_output( |
| 32 | + shortcode_name, |
| 33 | + "requires a version argument, e.g. {{< " .. shortcode_name .. " 1.9 >}}", |
| 34 | + context |
| 35 | + ) |
| 36 | + end |
| 37 | + ref_str = strip_quotes(ref_str) |
| 38 | + |
| 39 | + local version_str = meta["version"] and pandoc.utils.stringify(meta["version"]) or nil |
| 40 | + if not version_str or version_str == "" then |
| 41 | + return nil, nil, quarto.shortcode.error_output( |
| 42 | + shortcode_name, |
| 43 | + "missing 'version' in document metadata", |
| 44 | + context |
| 45 | + ) |
| 46 | + end |
| 47 | + |
| 48 | + local ok_branch, branch_version = pcall(pandoc.types.Version, version_str) |
| 49 | + if not ok_branch then |
| 50 | + return nil, nil, quarto.shortcode.error_output( |
| 51 | + shortcode_name, |
| 52 | + "invalid metadata version '" .. version_str .. "'", |
| 53 | + context |
| 54 | + ) |
| 55 | + end |
| 56 | + |
| 57 | + local ok_ref, ref_version = pcall(pandoc.types.Version, ref_str) |
| 58 | + if not ok_ref then |
| 59 | + return nil, nil, quarto.shortcode.error_output( |
| 60 | + shortcode_name, |
| 61 | + "invalid version argument '" .. ref_str .. "'", |
| 62 | + context |
| 63 | + ) |
| 64 | + end |
| 65 | + |
| 66 | + return ref_version, branch_version, nil |
| 67 | +end |
| 68 | + |
| 69 | +--- Check whether a referenced version is unreleased. |
| 70 | +-- On prerelease site (profile prerelease-docs): ref >= site version |
| 71 | +-- On main site: ref > site version |
| 72 | +local function is_unreleased(ref_version, branch_version) |
| 73 | + if quarto.project.profile:includes("prerelease-docs") then |
| 74 | + return ref_version >= branch_version |
| 75 | + else |
| 76 | + return ref_version > branch_version |
| 77 | + end |
| 78 | +end |
| 79 | + |
| 80 | +--- Parse a markdown string into pandoc Blocks. |
| 81 | +local function md_to_blocks(md) |
| 82 | + return pandoc.read(md, "markdown").blocks |
| 83 | +end |
| 84 | + |
| 85 | +-- Shortcode: prerelease-docs-url |
| 86 | +local function docs_url_handler(args, kwargs, meta, raw_args, context) |
| 87 | + local ref_version, branch_version, err = parse_versions( |
| 88 | + "prerelease-docs-url", args, meta, context |
| 89 | + ) |
| 90 | + if err then return err end |
| 91 | + |
| 92 | + -- On the prerelease site, always link to prerelease |
| 93 | + if quarto.project.profile:includes("prerelease-docs") then |
| 94 | + return pandoc.Str("prerelease.") |
| 95 | + end |
| 96 | + |
| 97 | + if ref_version <= branch_version then |
| 98 | + return pandoc.Str("") |
| 99 | + else |
| 100 | + return pandoc.Str("prerelease.") |
| 101 | + end |
| 102 | +end |
| 103 | + |
| 104 | +-- Shortcode: prerelease-callout |
| 105 | +local function callout_handler(args, kwargs, meta, raw_args, context) |
| 106 | + local ref_version, branch_version, err = parse_versions( |
| 107 | + "prerelease-callout", args, meta, context |
| 108 | + ) |
| 109 | + if err then return err end |
| 110 | + |
| 111 | + local ref_str = strip_quotes(quarto.shortcode.read_arg(args, 1)) |
| 112 | + local callout_type = kwargs["type"] or "" |
| 113 | + local is_blog = callout_type == "blog" |
| 114 | + local unreleased = is_unreleased(ref_version, branch_version) |
| 115 | + |
| 116 | + if unreleased then |
| 117 | + -- Pre-release callout (both feature docs and blog) |
| 118 | + local content = md_to_blocks( |
| 119 | + "This feature is new in the upcoming Quarto " .. ref_str .. " release. " .. |
| 120 | + "To use the feature now, you'll need to " .. |
| 121 | + "[download and install](/docs/download/prerelease.qmd) " .. |
| 122 | + "the Quarto pre-release." |
| 123 | + ) |
| 124 | + return quarto.Callout({ |
| 125 | + type = "note", |
| 126 | + title = "Pre-release Feature", |
| 127 | + content = content, |
| 128 | + }) |
| 129 | + end |
| 130 | + |
| 131 | + if is_blog then |
| 132 | + -- Released blog callout |
| 133 | + local content = md_to_blocks( |
| 134 | + "This post is part of a series highlighting new features in the " .. |
| 135 | + ref_str .. " release of Quarto. Get the latest release on the " .. |
| 136 | + "[download page](/docs/download/index.qmd)." |
| 137 | + ) |
| 138 | + return quarto.Callout({ |
| 139 | + type = "note", |
| 140 | + title = "Quarto " .. ref_str .. " Feature", |
| 141 | + content = content, |
| 142 | + }) |
| 143 | + end |
| 144 | + |
| 145 | + -- Feature docs, already released: show nothing |
| 146 | + return pandoc.Blocks({}) |
| 147 | +end |
| 148 | + |
| 149 | +return { |
| 150 | + ["prerelease-docs-url"] = docs_url_handler, |
| 151 | + ["prerelease-callout"] = callout_handler, |
| 152 | +} |
0 commit comments