Ruby CGI scripts that I used to set up my website https://yessiest.512mb.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

160 lines
4.6 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. #!/usr/bin/ruby
  2. #
  3. #Copyright 2022 Yessiest (yessiest@memeware.net)
  4. #
  5. #Licensed under the Apache License, Version 2.0 (the "License");
  6. #you may not use this file except in compliance with the License.
  7. #You may obtain a copy of the License at
  8. #
  9. #http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. #Unless required by applicable law or agreed to in writing, software
  12. #distributed under the License is distributed on an "AS IS" BASIS,
  13. #WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. #See the License for the specific language governing permissions and
  15. #limitations under the License.
  16. # Ruby CGI module to produce human-readable HTML from markdown pages
  17. # Variables
  18. ROOT_PATH="/www/"
  19. TAB_MULTIPLIER=10
  20. TAB_UNIT="px"
  21. QUOTE_TAB=4
  22. TEMPLATE_PRE="template.pre.html"
  23. TEMPLATE_POST="template.post.html"
  24. TEMPLATE_CSS="template.css"
  25. # Script
  26. require 'cgi'
  27. cgi = CGI.new("html5")
  28. def ident(ident)
  29. return "<span style=\"margin-left: #{(ident*TAB_MULTIPLIER).to_s+TAB_UNIT}\">"
  30. end
  31. def _parse_list(text,mode=["ul",/ *-/])
  32. new_text = ""
  33. list_started = false
  34. text.each_line do |line|
  35. starts = line.start_with?(mode[1])
  36. l_ident = line.match(/ */)[0].length
  37. if (not list_started) and (starts) then
  38. list_started = true
  39. new_text=new_text+"<#{mode[0]}>\n<li>#{ident l_ident}\n"+line.gsub(mode[1],"")+"</span></li>\n"
  40. elsif (list_started) and (not starts) then
  41. list_started = false
  42. new_text=new_text+"</#{mode[0]}>\n"+line
  43. elsif (list_started) and (starts) then
  44. new_text = new_text+"<li>#{ident l_ident}\n"+line.gsub(mode[1],"")+"</span></li>\n"
  45. else
  46. new_text = new_text+line
  47. end
  48. end
  49. return new_text
  50. end
  51. def _env(text,env)
  52. return text
  53. .gsub(/(?<!\\)\$PATH/,env["PATH"])
  54. .gsub(/(?<!\\)\$FILE/,env["FILE"])
  55. .gsub(/(?<!\\)\$CRUMB/,env["CRUMB"])
  56. end
  57. template_css = ""
  58. template_pre = ""
  59. template_post = ""
  60. if File::exists?( ROOT_PATH+TEMPLATE_CSS ) then
  61. template_css = "<link rel=\"stylesheet\" href=\"#{TEMPLATE_CSS}\">\n"
  62. end
  63. if File::exists?( ROOT_PATH+TEMPLATE_PRE) then
  64. template_pre_f = File.new( ROOT_PATH+TEMPLATE_PRE, "r")
  65. template_pre = template_pre_f.read
  66. template_pre_f.close
  67. end
  68. if File::exists?( ROOT_PATH+TEMPLATE_POST) then
  69. template_post_f = File.new( ROOT_PATH+TEMPLATE_POST, "r")
  70. template_post = template_post_f.read
  71. template_post_f.close
  72. end
  73. doc = "---
  74. # Error 404: Document not available
  75. Document you requested is not available
  76. ---"
  77. # Absolutely containing the script to the ROOT_PATH and making it only read .md
  78. if cgi["docfile"].end_with?(".md") and
  79. (File.absolute_path(ROOT_PATH+cgi["docfile"]).start_with?(ROOT_PATH)) and
  80. File::exists?( ROOT_PATH+cgi["docfile"] ) then
  81. docfile = File.new(ROOT_PATH+cgi["docfile"],"r")
  82. doc = docfile.read
  83. docfile.close
  84. end
  85. content = cgi.body {
  86. doc = "\n"+CGI.escapeHTML(doc)
  87. # Extra
  88. # - Horizontal rule
  89. doc = doc.gsub(/-{3,}/,"<hr />")
  90. # - Linebreak
  91. doc = doc.gsub("\n\n","<br />\n")
  92. # Parse lists
  93. # - Unordered lists
  94. doc = _parse_list(doc)
  95. # - Ordered lists
  96. doc = _parse_list(doc,mode = ["ol",/ *\d*\./])
  97. # Bounded markup
  98. # - Bold/Italics
  99. doc = doc.gsub(/(?<!\\)\*{3}(.*?)(?<!\\)\*{3}/m,"<i><b>\\1</b></i>")
  100. doc = doc.gsub(/(?<!\\)\*{2}(.*?)(?<!\\)\*{2}/m,"<b>\\1</b>")
  101. doc = doc.gsub(/(?<!\\)\*{1}(.*?)(?<!\\)\*{1}/m,"<i>\\1</i>")
  102. # - Underline
  103. doc = doc.gsub(/(?<!\\)_(.*?)_(?<!\\)/m,"<span style=\"text-decoration:underline;\">\\1</span>")
  104. # - Strikethrough
  105. doc = doc.gsub(/(?<!\\)~(.*?)~(?<!\\)/m,"<strike>\\1</strike>")
  106. # Unbounded (line) markup
  107. # - Headers
  108. doc = doc.gsub(/(?<=\n)\#{4} ?(.*)/,"<h4>\\1</h4>")
  109. doc = doc.gsub(/(?<=\n)\#{3} ?(.*)/,"<h3>\\1</h3>")
  110. doc = doc.gsub(/(?<=\n)\#{2} ?(.*)/,"<h2>\\1</h2>")
  111. doc = doc.gsub(/(?<=\n)\# ?(.*)/,"<h1>\\1</h1>")
  112. # - Quote
  113. doc = doc.gsub(/(?<=\n)&gt;(.*)/,"#{ident QUOTE_TAB}<span class=\"quote\">\\1</span></span>")
  114. # Links
  115. # - Images
  116. doc = doc.gsub(/!\[(.*?)\]\((.*?)\)/,"<img src=\"\\2\" alt=\"\\1\" />")
  117. # - Hyperlinks
  118. doc = doc.gsub(/\[(.*?)\]\((.*?)\)/,"<a href=\"\\2\">\\1</a>")
  119. # Code blocks
  120. # - Full block
  121. doc = doc.gsub(/(?<!\\)`{3}(.*?)(?<!\\)`{3}/m,"<pre><code class=\"codeblock\">\n\\1</pre></code>")
  122. # - Inline block
  123. doc = doc.gsub(/(?<!\\)`{2}(.*?)(?<!\\)`{2}/m,"<code class=\"codeinline\">\\1</code>")
  124. env = {
  125. "PATH" => cgi["docfile"].match("^(.*?)/?[^/]*$")[1].gsub(ROOT_PATH,""),
  126. "FILE" => cgi["docfile"].match("[^/]*$")[0],
  127. "CRUMB" => cgi["docfile"].gsub("/"," / ")
  128. }
  129. _env(template_pre,env)+"\n"+
  130. doc+"\n"+
  131. _env(template_post,env)+"\n"
  132. }
  133. cgi.out {
  134. cgi.html {
  135. cgi.head { "\n"+
  136. cgi.title { cgi["docfile"].gsub(/.md$/,"") }+"\n"+
  137. template_css
  138. } +
  139. content
  140. }
  141. }