feat: frontmatter
This commit is contained in:
46
awk/frontmatter.awk
Normal file
46
awk/frontmatter.awk
Normal file
@@ -0,0 +1,46 @@
|
||||
BEGIN {
|
||||
state = "start"
|
||||
}
|
||||
{
|
||||
if (state == "start") {
|
||||
if ($0 == "---") {
|
||||
state = "in_fm"
|
||||
next
|
||||
} else {
|
||||
state = "body"
|
||||
print
|
||||
next
|
||||
}
|
||||
}
|
||||
if (state == "in_fm") {
|
||||
if ($0 == "---") {
|
||||
state = "body"
|
||||
next
|
||||
}
|
||||
line = $0
|
||||
if (line ~ /^[[:space:]]*$/ || line ~ /^[[:space:]]*#/) next
|
||||
if (line !~ /=/) next
|
||||
|
||||
key = line
|
||||
val = line
|
||||
sub(/=.*/, "", key)
|
||||
sub(/[^=]*=/, "", val)
|
||||
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", key)
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", val)
|
||||
|
||||
if (val ~ /^".*"$/) {
|
||||
val = substr(val, 2, length(val) - 2)
|
||||
gsub(/\\"/, "\"", val)
|
||||
} else if (val ~ /^'.*'$/) {
|
||||
val = substr(val, 2, length(val) - 2)
|
||||
gsub(/\\'/, "'", val)
|
||||
}
|
||||
|
||||
if (fm_out != "") {
|
||||
print key "=" val >> fm_out
|
||||
}
|
||||
next
|
||||
}
|
||||
print
|
||||
}
|
||||
@@ -3,8 +3,14 @@ function strip_markdown(s) {
|
||||
gsub(/[*_`~]/, "", s)
|
||||
gsub(/[\[\]]/, "", s)
|
||||
gsub(/\([^\)]*\)/, "", s)
|
||||
s = tolower(s)
|
||||
gsub(/[^a-z0-9 -]/, "", s)
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", s)
|
||||
gsub(/[[:space:]]+/, "-", s)
|
||||
gsub(/-{2,}/, "-", s)
|
||||
gsub(/^-+|-+$/, "", s)
|
||||
if (length(s) > 80) s = substr(s, 1, 80)
|
||||
gsub(/-+$/, "", s)
|
||||
return s
|
||||
}
|
||||
function print_header(line) {
|
||||
|
||||
@@ -204,7 +204,7 @@ function render_embed(src, alt, has_alt, force_inline, ext, local_path, conte
|
||||
}
|
||||
if (is_audio_ext(ext)) return "<audio controls src=\"" src "\"></audio>"
|
||||
if (is_video_ext(ext)) return "<video controls src=\"" src "\"></video>"
|
||||
return "<iframe src=\"" src "\"></iframe>"
|
||||
return "<iframe src=\"" src "\" allowfullscreen></iframe>"
|
||||
}
|
||||
|
||||
if (is_image_ext(ext)) {
|
||||
@@ -223,7 +223,29 @@ function render_embed(src, alt, has_alt, force_inline, ext, local_path, conte
|
||||
}
|
||||
}
|
||||
|
||||
return "<iframe src=\"" src "\"></iframe>"
|
||||
return "<iframe src=\"" src "\" allowfullscreen></iframe>"
|
||||
}
|
||||
|
||||
function render_typed_embed(etype, src, alt, has_alt, local_path, content) {
|
||||
if (etype == "i") {
|
||||
if (has_alt) return "<img alt=\"" alt "\" src=\"" src "\" />"
|
||||
return "<img src=\"" src "\" />"
|
||||
}
|
||||
if (etype == "v") return "<video controls src=\"" src "\"></video>"
|
||||
if (etype == "a") return "<audio controls src=\"" src "\"></audio>"
|
||||
if (etype == "f") return "<iframe src=\"" src "\" allowfullscreen></iframe>"
|
||||
if (etype == "e") {
|
||||
if (!is_global_url(src)) {
|
||||
local_path = resolve_local_path(src)
|
||||
if (local_path != "") {
|
||||
content = read_file(local_path)
|
||||
if (content ~ /\n$/) sub(/\n$/, "", content)
|
||||
return content
|
||||
}
|
||||
}
|
||||
return render_embed(src, alt, has_alt, 1)
|
||||
}
|
||||
return render_embed(src, alt, has_alt, 0)
|
||||
}
|
||||
|
||||
function extract_attr(tag, attr, pat, m, token) {
|
||||
@@ -319,7 +341,7 @@ function apply_td_vertical_align(line, out, rest, seg, td_tag, img_tag, after
|
||||
return out rest
|
||||
}
|
||||
|
||||
function rewrite_img_tags(line, out, rest, tag, src, alt, force_inline_tag, pre, post, repl) {
|
||||
function rewrite_img_tags(line, out, rest, tag, src, alt, force_inline_tag, embed_type, pre, post, repl) {
|
||||
out = ""
|
||||
rest = line
|
||||
while (match(rest, /<img[^>]*\/?>/)) {
|
||||
@@ -329,7 +351,10 @@ function rewrite_img_tags(line, out, rest, tag, src, alt, force_inline_tag, p
|
||||
src = extract_attr(tag, "src")
|
||||
alt = extract_attr(tag, "alt")
|
||||
force_inline_tag = extract_attr(tag, "data-force-inline")
|
||||
if (is_image_ext(ext_of(src)) && force_inline_tag == "") {
|
||||
embed_type = extract_attr(tag, "data-embed-type")
|
||||
if (embed_type != "") {
|
||||
repl = render_typed_embed(embed_type, src, alt, (alt != ""))
|
||||
} else if (is_image_ext(ext_of(src)) && force_inline_tag == "") {
|
||||
# Preserve hand-written <img> attributes (style/class/etc) for normal images.
|
||||
repl = tag
|
||||
} else {
|
||||
|
||||
@@ -20,9 +20,11 @@ function mask_html_tags(s, out, rest, start, len, tag, token) {
|
||||
return out rest
|
||||
}
|
||||
|
||||
function restore_html_tags(s, i) {
|
||||
function restore_html_tags(s, i, val) {
|
||||
for (i = 1; i <= html_tag_count; i++) {
|
||||
gsub(html_tag_token[i], html_tag_value[i], s)
|
||||
val = html_tag_value[i]
|
||||
gsub(/&/, "\\\\&", val)
|
||||
gsub(html_tag_token[i], val, s)
|
||||
}
|
||||
return s
|
||||
}
|
||||
@@ -58,6 +60,36 @@ function restore_html_tags(s, i) {
|
||||
line = substr(line, 1, start - 1) repl substr(line, start + len)
|
||||
}
|
||||
|
||||
# typed embeds: !i, !v, !a, !f, !e
|
||||
while (match(line, /![ivafe]\[[^\]]*\]\([^\)]+ "[^"]*"\)/)) {
|
||||
start = RSTART; len = RLENGTH
|
||||
token = substr(line, start, len)
|
||||
etype = substr(token, 2, 1)
|
||||
match(token, /\[[^\]]*\]/); alt = substr(token, RSTART + 1, RLENGTH - 2)
|
||||
match(token, /"[^"]*"/); etitle = substr(token, RSTART + 1, RLENGTH - 2)
|
||||
match(token, /\([^\)]+/); inner = substr(token, RSTART + 1, RLENGTH - 1)
|
||||
sub(/[[:space:]]*"[^"]*"/, "", inner); src = inner
|
||||
repl = "<img data-embed-type=\"" etype "\" alt=\"" alt "\" src=\"" src "\" title=\"" etitle "\" />"
|
||||
line = substr(line, 1, start - 1) repl substr(line, start + len)
|
||||
}
|
||||
while (match(line, /![ivafe]\[[^\]]*\]\([^\)]+\)/)) {
|
||||
start = RSTART; len = RLENGTH
|
||||
token = substr(line, start, len)
|
||||
etype = substr(token, 2, 1)
|
||||
match(token, /\[[^\]]*\]/); alt = substr(token, RSTART + 1, RLENGTH - 2)
|
||||
match(token, /\([^\)]+/); src = substr(token, RSTART + 1, RLENGTH - 1)
|
||||
repl = "<img data-embed-type=\"" etype "\" alt=\"" alt "\" src=\"" src "\" />"
|
||||
line = substr(line, 1, start - 1) repl substr(line, start + len)
|
||||
}
|
||||
while (match(line, /![ivafe]\[[^\]]+\]/)) {
|
||||
start = RSTART; len = RLENGTH
|
||||
token = substr(line, start, len)
|
||||
etype = substr(token, 2, 1)
|
||||
src = substr(token, 4, len - 4)
|
||||
repl = "<img data-embed-type=\"" etype "\" src=\"" src "\" />"
|
||||
line = substr(line, 1, start - 1) repl substr(line, start + len)
|
||||
}
|
||||
|
||||
# force-inline image syntax (double bang)
|
||||
while (match(line, /!!\[[^\]]*\]\([^\)]+ "[^"]*"\)/)) {
|
||||
start = RSTART; len = RLENGTH
|
||||
|
||||
Reference in New Issue
Block a user