#!/usr/bin/ruby
#
#Copyright 2022 Yessiest (yessiest@memeware.net)
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
#http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
# Ruby CGI module to produce human-readable HTML from markdown pages
# Variables
ROOT_PATH="/www/"
TAB_MULTIPLIER=10
TAB_UNIT="px"
QUOTE_TAB=4
TEMPLATE_PRE="template.pre.html"
TEMPLATE_POST="template.post.html"
TEMPLATE_CSS="template.css"
# Script
require 'cgi'
cgi = CGI.new("html5")
def ident(ident)
return ""
end
def _parse_list(text,mode=["ul",/ *-/])
new_text = ""
list_started = false
text.each_line do |line|
starts = line.start_with?(mode[1])
l_ident = line.match(/ */)[0].length
if (not list_started) and (starts) then
list_started = true
new_text=new_text+"<#{mode[0]}>\n#{ident l_ident}\n"+line.gsub(mode[1],"")+"\n"
elsif (list_started) and (not starts) then
list_started = false
new_text=new_text+"#{mode[0]}>\n"+line
elsif (list_started) and (starts) then
new_text = new_text+"
#{ident l_ident}\n"+line.gsub(mode[1],"")+"\n"
else
new_text = new_text+line
end
end
return new_text
end
def _env(text,env)
return text
.gsub(/(?\n"
end
if File::exists?( ROOT_PATH+TEMPLATE_PRE) then
template_pre_f = File.new( ROOT_PATH+TEMPLATE_PRE, "r")
template_pre = template_pre_f.read
template_pre_f.close
end
if File::exists?( ROOT_PATH+TEMPLATE_POST) then
template_post_f = File.new( ROOT_PATH+TEMPLATE_POST, "r")
template_post = template_post_f.read
template_post_f.close
end
doc = "---
# Error 404: Document not available
Document you requested is not available
---"
# Absolutely containing the script to the ROOT_PATH and making it only read .md
if cgi["docfile"].end_with?(".md") and
(File.absolute_path(ROOT_PATH+cgi["docfile"]).start_with?(ROOT_PATH)) and
File::exists?( ROOT_PATH+cgi["docfile"] ) then
docfile = File.new(ROOT_PATH+cgi["docfile"],"r")
doc = docfile.read
docfile.close
end
content = cgi.body {
doc = "\n"+CGI.escapeHTML(doc)
# Extra
# - Horizontal rule
doc = doc.gsub(/-{3,}/,"
")
# - Linebreak
doc = doc.gsub("\n\n","
\n")
# Parse lists
# - Unordered lists
doc = _parse_list(doc)
# - Ordered lists
doc = _parse_list(doc,mode = ["ol",/ *\d*\./])
# Bounded markup
# - Bold/Italics
doc = doc.gsub(/(?\\1")
doc = doc.gsub(/(?\\1")
doc = doc.gsub(/(?\\1")
# - Underline
doc = doc.gsub(/(?\\1")
# - Strikethrough
doc = doc.gsub(/(?\\1")
# Unbounded (line) markup
# - Headers
doc = doc.gsub(/(?<=\n)\#{4} ?(.*)/,"\\1
")
doc = doc.gsub(/(?<=\n)\#{3} ?(.*)/,"\\1
")
doc = doc.gsub(/(?<=\n)\#{2} ?(.*)/,"\\1
")
doc = doc.gsub(/(?<=\n)\# ?(.*)/,"\\1
")
# - Quote
doc = doc.gsub(/(?<=\n)>(.*)/,"#{ident QUOTE_TAB}\\1")
# Links
# - Images
doc = doc.gsub(/!\[(.*?)\]\((.*?)\)/,"")
# - Hyperlinks
doc = doc.gsub(/\[(.*?)\]\((.*?)\)/,"\\1")
# Code blocks
# - Full block
doc = doc.gsub(/(?\n\\1
")
# - Inline block
doc = doc.gsub(/(?\\1")
env = {
"PATH" => cgi["docfile"].match("^(.*?)/?[^/]*$")[1].gsub(ROOT_PATH,""),
"FILE" => cgi["docfile"].match("[^/]*$")[0],
"CRUMB" => cgi["docfile"].gsub("/"," / ")
}
_env(template_pre,env)+"\n"+
doc+"\n"+
_env(template_post,env)+"\n"
}
cgi.out {
cgi.html {
cgi.head { "\n"+
cgi.title { cgi["docfile"].gsub(/.md$/,"") }+"\n"+
template_css
} +
content
}
}