From 4d4867ed7731c7aa70855e0b62913f442d35628c Mon Sep 17 00:00:00 2001 From: rodri Date: Sat, 10 Apr 2021 14:37:56 +0000 Subject: finally released to the world. --- bin/capitalize | 2 + bin/md2html.awk | 427 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ index.md | 25 ++++ lib/style | 147 +++++++++++++++++++ mkweb | 48 +++++++ readme.md | 40 ++++++ tpl/feet | 9 ++ tpl/head | 25 ++++ tpl/menu | 15 ++ 9 files changed, 738 insertions(+) create mode 100755 bin/capitalize create mode 100755 bin/md2html.awk create mode 100644 index.md create mode 100644 lib/style create mode 100755 mkweb create mode 100644 readme.md create mode 100644 tpl/feet create mode 100644 tpl/head create mode 100644 tpl/menu diff --git a/bin/capitalize b/bin/capitalize new file mode 100755 index 0000000..58b338b --- /dev/null +++ b/bin/capitalize @@ -0,0 +1,2 @@ +#!/bin/rc +awk '{for(i=1;i<=NF;i++)sub(/./,toupper(substr($i,1,1)),$i)}1' diff --git a/bin/md2html.awk b/bin/md2html.awk new file mode 100755 index 0000000..81d1241 --- /dev/null +++ b/bin/md2html.awk @@ -0,0 +1,427 @@ +#!/bin/awk -f +# +# by: Jesus Galan (yiyus) 2009 +# +# Usage: md2html.awk file.md > file.html +# See: http://4l77.com/src/md2html.awk + +function eschtml(t) { + gsub("&", "\\&", t); + gsub("<", "\\<", t); + return t; +} + +function oprint(t){ + if(nr == 0) + print t; + else + otext = otext "\n" t; +} + +function subref(id){ + for(; nr > 0 && sub("<<" id, ref[id], otext); nr--); + if(nr == 0 && otext) { + print otext; + otext = ""; + } +} + +function nextil(t) { + if(!match(t, /[`<&\[*_\\-]|(\!\[)/)) + return t; + t1 = substr(t, 1, RSTART - 1); + tag = substr(t, RSTART, RLENGTH); + t2 = substr(t, RSTART + RLENGTH); + if(ilcode && tag != "`") + return eschtml(t1 tag) nextil(t2); + # Backslash escaping + if(tag == "\\"){ + if(match(t2, /^[\\`*_{}\[\]()#+\-\.!]/)){ + tag = substr(t2, 1, 1); + t2 = substr(t2, 2); + } + return t1 tag nextil(t2); + } + # Dashes + if(tag == "-"){ + if(sub(/^-/, "", t2)) + tag = "—"; + return t1 tag nextil(t2); + } + # Inline Code + if(tag == "`"){ + if(sub(/^`/, "", t2)){ + if(!match(t2, /``/)) + return t1 "”" nextil(t2); + ilcode2 = !ilcode2; + } + else if(ilcode2) + return t1 tag nextil(t2); + tag = ""; + if(ilcode){ + t1 = eschtml(t1); + tag = ""; + } + ilcode = !ilcode; + return t1 tag nextil(t2); + } + if(tag == "<"){ + # Autolinks + if(match(t2, /^[^ ]+[\.@][^ ]+>/)){ + url = eschtml(substr(t2, 1, RLENGTH - 1)); + t2 = substr(t2, RLENGTH + 1); + linktext = url; + if(match(url, /@/) && !match(url, /^mailto:/)) + url = "mailto:" url; + return t1 "" linktext "" nextil(t2); + } + # Html tags + if(match(t2, /^[A-Za-z\/!][^>]*>/)){ + tag = tag substr(t2, RSTART, RLENGTH); + t2 = substr(t2, RLENGTH + 1); + return t1 tag nextil(t2); + } + return t1 "<" nextil(t2); + } + # Html special entities + if(tag == "&"){ + if(match(t2, /^#?[A-Za-z0-9]+;/)){ + tag = tag substr(t2, RSTART, RLENGTH); + t2 = substr(t2, RLENGTH + 1); + return t1 tag nextil(t2); + } + return t1 "&" nextil(t2); + } + # Images + if(tag == "!["){ + if(!match(t2, /(\[.*\])|(\(.*\))/)) + return t1 tag nextil(t2); + match(t2, /^[^\]]*/); + alt = substr(t2, 1, RLENGTH); + t2 = substr(t2, RLENGTH + 2); + if(match(t2, /^\(/)){ + # Inline + sub(/^\(/, "", t2); + match(t2, /^[^\)]+/); + url = eschtml(substr(t2, 1, RLENGTH)); + t2 = substr(t2, RLENGTH + 2); + title = ""; + if(match(url, /[ ]+\".*\"[ ]*$/)) { + title = substr(url, RSTART, RLENGTH); + url = substr(url, 1, RSTART - 1); + match(title, /\".*\"/); + title = " title=\"" substr(title, RSTART + 1, RLENGTH - 2) "\""; + } + if(match(url, /^<.*>$/)) + url = substr(url, 2, RLENGTH - 2); + return t1 "\""" nextil(t2); + } + else{ + # Referenced + sub(/^ ?\[/, "", t2); + id = alt; + if(match(t2, /^[^\]]+/)) + id = substr(t2, 1, RLENGTH); + t2 = substr(t2, RLENGTH + 2); + if(ref[id]) + r = ref[id]; + else{ + r = "<<" id; + nr++; + } + return t1 "\""" nextil(t2); + } + } + # Links + if(tag == "["){ + if(!match(t2, /(\[.*\])|(\(.*\))/)) + return t1 tag nextil(t2); + match(t2, /^[^\]]*(\[[^\]]*\][^\]]*)*/); + linktext = substr(t2, 1, RLENGTH); + t2 = substr(t2, RLENGTH + 2); + if(match(t2, /^\(/)){ + # Inline + match(t2, /^[^\)]+(\([^\)]+\)[^\)]*)*/); + url = substr(t2, 2, RLENGTH - 1); + pt2 = substr(t2, RLENGTH + 2); + title = ""; + if(match(url, /[ ]+\".*\"[ ]*$/)) { + title = substr(url, RSTART, RLENGTH); + url = substr(url, 1, RSTART - 1); + match(title, /\".*\"/); + title = " title=\"" substr(title, RSTART + 1, RLENGTH - 2) "\""; + } + if(match(url, /^<.*>$/)) + url = substr(url, 2, RLENGTH - 2); + url = eschtml(url); + return t1 "" nextil(linktext) "" nextil(pt2); + } + else{ + # Referenced + sub(/^ ?\[/, "", t2); + id = linktext; + if(match(t2, /^[^\]]+/)) + id = substr(t2, 1, RLENGTH); + t2 = substr(t2, RLENGTH + 2); + if(ref[id]) + r = ref[id]; + else{ + r = "<<" id; + nr++; + } + pt2 = t2; + return t1 "" nextil(linktext) "" nextil(pt2); + } + } + # Emphasis + if(match(tag, /[*_]/)){ + ntag = tag; + if(sub("^" tag, "", t2)){ + if(stag[ns] == tag && match(t2, "^" tag)) + t2 = tag t2; + else + ntag = tag tag + } + n = length(ntag); + tag = (n == 2) ? "strong" : "em"; + if(match(t1, / $/) && match(t2, /^ /)) + return t1 tag nextil(t2); + if(stag[ns] == ntag){ + tag = "/" tag; + ns--; + } + else + stag[++ns] = ntag; + tag = "<" tag ">"; + return t1 tag nextil(t2); + } +} + +function inline(t) { + ilcode = 0; + ilcode2 = 0; + ns = 0; + + return nextil(t); +} + +function printp(tag) { + if(!match(text, /^[ ]*$/)){ + text = inline(text); + if(tag != "") + oprint("<" tag ">" text ""); + else + oprint(text); + } + text = ""; +} + +BEGIN { + blank = 0; + code = 0; + hr = 0; + html = 0; + nl = 0; + nr = 0; + otext = ""; + text = ""; + par = "p"; +} + +# References +!code && /^ *\[[^\]]*\]:[ ]+/ { + sub(/^ *\[/, ""); + match($0, /\]/); + id = substr($0, 1, RSTART - 1); + sub(id "\\]:[ ]+", ""); + title = ""; + if(match($0, /\".*\"$/)) + title = "\" title=\"" substr($0, RSTART + 1, RLENGTH - 2); + sub(/[ ]+\".*\"$/, ""); + url = eschtml($0); + ref[id] = url title; + + subref(id); + next; +} + +# html +!html && /^<(address|blockquote|center|dir|div|dl|fieldset|form|h[1-6r]|\ +isindex|menu|noframes|noscript|ol|p|pre|table|ul|!--)/ { + if(code) + oprint(""); + for(; !text && block[nl] == "blockquote"; nl--) + oprint(""); + match($0, /^<(address|blockquote|center|dir|div|dl|fieldset|form|h[1-6r]|\ + isindex|menu|noframes|noscript|ol|p|pre|table|ul|!--)/); + htag = substr($0, 2, RLENGTH - 1); + if(!match($0, "(<\\/" htag ">)|((^
$)")) + html = 1; + if(html && match($0, /^
$/ || +(hr && />$/)) { + html = 0; + hr = 0; + oprint($0); + next; +} + +html { + oprint($0); + next; +} + +# List and quote blocks + +# Remove indentation +{ + for(nnl = 0; nnl < nl; nnl++) + if((match(block[nnl + 1], /[ou]l/) && !sub(/^( | )/, "")) || \ + (block[nnl + 1] == "blockquote" && !sub(/^> ?/, ""))) + break; +} +nnl < nl && !blank && text && ! /^ ? ? ?([*+-]|([0-9]+\.)+)( +| )/ { nnl = nl; } +# Quote blocks +{ + while(sub(/^> /, "")) + nblock[++nnl] = "blockquote"; +} +# Horizontal rules +{ hr = 0; } +(blank || (!text && !code)) && /^ ? ? ?([-*_][ ]*)([-*_][ ]*)([-*_][ ]*)+$/ { + if(code){ + oprint(""); + code = 0; + } + blank = 0; + nnl = 0; + hr = 1; +} +# List items +block[nl] ~ /[ou]l/ && /^$/ { + blank = 1; + next; +} +{ newli = 0; } +!hr && (nnl != nl || !text || block[nl] ~ /[ou]l/) && /^ ? ? ?[*+-]( +| )/ { + sub(/^ ? ? ?[*+-]( +| )/, ""); + nnl++; + nblock[nnl] = "ul"; + newli = 1; +} +(nnl != nl || !text || block[nl] ~ /[ou]l/) && /^ ? ? ?([0-9]+\.)+( +| )/ { + sub(/^ ? ? ?([0-9]+\.)+( +| )/, ""); + nnl++; + nblock[nnl] = "ol"; + newli = 1; +} +newli { + if(blank && nnl == nl && !par) + par = "p"; + blank = 0; + printp(par); + if(nnl == nl && block[nl] == nblock[nl]) + oprint("
  • "); +} +blank && ! /^$/ { + if(match(block[nnl], /[ou]l/) && !par) + par = "p"; + printp(par); + par = "p"; + blank = 0; +} + +# Close old blocks and open new ones +nnl != nl || nblock[nl] != block[nl] { + if(code){ + oprint(""); + code = 0; + } + printp(par); + b = (nnl > nl) ? nblock[nnl] : block[nnl]; + par = (match(b, /[ou]l/)) ? "" : "p"; +} +nnl < nl || (nnl == nl && nblock[nl] != block[nl]) { + for(; nl > nnl || (nnl == nl && pblock[nl] != block[nl]); nl--){ + if(match(block[nl], /[ou]l/)) + oprint("
  • "); + oprint(""); + } +} +nnl > nl { + for(; nl < nnl; nl++){ + block[nl + 1] = nblock[nl + 1]; + oprint("<" block[nl + 1] ">"); + if(match(block[nl + 1], /[ou]l/)) + oprint("
  • "); + } +} +hr { + oprint("
    "); + next; +} + +# Code blocks +code && /^$/ { + if(blanK) + oprint(""); + blank = 1; + next; +} +!text && sub(/^( | )/, "") { + if(blanK) + oprint(""); + blank = 0; + if(!code) + oprint("
    ");
    +	code = 1;
    +	$0 = eschtml($0);
    +	oprint($0);
    +	next;
    +}
    +code {
    +	oprint("
    "); + code = 0; +} + +# Setex-style Headers +text && /^=+$/ {printp("h1"); next;} +text && /^-+$/ {printp("h2"); next;} + +# Atx-Style headers +/^#+/ && (!newli || par=="p" || /^##/) { + for(n = 0; n < 6 && sub(/^# */, ""); n++) + sub(/#$/, ""); + par = "h" n; +} + +# Paragraph +/^$/ { + printp(par); + par = "p"; + next; +} + +# Add text +{ text = (text ? text " " : "") $0; } + +END { + if(code){ + oprint(""); + code = 0; + } + printp(par); + for(; nl > 0; nl--){ + if(match(block[nl], /[ou]l/)) + oprint("
  • "); + oprint(""); + } + gsub(/<<[^\"]*/, "", otext); + print(otext); +} diff --git a/index.md b/index.md new file mode 100644 index 0000000..12eb232 --- /dev/null +++ b/index.md @@ -0,0 +1,25 @@ +# The Matrix + +Do not try and bend the spoon, that's impossible. Instead, only try +to realize the truth... There is no spoon... Then you'll see that it +is not the spoon that bends, it is only *yourself*. + +# Colette + +Words are deceptive little bastards. + +# Earthquake Bird + +> _L_: Just trying to make conversation. + +> _T_: Why? + +> _L_: Because that's what normal people do. + +> _T_: But you are not normal. + +> _L_: Neither are you. + +> _T_: So let's not pretend to be. + +> _L_: Okay. diff --git a/lib/style b/lib/style new file mode 100644 index 0000000..7be863f --- /dev/null +++ b/lib/style @@ -0,0 +1,147 @@ +body { + color: black; + background-color: gray; + font-family: lexend, vga8, sans-serif; + margin: 2% 6%; + margin-right: 9em; +} +#atl { + border: 4px solid #8888cc; + background-color: #eaffff; +} +#atl ::selection { background: #9eeeee; } +#atl img { + float: left; + margin: 5px 10px 5px 5px; +} +#atl h1 { + font-family: lexend, vga8, sans-serif; + font-weight: 400; + text-align: left; +} +#main { + border: 4px solid #99994c; + background-color: #ffffea; + padding: 1em; + margin: 5px 0 5px 0; +} +#main ::selection { background: #eeee9e; } +h1 { + text-align: center; + font-weight: 300; +} +h2, h3, h4 { + margin: 2pt; + margin-top: 1em; +} +hr { border: 1px solid #428a42; } +/* ul { margin: 1pt; } This breaks IE */ +li { padding: 1pt; } +p.para { +} +pre { + margin-left: 2em; + border : 2px +} +code, pre { + font-family: roboto, vga8, monospace; +} +a { + text-decoration-style: dotted; + color: inherit; +} +a:hover { + text-decoration: none; + background-color: black; + color: white; +} +div.banner { + margin: 0; + line-height: 1.1; + text-align: center; + position: absolute; /* Fallback if 'fixed' is not supported */ + top: 2%; + right: 1em; + left: auto; + width: 6.5em; + z-index: 1000; +} +div.banner ul { + margin: 0px; + list-style-type: none; + list-style-position: outside; + padding: 0.1em 0.1em; + font-family: vga8, sans-serif; + background-color: #eaffea; + border: 2px solid #88cc88; + color: black; +} +.banner ul li { margin: 0px; } +.banner ul a { + display: block; + text-decoration: none; + background-color: transparent; + font-weight: 400; +} +.banner ul a:hover { + color: #eaffea; + background-color: #448844; +} +.banner img { + border: 0px; + padding: 4pt; +} +.banner_sep { display: none; /* hide from non-css browsers */ } +blockquote { + position: relative; + width: 70%; + padding: 1em 1.5em; + margin: 2em auto; + color: black; + background: #ffffca; + overflow: hidden; +} +blockquote::before { + content: ""; + position: absolute; + top: 0; + right: 0; + border-width: 0 16px 16px 0; + border-style: solid; + border-color: #eeee4c #ffffea; + background: #eeee4c; + box-shadow: 0 1px 5px rgba(0,0,0,0.3), -1px 1px 2px rgba(0,0,0,0.2); + display: block; + width: 0; +} +.footer_sep { + border: 0px solid black; + /*border-bottom: 1px solid black;*/ + padding-top: 5pt; + +} +.footer { + color: white; + text-align: center; + padding: 2pt; + font-size: 80%; +} +.footer a { + text-decoration: none; +} +.footer img { border: none; } +/* dissabled stuff */ +#top_sidebar_link { display: none; } +* { cursor: url(/pic/cursor.png), auto; } +@font-face { + font-family: "vga8"; + src: url(/lib/font/vga8.ttf) format("truetype"); +} +@font-face { + font-family: "lexend"; + src: url(/lib/font/lexend.ttf) format("truetype"); +} +@font-face { + font-family: "roboto"; + src: url(/lib/font/roboto.ttf) format("truetype"); +} diff --git a/mkweb b/mkweb new file mode 100755 index 0000000..d29cc05 --- /dev/null +++ b/mkweb @@ -0,0 +1,48 @@ +#!/bin/rc +rfork en +filter='^(bin|lib|pic|tpl)' +sections=`{walk -d | grep -v $filter} + +fn entitle { + basename $1 | sed 's/-/ /g' | bin/capitalize +} + +fn usage { + echo usage: $0 [ -m ] [ -s section ] >[1=2] + exit usage +} + +fn buildsection { + if(test -f $1/index.md) + >$1/index.html { + if(! ~ $1 .){ + title=`{entitle $1} + [^<]*)/\1 - '^$"title^'/' + } + if not cat tpl/head + cat tpl/menu \ + <{bin/md2html.awk $1/index.md}\ + tpl/feet + } +} + +if(! ~ $#* 0) + switch($1){ + case -m + >sitemap.txt { + site=http://rgl.antares-labs.eu + echo $site/index.html + for(d in $sections) + echo $site/$d/index.html + } + case -s + if(~ $#2 0) + usage + buildsection $2 + case -* + usage + } +if not + for(d in $sections .){ + buildsection $d + } diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..30a6300 --- /dev/null +++ b/readme.md @@ -0,0 +1,40 @@ +# mkweb + +Mkweb is a very little framework I've developed for the last four +years based on markdown files. +It started as an actual `mkfile` (of which there was a `Makefile` +translation for UNIX™ systems) and turned into a standalone +[rc(1)](http://man.9front.org/1/rc) script over time. + +I've been meaning to release it for a long time now. + +_I know there are many like it, but this one is mine_. + +## Usage + +The script is quite simple and, since you will have to modify it +whether you want to or not, I recommend you take a peek before we +continue. + +Alright, see? there are three variables you need to keep track of: +`filter`, `sections` and `site`. The `filter` is a +[regexp(6)](http://man.9front.org/6/regexp) used to exclude files from +`sections`, a list of folders possibly holding an `index.md`, which +would otherwise crawl into the depths of every directory there is. +`site` is the root URL of your website, it's only used for generating +the sitemap file (ab)used by some bots out there. + +Every time you create a section and add an `index.md` to it, you must +run `mkweb` to generate the entire site, or you can also just `mkweb +-s path/to/newsection` to process your new webshit. + +This process will translate the markdown file into html, while +attaching to it a head, a menu and some feet (see `tpl/`) to make a +proper document. + +And that's it. All the hypertexting is done by yiyus' `md2html.awk`, +which could be replaced by discount or any other translator of your +choice, doesn't even need to be a markdown one (Wikitext, AsciiDoc, +BBCode are all easy to plug in). + +Enjoy! diff --git a/tpl/feet b/tpl/feet new file mode 100644 index 0000000..abf52e8 --- /dev/null +++ b/tpl/feet @@ -0,0 +1,9 @@ + + +
    +Copyright © 2015-2021 Rodrigo G. López. No rights reserved. +
    + + + + diff --git a/tpl/head b/tpl/head new file mode 100644 index 0000000..5012a80 --- /dev/null +++ b/tpl/head @@ -0,0 +1,25 @@ + + + + + + + + + +rodri's place + + + +
    + +

    rodri's place

    +
    +
    diff --git a/tpl/menu b/tpl/menu new file mode 100644 index 0000000..4737d14 --- /dev/null +++ b/tpl/menu @@ -0,0 +1,15 @@ + -- cgit v1.2.3