Skip to content

Instantly share code, notes, and snippets.

@ZodmanPerth
Last active August 26, 2021 22:29
Show Gist options
  • Save ZodmanPerth/76fdee2e89ed89e38d5cce7cfbb3dbce to your computer and use it in GitHub Desktop.
Save ZodmanPerth/76fdee2e89ed89e38d5cce7cfbb3dbce to your computer and use it in GitHub Desktop.
Custom Tag Script Plugins for Hexo.io with Icaraus Theme v5.4. Blog post at ...
// Kudos: https://github.com/haishanh/hexo-tag-admonition/blob/master/index.js
// Adds a centered caption to anything.
// Usage:
// {% zodcaption %}
// content of caption
// {% endzodcaption %}
// Where:
// content = markdown content of the caption
// mt:x = optional top margin (x either being the size or "mt-[1,2,3,4,5,6]")
// mb:x = optional bottom margin (x either being the size or "mb-[1,2,3,4,5,6]")
hexo.extend.tag.register('zodcaption', function (args, content) {
var quoteText = hexo.render.renderSync({
text: content,
engine: 'markdown'
}).slice(3, -5) // remove <p> container
// Optional args
var optionals = args
var mt = "0.3em"
var mb = ""
var isClassMarginTop = false
var isClassMarginBottom = false
if (optionals) {
for (let arg of optionals) {
if (arg.startsWith('mt:')) {
mt = arg.substr(3)
isClassMarginTop = mt.startsWith("mt-")
}
else if (arg.startsWith('mb:')) {
mb = arg.substr(3)
isClassMarginBottom = mb.startsWith("mb-")
}
}
}
var classContent = "has-text-centered is-size-6 caption"
var styleContent = "color:#7a7a7a"
if (isClassMarginTop)
classContent += ` ${mt}`
else
styleContent += `;margin-top:${mt}`
if (mb)
if (isClassMarginBottom)
classContent += ` ${mb}`
else
styleContent += `;margin-bottom:${mb}`
var output =
`<p class="${classContent}" style="${styleContent}">${quoteText}</p>`
return output;
}, {
async: true,
ends: true
});
// Adds content in columns. Can be optionally coloured with a Bulma message block.
// Usage:
// {% zodcolumns [colour] %}
// /title
// Put an optional title block in here. It will be capitalised.
// /
// this is the first row of column 1.
// this is the second row of column 1.
// add as many rows as you want.
// There are 4 rows in column 1.
// /
// you can add as many columns as you want as well.
// there doesn't have to be an equal amount of rows in each column.
// There are 3 rows in column 2.
// /title
// You can add multiple titles
// /
// This is a new set of columns!
// There are 2 rows in column 1.
// /
// There is 1 row in column 2.
// /
// There is a 3rd column in this column block.
// {% endzodcolumns %}
// Where:
// colour = optional values are [link]
hexo.extend.tag.register('zodcolumns', function(args, content) {
var messageClass = "";
var textColour = "inherit";
switch (args[0]) {
case 'link':
messageClass = 'is-link'
textColour = '#3273dc'
break;
}
var output = "";
if (messageClass!="") {
output = `<article class=\"message ${messageClass}\" style=\"margin-top: 1.3em\">`;
output += `<div class="message-body" style="color:${textColour}">`;
}
var columns = content.split('\n')
var isFirstColumnDirective = true;
var isTitle = false;
for(var row of columns) {
if (row.startsWith("/")) { // directive
if (row.startsWith("/title")) {
isTitle = true;
if (isFirstColumnDirective == false) {
output += "\t</div>\n</div>\n";
isFirstColumnDirective = true;
}
}
else {
if (isFirstColumnDirective) {
output += `<div class="columns" style="overflow:auto">\n`;
}
else {
output += "\t</div>\n";
}
output += "\t<div class=\"column is-narrow\">\n";
isFirstColumnDirective = false;
}
}
else { // not a directive
if (isTitle) {
row = row.toUpperCase();
rowText = `<p style="font-size: 0.8em;margin-bottom: 0.5em;">${row}</p>`;
}
else {
var rowText = hexo.render.renderSync({
text: row,
engine: 'markdown'
}).slice(3, -5); // slice removes leading <p> and trailing </p>
rowText+=`<br>`;
}
output += `\t\t${rowText}\n`;
isTitle = false;
}
}
output += `\t</div>\n\</div>`;
if (messageClass!="") {
output += `\n\</div>\n</article>`;
}
return output;
}, {
async: true,
ends: true
});
// Adds an image with optional caption, height, and link to somewhere else.
// Usage:
// {% zodimage imageUrl [linkUrl] [h:height] %}
// caption
// {% endzodimglink %}
// Where:
// imageUrl = the relative image path or URL
// linkUrl = optionally convert the image into a link
// h:x = the optional image render height (x)
// mt:x = optional top margin (x either being the size or "mt-[1,2,3,4,5,6]")
// mb:x = optional bottom margin (x either being the size or "mb-[1,2,3,4,5,6]")
// mc:x = optional margin above the caption (x either being the size or "mb-[1,2,3,4,5,6]")
// caption = the caption on the image
hexo.extend.tag.register('zodimage', function (args, content) {
var imgUrl = args[0];
var captionHtml = ""
var caption = hexo.render.renderSync({
text: content,
engine: 'markdown'
}).slice(3, -5) // slice removes leading <p> and trailing </p>
// Optional args
var optionals = args.slice(1) // take remaining
var url = imgUrl
var linkAttributes = ` target="_blank"`
var height = ""
var mt = ""
var mb = ""
var mc = ""
var isClassMarginTopA = false
var isClassMarginBottomA = false
var isClassMarginCaption = false
if (optionals) {
for (let arg of optionals) {
if (arg.startsWith('h:')) {
height = `height:${arg.substr(2)};`
}
else if (arg.startsWith('mt:')) {
mt = arg.substr(3)
isClassMarginTopA = mt.startsWith("mt-")
}
else if (arg.startsWith('mb:')) {
mb = arg.substr(3)
isClassMarginBottomA = mb.startsWith("mb-")
}
else if (arg.startsWith('mc:')) {
mc = arg.substr(3)
if (mc.startsWith("mc-")) {
isClassMarginCaption = true
var mcValue = mc.substr(3)
mc = `mt-${mcValue}`
}
}
else {
url = arg
if (url[0] == `#`) // anchor
linkAttributes = ``
else if (url.startsWith("http")) // external
linkAttributes = ` target="_blank" rel="external"`
}
}
}
// Spacing above and below link
var divClassContent = ""
var divStyleContent = ""
if (mt)
if (isClassMarginTopA)
divClassContent = mt
else
divStyleContent = `margin-top:${mt}`
if (mb)
if (isClassMarginBottomA) {
if (divClassContent) divClassContent += ` `
divClassContent += mb
}
else {
if (divStyleContent) divStyleContent += `;`
divStyleContent += `margin-bottom:${mb}`
}
if (divClassContent)
divClassContent = `class="${divClassContent}"`
if (divStyleContent)
divStyleContent = `style="${divStyleContent}"`
// Link
aClassText = `class="gallery-item"`
var aStyleText = `color:#7a7a7a`
// Caption
var captionClassText = null
var captionClassContent = ""
var captionStyleContent = ""
if (mc)
if (isClassMarginCaption)
captionClassContent = ` ${mc}`
else
captionStyleContent = `;margin-top:${mc}`
else
captionStyleContent = ";margin-top:0.5em"
captionClassText = `has-text-centered is-size-6 caption${captionClassContent}`
captionStyleText = `color:#7a7a7a${captionStyleContent};padding-bottom:1em`
// Assemble output
if (caption)
captionHtml = `<p class="${captionClassText}" style="${captionStyleText}">${caption}</p>`
var body =
`<a ${aClassText} style="${aStyleText}" href="${url}"${linkAttributes}>
<img src="${imgUrl}" style="display:block;margin:0 auto 0 auto;${height}object-fit:contain">
${captionHtml}
</a>`
var output = ""
if (mt || mb)
output = `<div ${divClassContent}${divStyleContent}>${body}</div>`
else
output = body
return output;
}, {
async: true,
ends: true
});
.zodnote .message-body .tag
color: white
.is-primary.zodnote
.message-body
color: darken(zodnote-color-blue, 18.5)
background-color: lighten(zodnote-color-blue, 21%)
.tag
background-color: zodnote-color-blue
.is-info.zodnote
.message-body
color: darken(zodnote-color-aqua, 20)
background-color: lighten(zodnote-color-aqua, 30.5%)
.tag
background-color: zodnote-color-aqua
.is-success.zodnote
.message-body
color: darken(zodnote-color-green, 17)
background-color: lighten(zodnote-color-green, 31.8%)
.tag
background-color: zodnote-color-green
.is-warning.zodnote
.message-body
color: darken(zodnote-color-yellow, 28)
background-color: lighten(zodnote-color-yellow, 27.5%)
.tag
color: darken(zodnote-color-yellow, 37)
background-color: zodnote-color-yellow
.is-danger.zodnote
.message-body
color: darken(zodnote-color-red, 10)
background-color: lighten(zodnote-color-red, 34%)
.tag
background-color: zodnote-color-red
zodnote-color-blue = #a1b4ca
zodnote-color-aqua = #68c7dc
zodnote-color-green = #89ad8e
zodnote-color-yellow = #fbda5c
zodnote-color-red = #f14a51
// Kudos: https://github.com/haishanh/hexo-tag-admonition/blob/master/index.js
// Adds a tagged note in a variety of colours.
// Usage:
// {% zodnote colour [header text] %}
// content of note
// {% endzodnote %}
// Where:
// colour = [blue,aqua,green,yellow,red]
// header text = the text in the tag. Can include spaces.
// content = markdown content of the note
hexo.extend.tag.register('zodnote', function(args, content) {
var colourClass = "is-primary";
switch (args[0] || 'blue') {
case 'aqua':
colourClass = 'is-info'
break;
case 'green':
colourClass = 'is-success'
break;
case 'yellow':
colourClass = 'is-warning'
break;
case 'red':
colourClass = 'is-danger'
break;
}
var titleText = args.slice(1).join(' ').toUpperCase() || 'NOTE';
var quoteText = hexo.render.renderSync({
text: content,
engine: 'markdown'
}).slice(3, -5); // slice removes leading <p> and trailing </p>
var output =
`<article class="message message-immersive ${colourClass} zodnote">
<div class="message-body">
<span class="tag ${colourClass} mr-2">${titleText}</span>
${quoteText}
</div>
</article>
`
return output;
}, {
async: true,
ends: true
});
// Adds a tag with an optional link
// Usage:
// {% zodtag colour type [url] [mt:n] [mb:n] %}
// content of tag
// {% endzodtag %}
// Where:
// colour = [black,green]
// type = [photo,skip]
// url = optional link
// mt:x = optional top margin (x either being the size or "mt-[1,2,3,4,5,6]")
// mb:x = optional bottom margin (x either being the size or "mb-[1,2,3,4,5,6]")
// content = markdown content of the tag
hexo.extend.tag.register('zodtag', function (args, content) {
var backgroundColourStyle = 'black'
switch (args[0] || 'black') {
case 'green':
backgroundColourStyle = '#28a028'
break
}
var typeClass = "fas fa-camera"
switch (args[1] || 'photo') {
case 'skip':
typeClass = "fas fa-share fa-rotate-180"
break
}
var optionals = args.slice(2) // take remaining
var url = null
var mt = "mt-3"
var mb = "mb-2"
var isClassMarginTop = true
var isClassMarginBottom = true
if (optionals) {
for (let arg of optionals) {
if (arg.startsWith('mt:')) {
mt = arg.substr(3)
isClassMarginTop = mt.startsWith("mt-")
}
else if (arg.startsWith('mb:')) {
mb = arg.substr(3)
isClassMarginBottom = mb.startsWith("mb-")
}
else {
url = `href="${arg}"`
}
}
}
var classText = null
var styleContent = ""
var classContent = ""
if (isClassMarginTop) {
if (isClassMarginBottom) {
classContent = `${mt} ${mb}`
}
else {
classContent = mt
styleContent = `;margin-bottom:${mb}`
}
}
else {
styleContent = `;margin-top:${mt}`
if (isClassMarginBottom) {
classContent = mb
}
else {
styleContent += `;margin-bottom:${mb}`
}
}
classText = ` class="${classContent}" `
var styleText = `background-color:${backgroundColourStyle};color:white;text-decoration:none;padding:4px 6px;font-size:12px;line-height:1.2;display:inline-block;border-radius:3px${styleContent}`
var bodyText = hexo.render.renderSync({
text: content,
engine: 'markdown'
}).slice(3, -5) // slice removes leading <p> and trailing </p>
var container = "a"
if (!url) container = "div"
var output =
`
<${container} style="${styleText}"${classText} ${url}>
<i class="${typeClass} mr-2"></i>${bodyText}
</${container}>
`
return output
}, {
async: true,
ends: true
})
// Adds a video with an optional caption
// Usage:
// {% zodvideo platform id %}
// content of caption
// {% endzodcaption %}
// Where:
// platform = [youtube|vimeo]
// id = the id of the video on the platform
// content = optional markdown content for the caption
hexo.extend.tag.register('zodvideo', function(args, content) {
var idArg = args[1]
var iframeSource = ""
var platformArg = args[0]
switch (platformArg) {
case 'youtube':
iframeSource = `https://www.youtube.com/embed/${idArg}`
break
case 'vimeo':
iframeSource = `https://player.vimeo.com/video/${idArg}`
break
}
var contentText = hexo.render.renderSync({
text: content,
engine: 'markdown'
}).slice(3, -5); // slice removes leading <p> and trailing </p>
// NOTE:
// This is the same content as generated by the nunjucks templates defined by icarus video tags.
// It may need updating when upgrading the icarus version.
var videoIcarusNunjucksContent =
`
<div class="video-container" style="padding-top:0">
<iframe src="${iframeSource}" frameborder="0" loading="lazy" allowfullscreen></iframe>
</div>
`
var videoHtml =
`
<div class="video-container" style="padding-top:0.49em">
${videoIcarusNunjucksContent}
</div>
`
// NOTE:
// This is a copy of the style from zodcaption.js.
// I didn't want to create a dependency on a nunjucks renderer engine just to remove the duplicate code.
var captionHtml = ""
if (contentText)
captionHtml = `<p class="has-text-centered is-size-6 caption" style="color: #7a7a7a;padding-top: 6px">${contentText}</p>`
var output = `${videoHtml}${captionHtml}`
return output
}, {
async: true,
ends: true
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment