166 lines
3.9 KiB
Awk
Executable File
166 lines
3.9 KiB
Awk
Executable File
#!/usr/bin/awk
|
|
|
|
BEGIN {
|
|
env = "none"
|
|
stack_pointer = 0
|
|
push(env)
|
|
}
|
|
|
|
# Function to push a value onto the stack
|
|
function push(value) {
|
|
stack_pointer++
|
|
stack[stack_pointer] = value
|
|
}
|
|
|
|
# Function to pop a value from the stack (LIFO)
|
|
function pop() {
|
|
if (stack_pointer > 0) {
|
|
value = stack[stack_pointer]
|
|
delete stack[stack_pointer]
|
|
stack_pointer--
|
|
return value
|
|
} else {
|
|
return "empty"
|
|
}
|
|
}
|
|
|
|
# Function to get last value in LIFO
|
|
function last() {
|
|
return stack[stack_pointer]
|
|
}
|
|
|
|
function replaceInline(line, result, start, end) {
|
|
# Replace occurrences of **...** with <strong>...</strong>
|
|
while (match(line, /\*\*([^*]+)\*\*/)) {
|
|
start = RSTART
|
|
end = RSTART + RLENGTH - 1
|
|
# Build the result: before match, <strong>, content, </strong>, after match
|
|
line = substr(line, 1, start-1) "<strong>" substr(line, start+2, RLENGTH-4) "</strong>" substr(line, end+1)
|
|
}
|
|
|
|
# Replace occurrences of *...* with <em>...</em>
|
|
while (match(line, /\*([^*]+)\*/)) {
|
|
start = RSTART
|
|
end = RSTART + RLENGTH - 1
|
|
# Build the result: before match, <em>, content, </em>, after match
|
|
line = substr(line, 1, start-1) "<em>" substr(line, start+1, RLENGTH-2) "</em>" substr(line, end+1)
|
|
}
|
|
|
|
# Replace occurances of [link](url) with <a href="url">link</<a>
|
|
while (match(line, /\[([^\]]+)\]\([^\)]+\)/)) {
|
|
start = RSTART
|
|
end = RSTART + RLENGTH - 1
|
|
matched = substr($0, RSTART, RLENGTH)
|
|
if (match(matched, /\[([^\]]+)\]/)) {
|
|
matched_link = substr(matched, RSTART+1, RLENGTH-2)
|
|
}
|
|
if (match(matched, /\([^\)]+\)/)) {
|
|
matched_url = substr(matched, RSTART+1, RLENGTH-2)
|
|
}
|
|
# Build the result: before match, <a href="url">, content, </a>, after match
|
|
line = substr(line, 1, start-1) "<a href=\"" matched_url "\">" matched_link "</a>" substr(line, end+1)
|
|
}
|
|
|
|
return line
|
|
}
|
|
|
|
|
|
function closeOne() {
|
|
env = pop()
|
|
print "</" env ">"
|
|
}
|
|
|
|
# Matching headers
|
|
/^#+ / {
|
|
match($0, /#+ /);
|
|
n = RLENGTH;
|
|
print "<h" n-1 ">" substr($0, n + 1) "</h" n-1 ">"
|
|
}
|
|
|
|
# Matching blockquotes
|
|
/^> / {
|
|
env = last()
|
|
if (env == "blockquote")
|
|
{
|
|
# In a blockquote block only print the text
|
|
print substr($0, 3);
|
|
} else {
|
|
# Otherwise, init the blockquote block
|
|
push("blockquote")
|
|
print "<blockquote>\n" substr($0, 3)
|
|
}
|
|
}
|
|
|
|
# Matching unordered lists
|
|
/^[-+*] / {
|
|
env = last()
|
|
if (env == "ul" ) {
|
|
# In a unordered list block, print a new item
|
|
print "<li>" replaceInline(substr($0, 3)) "</li>"
|
|
} else {
|
|
# Otherwise, init the unordered list block
|
|
push("ul")
|
|
print "<ul>\n<li>" replaceInline(substr($0, 3)) "</li>"
|
|
}
|
|
}
|
|
|
|
# Matching ordered lists
|
|
/^[0-9]+\./ {
|
|
env = last()
|
|
if (env == "ol") {
|
|
# In a ordered list block, print a new item
|
|
print "<li>" substr($0, 4) "</li>"
|
|
} else {
|
|
# Otherwise, init the ordered list block
|
|
push("ol")
|
|
print "<ol>\n<li>" substr($0, 4) "</li>"
|
|
}
|
|
}
|
|
|
|
# Matching code block
|
|
/^( |\t)/ {
|
|
env = last()
|
|
match($0, /( |\t)/);
|
|
n = RLENGTH;
|
|
if (env == "code") {
|
|
# In a code block, print a new item
|
|
print substr($0, n+1)
|
|
} else {
|
|
# Otherwise, init the code block
|
|
push("pre")
|
|
push("code")
|
|
print "<pre><code>" substr($0, n+1)
|
|
}
|
|
}
|
|
|
|
|
|
# Matching a simple paragraph
|
|
!/^(#|\*|-|\+|>|`|$|\t| )/ {
|
|
env = last()
|
|
if (env == "none") {
|
|
# If no block, print a paragraph
|
|
print "<p>" replaceInline($0) "</p>"
|
|
} else if (env == "blockquote") {
|
|
print $0
|
|
}
|
|
}
|
|
|
|
$0 == "" {
|
|
env = last()
|
|
while (env != "none") {
|
|
env = pop()
|
|
print "</" env ">"
|
|
env = last()
|
|
}
|
|
}
|
|
|
|
|
|
END {
|
|
env = last()
|
|
while (env != "none") {
|
|
env = pop()
|
|
print "</" env ">"
|
|
env = last()
|
|
}
|
|
}
|