Add embed method in markdown plugin (#263)

This commit is contained in:
Simon Lecoq
2021-04-26 18:27:41 +02:00
committed by GitHub
parent 43ec9a7c54
commit d3211313e5
3 changed files with 58 additions and 4 deletions

View File

@@ -65,7 +65,7 @@
const { const {
user:_user, repo:_repo, token, user:_user, repo:_repo, token,
template, query, "setup.community.templates":_templates, template, query, "setup.community.templates":_templates,
filename, optimize, verify, filename, optimize, verify, "markdown.cache":_markdown_cache,
debug, "debug.flags":dflags, "use.mocked.data":mocked, dryrun, debug, "debug.flags":dflags, "use.mocked.data":mocked, dryrun,
"plugins.errors.fatal":die, "plugins.errors.fatal":die,
"committer.token":_token, "committer.branch":_branch, "committer.message":_message, "committer.gist":_gist, "committer.token":_token, "committer.branch":_branch, "committer.message":_message, "committer.gist":_gist,
@@ -215,6 +215,8 @@
info("Plugin errors", die ? "(exit with error)" : "(displayed in generated image)") info("Plugin errors", die ? "(exit with error)" : "(displayed in generated image)")
const convert = ["jpeg", "png", "json", "markdown"].includes(config["config.output"]) ? config["config.output"] : null const convert = ["jpeg", "png", "json", "markdown"].includes(config["config.output"]) ? config["config.output"] : null
Object.assign(q, config) Object.assign(q, config)
if (/markdown/.test(convert))
info("Markdown cache", _markdown_cache)
//Base content //Base content
info.break() info.break()
@@ -281,6 +283,40 @@
info(`Save to /metrics_renders/${filename}`, "ok") info(`Save to /metrics_renders/${filename}`, "ok")
} }
//Cache
if (/markdown/.test(convert)) {
const regex = /(?<match><img class="metrics-cachable" data-name="(?<name>[\s\S]+?)" src="data:image[/]svg[+]xml;base64,(?<content>[/+\w]+)">)/g
let matched = null
while (matched = regex.exec(rendered)?.groups) { //eslint-disable-line no-cond-assign
const {match, name, content} = matched
let path = `${_markdown_cache}/${name}.svg`
console.debug(`Processing ${path}`)
let sha = null
try {
const {repository:{object:{oid}}} = await graphql(`
query Sha {
repository(owner: "${github.context.repo.owner}", name: "${github.context.repo.repo}") {
object(expression: "${committer.head}:${path}") { ... on Blob { oid } }
}
}
`, {headers:{authorization:`token ${committer.token}`}})
sha = oid
}
catch (error) {
console.debug(error)
}
finally {
await committer.rest.repos.createOrUpdateFileContents({
...github.context.repo, path, content,
message:`${committer.message} (cache)`, ...(sha ? {sha} : {}),
branch:committer.pr ? committer.head : committer.branch,
})
rendered = rendered.replace(match, `<img src="https://github.com/${github.context.repo.owner}/${github.context.repo.repo}/blob/${committer.branch}/${path}">`)
info(`Saving ${path}`, "ok")
}
}
}
//Check editions //Check editions
if ((committer.commit)||(committer.pr)) { if ((committer.commit)||(committer.pr)) {
const git = sgit() const git = sgit()

View File

@@ -82,11 +82,17 @@
catch (error) { catch (error) {
console.debug(error) console.debug(error)
} }
//Embed method
const embed = async(q, name = Math.random().toString().substring(2)) => {
q = Object.fromEntries([...Object.entries(q).map(([key, value]) => [key.replace(/^plugin_/, "").replace(/_/g, "."), value]), ["base", false], ["config.animations", false]])
const {rendered} = await metrics({login, q}, {...arguments[1], convert:null}, arguments[2])
return `<img class="metrics-cachable" data-name="${name}" src="data:image/svg+xml;base64,${Buffer.from(rendered).toString("base64")}">`
}
//Rendering template source //Rendering template source
let rendered = source.replace(/\{\{ (?<content>[\s\S]*?) \}\}/g, "{%= $<content> %}") let rendered = source.replace(/\{\{ (?<content>[\s\S]*?) \}\}/g, "{%= $<content> %}")
console.debug(rendered) console.debug(rendered)
for (const delimiters of [{openDelimiter:"<", closeDelimiter:">"}, {openDelimiter:"{", closeDelimiter:"}"}]) for (const delimiters of [{openDelimiter:"<", closeDelimiter:">"}, {openDelimiter:"{", closeDelimiter:"}"}])
rendered = await ejs.render(rendered, {...data, s:imports.s, f:imports.format}, {views, async:true, ...delimiters}) rendered = await ejs.render(rendered, {...data, s:imports.s, f:imports.format, embed}, {views, async:true, ...delimiters})
console.debug(`metrics/compute/${login} > success`) console.debug(`metrics/compute/${login} > success`)
return {rendered, mime:"text/plain"} return {rendered, mime:"text/plain"}
} }

View File

@@ -18,9 +18,13 @@ I joined GitHub on `{{ f.date(REGISTRATION_DATE, {dateStyle:"short"}) }}`.
I contributed to `{{ REPOSITORIES_CONTRIBUTED_TO }}` repositories and made `{{ COMMITS }}` commits. I contributed to `{{ REPOSITORIES_CONTRIBUTED_TO }}` repositories and made `{{ COMMITS }}` commits.
``` ```
## 🧩 Markdown plugins <%- await embed({isocalendar:true}) %>
Most of plugins from SVG templates can be reused directly by including image source in markdown, but some have them have their own **markdown** version which includes hyperlinks and reduce image overhead. ## 🧩 Plugins
### Using markdown plugins
Some plugins have their own **markdown** version which includes hyperlinks and reduce image overhead.
See [compatibility matrix](https://github.com/lowlighter/metrics#-templateplugin-compatibily-matrix) for more informations. See [compatibility matrix](https://github.com/lowlighter/metrics#-templateplugin-compatibily-matrix) for more informations.
@@ -43,3 +47,11 @@ ___
___ ___
<%- await include(`partials/topics.ejs`) %> <%- await include(`partials/topics.ejs`) %>
### Embedding SVG metrics
You can also generate "on-the-fly" SVGs metrics image using the `embed` function:
<%- await embed({isocalendar:true, isocalendar_duration:"full-year"}) %>
Available configuration options are mostly the same as [action.yml](https://github.com/lowlighter/metrics/blob/master/action.yml). Note that tokens options must **not** be passed to this function. These will be automatically passed down when defined in your workflow job.