#!/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+"\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(/!\[(.*?)\]\((.*?)\)/,"\"\\1\"") # - 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 } }