From 78310b7fb17976d6b8c9448d0dcd5a4368300948 Mon Sep 17 00:00:00 2001 From: mischief Date: Tue, 25 Mar 2014 00:58:46 -0700 Subject: [PATCH] initial commit --- .hgignore | 2 + main.go | 363 ++++++++++++++++++++ werc/etc/config.json | 4 + werc/lib/base.html | 64 ++++ werc/lib/directory.html | 7 + werc/lib/footer.html | 2 + werc/lib/menu.html | 15 + werc/lib/text.html | 4 + werc/lib/topbar.html | 11 + werc/pub/style/style.css | 0 werc/sites/offblast.org/_werc/config.json | 4 + werc/sites/offblast.org/_werc/pub/style.css | 332 ++++++++++++++++++ werc/sites/offblast.org/foo/bar.md | 67 ++++ werc/sites/offblast.org/index.md | 5 + werc/sites/offblast.org/test/apage.md | 3 + werc/sites/offblast.org/test/coolhtml.html | 2 + werc/sites/offblast.org/test/file.txt | 3 + werc/sites/offblast.org/test/index.md | 5 + 18 files changed, 893 insertions(+) create mode 100644 .hgignore create mode 100644 main.go create mode 100644 werc/etc/config.json create mode 100644 werc/lib/base.html create mode 100644 werc/lib/directory.html create mode 100644 werc/lib/footer.html create mode 100644 werc/lib/menu.html create mode 100644 werc/lib/text.html create mode 100644 werc/lib/topbar.html create mode 100644 werc/pub/style/style.css create mode 100644 werc/sites/offblast.org/_werc/config.json create mode 100644 werc/sites/offblast.org/_werc/pub/style.css create mode 100644 werc/sites/offblast.org/foo/bar.md create mode 100644 werc/sites/offblast.org/index.md create mode 100644 werc/sites/offblast.org/test/apage.md create mode 100644 werc/sites/offblast.org/test/coolhtml.html create mode 100644 werc/sites/offblast.org/test/file.txt create mode 100644 werc/sites/offblast.org/test/index.md diff --git a/.hgignore b/.hgignore new file mode 100644 index 0000000..72cf6d1 --- /dev/null +++ b/.hgignore @@ -0,0 +1,2 @@ +gowerc + diff --git a/main.go b/main.go new file mode 100644 index 0000000..2fbbb89 --- /dev/null +++ b/main.go @@ -0,0 +1,363 @@ +package main + +import ( + "bytes" + "encoding/json" + "flag" + "fmt" + "github.com/russross/blackfriday" + "html/template" + "io/ioutil" + "log" + "net/http" + "os" + "path/filepath" + "strings" + "time" +) + +var ( + listen = flag.String("l", ":8080", "set http listener to [ip]:port") + root = flag.String("root", "werc", "werc webroot") +) + +type WercConfig struct { + MasterSite string + Title string + Subtitle string +} + +type WercPage struct { + Title string // title + Menu []MenuEntry // menu entries + Content template.HTML // inner page content + Config WercConfig // site-specific config +} + +type MenuEntry struct { + Name string + Path string + This bool + Sub []MenuEntry +} + +type Werc struct { + root string + conf WercConfig + tmpl *template.Template +} + +func New(root string) *Werc { + w := new(Werc) + w.root = root + w.tmpl = template.Must(template.ParseGlob(root + "/lib/*.html")) + + b, err := ioutil.ReadFile(root + "/etc/config.json") + if err != nil { + log.Printf("no config.json in %s", root) + return nil + } + err = json.Unmarshal(b, &w.conf) + if err != nil { + log.Printf("%s: %s", root+"/config.json", err) + return nil + } + return w +} + +func cleanname(s string) string { + if s == "_werc" { + return "" + } + + if strings.HasPrefix(s, "index") { + return "" + } + + switch s { + case "sitemap.txt", "sitemap.gz": + return "" + } + + for _, suf := range []string{".md", ".txt", ".html"} { + if strings.HasSuffix(s, suf) { + return strings.TrimSuffix(s, suf) + } + } + return s +} + +func ptitle(s string) string { + s = strings.TrimSuffix(s, "/") + if idx := strings.LastIndex(s, "index"); idx != -1 { + s = s[:idx-1] + } + _, file := filepath.Split(s) + for _, suf := range []string{".md", ".txt", ".html"} { + if strings.HasSuffix(file, suf) { + return strings.TrimSuffix(file, suf) + } + } + return file +} + +func (werc *Werc) genmenu(site, dir string) []MenuEntry { + var dirs []string + var root []MenuEntry + + base := werc.root + "/sites/" + site + + spl := strings.Split(strings.TrimPrefix(filepath.Clean(dir), "/"), string(filepath.Separator)) + + _, current := filepath.Split(dir) + + if current != "" { + spl = spl[:len(spl)-1] + } + + //log.Printf("base %s path %s spl %+v", base, dir, spl) + + dirs = append(dirs, "/") + + for i := range spl { + path := "/" + filepath.Join(spl[:i+1]...) + dirs = append(dirs, path) + } + + //log.Printf("dirs %v", dirs) + + var last []MenuEntry + for i := range dirs { + var sub []MenuEntry + b := filepath.Join(base, dirs[i]) + fi, _ := ioutil.ReadDir(b) + for _, f := range fi { + newname, ok := okmenu(b, f) + if !ok { + continue + } + me := MenuEntry{Name: newname, Path: filepath.Join(dirs[i], newname)} + if f.Mode().IsDir() { + me.Path = me.Path + "/" + me.Name = me.Name + "/" + } + // if browing a file, mark it as current + if me.Name == current { + me.This = true + } + //log.Printf("me %+v", me) + sub = append(sub, me) + } + + if dirs[i] == "/" { + root = sub + last = root + } else { + // mark directories as currently being browsed + for l, v := range last { + _, file := filepath.Split(dirs[i]) + if v.Name == file+"/" { + last[l].This = true + last[l].Sub = sub + last = sub + } + } + } + } + + return root +} + +func (werc *Werc) WercCommon(w http.ResponseWriter, r *http.Request, page *WercPage) { + site := r.URL.Host + if site == "" { + site = werc.conf.MasterSite + } + path := r.URL.Path + + page.Menu = werc.genmenu(site, path) + + conf := werc.root + "/sites/" + site + "/_werc/config.json" + b, err := ioutil.ReadFile(conf) + if err != nil { + log.Printf("%s: %s", conf, err) + } + err = json.Unmarshal(b, &page.Config) + if err != nil { + log.Printf("%s: %s", conf, err) + } + //log.Printf("root %+v", page.Menu) + if err := werc.tmpl.ExecuteTemplate(w, "base.html", page); err != nil { + log.Printf("%s: %s", r.URL, err) + } +} + +// returns true if a path name is ok to show in the navigation +func okmenu(base string, fi os.FileInfo) (string, bool) { + if strings.HasPrefix(fi.Name(), ".") { + return "", false + } + if fi.Name() == "_werc" { + return "", false + } + if strings.HasPrefix(fi.Name(), "index.") { + return "", false + } + if strings.Contains(fi.Name(), "sitemap.") { + return "", false + } + if fi.Mode().IsDir() { + return fi.Name(), true + } + for _, suf := range []string{".md", ".txt", ".html"} { + if strings.HasSuffix(fi.Name(), suf) { + return strings.TrimSuffix(fi.Name(), suf), true + } + } + return "", false +} + +func (werc *Werc) WercDir(w http.ResponseWriter, r *http.Request, dir string) { + type DirEntry struct { + Name string + Fi os.FileInfo + } + + type DirData struct { + Title string + Entries []DirEntry + } + + var data DirData + data.Title = r.URL.Path + + buf := new(bytes.Buffer) + fi, err := ioutil.ReadDir(dir) + if err != nil { + http.Error(w, fmt.Sprintf("%s", err), 500) + return + } + for _, f := range fi { + if name := cleanname(f.Name()); name != "" { + e := DirEntry{Name: name, Fi: f} + data.Entries = append(data.Entries, e) + } + } + + werc.tmpl.ExecuteTemplate(buf, "directory.html", data) + werc.WercCommon(w, r, &WercPage{Title: ptitle(dir), Content: template.HTML(buf.String())}) +} + +func (werc *Werc) WercMd(w http.ResponseWriter, r *http.Request, path string) { + b, err := ioutil.ReadFile(path) + if err != nil { + http.Error(w, fmt.Sprintf("%s", err), 404) + return + } + md := blackfriday.MarkdownBasic(b) + werc.WercCommon(w, r, &WercPage{Title: ptitle(path), Content: template.HTML(string(md))}) +} + +func (werc *Werc) WercHTML(w http.ResponseWriter, r *http.Request, path string) { + b, err := ioutil.ReadFile(path) + if err != nil { + http.Error(w, fmt.Sprintf("%s", err), 404) + return + } + werc.WercCommon(w, r, &WercPage{Title: ptitle(path), Content: template.HTML(string(b))}) +} + +func (werc *Werc) WercTXT(w http.ResponseWriter, r *http.Request, path string) { + b, err := ioutil.ReadFile(path) + if err != nil { + http.Error(w, fmt.Sprintf("%s", err), 404) + return + } + + buf := new(bytes.Buffer) + werc.tmpl.ExecuteTemplate(buf, "text.html", string(b)) + werc.WercCommon(w, r, &WercPage{Title: ptitle(path), Content: template.HTML(buf.String())}) +} + +func (werc *Werc) Werc404(w http.ResponseWriter, r *http.Request) { + http.NotFound(w, r) +} + +func (werc *Werc) ServeHTTP(w http.ResponseWriter, r *http.Request) { + log.Printf("%s", r.URL) + site := r.URL.Host + if site == "" { + site = werc.conf.MasterSite + } + path := r.URL.Path + + base := werc.root + "/sites/" + site + + if strings.HasSuffix(path, "/index") { + http.Redirect(w, r, strings.TrimSuffix(path, "/index"), http.StatusMovedPermanently) + return + } + + if !strings.HasSuffix(path, "/") { + if st, err := os.Stat(base + path); err == nil { + if st.Mode().IsDir() { + http.Redirect(w, r, path+"/", http.StatusMovedPermanently) + return + } + } + } + + // various format handling + sufferring := map[string]func(w http.ResponseWriter, r *http.Request, path string){ + "md": werc.WercMd, + "html": werc.WercHTML, + "txt": werc.WercTXT, + } + + for suf, handler := range sufferring { + f := base + if strings.HasSuffix(path, "/") { + f = filepath.Join(f, path, "index."+suf) + } else { + f = filepath.Join(f, path+"."+suf) + } + + if _, err := os.Stat(f); err == nil { + log.Printf("%s %s", suf, f) + handler(w, r, f) + return + } + } + + if st, err := os.Stat(base + path); err == nil { + if st.Mode().IsDir() { + // directory handling + log.Printf("d %s", base+path) + werc.WercDir(w, r, base+path) + return + } else { + // plain file handling + log.Printf("f %s", base+path) + http.ServeFile(w, r, base+path) + return + } + } + + werc.Werc404(w, r) +} + +func main() { + flag.Parse() + w := New(*root) + mux := http.NewServeMux() + mux.Handle("/", w) + mux.Handle("/pub/", http.StripPrefix("/pub/", http.FileServer(http.Dir(filepath.Join(w.root, "pub"))))) + s := &http.Server{ + Addr: *listen, + Handler: mux, + ReadTimeout: 10 * time.Second, + WriteTimeout: 10 * time.Second, + MaxHeaderBytes: 1 << 20, + } + log.Fatal(s.ListenAndServe()) +} diff --git a/werc/etc/config.json b/werc/etc/config.json new file mode 100644 index 0000000..49016b2 --- /dev/null +++ b/werc/etc/config.json @@ -0,0 +1,4 @@ +{ + "mastersite": "offblast.org" +} + diff --git a/werc/lib/base.html b/werc/lib/base.html new file mode 100644 index 0000000..9c9476f --- /dev/null +++ b/werc/lib/base.html @@ -0,0 +1,64 @@ + + + + {{.Title}} + + + + + + + + + + + + + + + +
+ {{.Content}} +
+ + + + + + + diff --git a/werc/lib/directory.html b/werc/lib/directory.html new file mode 100644 index 0000000..20c02ac --- /dev/null +++ b/werc/lib/directory.html @@ -0,0 +1,7 @@ +

{{.Title}}

+ + diff --git a/werc/lib/footer.html b/werc/lib/footer.html new file mode 100644 index 0000000..37d0cc6 --- /dev/null +++ b/werc/lib/footer.html @@ -0,0 +1,2 @@ +
Powered by gowerc
+ diff --git a/werc/lib/menu.html b/werc/lib/menu.html new file mode 100644 index 0000000..79ffa68 --- /dev/null +++ b/werc/lib/menu.html @@ -0,0 +1,15 @@ + diff --git a/werc/lib/text.html b/werc/lib/text.html new file mode 100644 index 0000000..c531a77 --- /dev/null +++ b/werc/lib/text.html @@ -0,0 +1,4 @@ +
+{{.}}
+
+ diff --git a/werc/lib/topbar.html b/werc/lib/topbar.html new file mode 100644 index 0000000..3393723 --- /dev/null +++ b/werc/lib/topbar.html @@ -0,0 +1,11 @@ +
+ site map | + 9.offblast.org | + mindlock.us | + github | + bitbucket +
+ +
+
+ diff --git a/werc/pub/style/style.css b/werc/pub/style/style.css new file mode 100644 index 0000000..e69de29 diff --git a/werc/sites/offblast.org/_werc/config.json b/werc/sites/offblast.org/_werc/config.json new file mode 100644 index 0000000..543f78f --- /dev/null +++ b/werc/sites/offblast.org/_werc/config.json @@ -0,0 +1,4 @@ +{ + "title": "offblast.org", + "subtitle": "blast off!" +} diff --git a/werc/sites/offblast.org/_werc/pub/style.css b/werc/sites/offblast.org/_werc/pub/style.css new file mode 100644 index 0000000..ef937d1 --- /dev/null +++ b/werc/sites/offblast.org/_werc/pub/style.css @@ -0,0 +1,332 @@ +/* General style guidelines: + - All font-size at least 14px (recommended 16px) + - Line-height: 1.5 for paragraph body, 1.1 for header +*/ + +body { + color: #859900; + background-color: #002b36; + font-family: Helvetica, Verdana, Arial, 'Liberation Sans', FreeSans, sans-serif; + font-size: 84%; /* Enables font size scaling in MSIE */ + margin: 0; + padding: 0; +} + + +/* # Header # */ +.superHeader { + color: #859900; + height: 1.6em; +} + +.superHeader img { vertical-align: bottom; } + +.superHeader a { + color: #268BD2; + background-color: transparent; + font-size: 91%; + margin: 0; + padding: 0 0.5ex 0 0.25ex; +} + +a { text-decoration: none; } +a:hover { text-decoration: underline; } + +.superHeader div { + position: absolute; + top: 0.40ex; +} + +.superHeader .left { left: 0.4em; } +.superHeader .right { right: 0.4em; } + +.midHeader { + color: #839496; +/* background-color: #859900;*/ + border: solid 0 #859900; + border-width: 2px 0; +} + +.headerTitle { + color: #839496; + font-size: 233%; + font-weight: normal; + margin: 0 0 0 4mm; + padding: 0.25ex 0; +} +#headerSubTitle { + font-size: 50%; + font-style: italic; + margin-left: 1em; +} + +.headerTitle a { color: #268BD2; } +.headerTitle a:hover { text-decoration: none; } + +.subHeader { + display: none; + color: white; + background-color: rgb(0,51,153); + margin: 0; + padding: 1ex 1ex 1ex 1.5mm; +} + +.subHeader a { + color: white; + background-color: transparent; + font-weight: bold; + margin: 0; + padding: 0 0.75ex 0 0.5ex; +} + +.superHeader .highlight, .subHeader .highlight { + color: rgb(253,160,91); + background-color: transparent; +} + + +/* # Side # */ +#side-bar { + width: 16em; + float: left; + clear: left; + border-right: 1px solid #859900; +} + +#side-bar div { + border-bottom: 1px solid #859900; +} + +.sideBarTitle { + font-weight: bold; + margin: 0 0 0.5em 2mm; + padding: 1em 0 0 0; +} + +#side-bar ul { + list-style-type: none; + list-style-position: outside; + margin: 0; + padding: 0 0 0.3em 0; +} + +li ul { + padding-left: 0.6em !important; +} + +#side-bar li { + margin: 0; + padding: 0.1ex 0; /* Circumvents a rendering bug (?) in MSIE 6.0 XXX should move to iehacks.css, this causes an ugly gap */ +} + +#side-bar a { + color: #268BD2; + background-color: transparent; + margin: 0; + padding: 0.25em 1ex 0.25em 2mm; + display: block; + text-transform: capitalize; + font-weight: bold!important; + font-size: 102%; + border-left: #268BD2 solid 0.2em; +} + +.thisPage, .thisPage a { + color: #859900 !important; + background-color: white; + padding-left: 5mm; +} + +#side-bar a:hover { + color: #839496; +/* background-color: #586e75; + border-left: black solid 0.2em;*/ + text-decoration: none; +} + +.sideBarText { + line-height: 1.5em; + margin: 0 0 1em 0; + padding: 0 1.5ex 0 2.5mm; + display: block; +} + +#side-bar .sideBarText a { + margin: 0; + padding: 0; + display: inline; +} + +#side-bar .sideBarText a:hover { + color: rgb(0,102,204); + background-color: transparent; + text-decoration: none; +} + + +/* # Main Copy # */ +#main-copy { + max-width: 70em; + color: #859900; + background-color: transparent; + text-align: justify; + line-height: 1.5em; + margin: 0em 0 0 16em; + padding: 0.5mm 5mm 5mm 5mm; + border-left: 1px solid #859900; +} + +#bodyText { + margin: 0 0 0 15.5em; + padding: 2mm 5mm 2mm 5mm; +} + +#main-copy p { + margin: 1em 1ex 1em 1ex !important; /* Need !important so troff-generated pages don't look totally squezed */ + padding: 0; +} + +#main-copy a { + color: #268bd2; + background-color: transparent; +} + +#main-copy a:hover { + color: #839496; +} + +#main-copy h1, #main-copy h2 { + color: #859900; + background-color: transparent; + font-size: 145.5%; + font-weight: bold; + margin: 2em 0 0 0; + padding: 0.5ex 0 0.5ex 0.6ex; + border-bottom: 2px solid #859900; +} + +#main-copy h2 { + font-size: 115.5%; + border-bottom: 1px solid #859900; +} + +#main-copy .topOfPage { + color: rgb(0,102,204); + background-color: transparent; + font-size: 91%; + font-weight: bold; + text-decoration: none; + margin: 3ex 1ex 0 0; + padding: 0; + float: right; +} + +dl { + margin: 1em 1ex 2em 1ex; + padding: 0; +} + +dt { + font-weight: bold; + margin: 0 0 0 0; + padding: 0; +} + +dd { + margin: 0 0 2em 2em; + padding: 0; +} + + +/* # Footer # */ +#footer { + color: #839496; + border: solid 0 #859900; + border-width: 2px 0; + padding: 2em; + clear: both; +} + +#footer .left { + text-align: left; + line-height: 1.55em; + float: left; + clear: left; +} + +#footer .right { + text-align: right; + line-height: 1.45em; +} + +#footer a { + color: #268BD2; + background-color: transparent; +} + + +/* GENERAL */ + +table { + border: solid 1px black; +} +th { + background-color: #abc; + border: solid 1px black; + text-align: center; +} +td { + background-color: #def; + border: solid 1px black; +} + +hr { + border-width: 0px 0px 0.1em 0px; + border-color: black; +} + +acronym, .titleTip { + border-bottom: 1px solid #ddd; + cursor: help; + margin: 0; + padding: 0 0 0.4px 0; +} + +pre { + margin-left: 2em; + font-size: 1.2em; +} + +blockquote { + border-left: 1px solid blue; + font-style: italic; +} + +.smallCaps { + font-size: 110%; + font-variant: small-caps; +} + +.doNotDisplay { display: none; } + + +.notify_errors, +.notify_notes, +.notify_success { padding: .8em; margin-bottom: 1em; border: 2px solid #ddd; } + +.notify_errors { background: #FBE3E4; color: #8a1f11; border-color: #FBC2C4; } +.notify_notes { background: #FFF6BF; color: #514721; border-color: #FFD324; } +.notify_success { background: #E6EFC2; color: #264409; border-color: #C6D880; } +.notify_errors a { color: #8a1f11; } +.notify_notes a { color: #514721; } +.notify_success a { color: #264409; } + + +/* # Page/Handler specific # */ +h1.dir-list-head, ul.dir-list { + text-transform: capitalize; + font-weight: bold; +} +ul.sitemap-list a { + text-transform: capitalize; +} diff --git a/werc/sites/offblast.org/foo/bar.md b/werc/sites/offblast.org/foo/bar.md new file mode 100644 index 0000000..f7700d0 --- /dev/null +++ b/werc/sites/offblast.org/foo/bar.md @@ -0,0 +1,67 @@ +# Dolentem volucri lugubris + +## Alto exercet + +[Lorem markdownum rogavit](http://imgur.com/) obsedit **Thebis** in dextera? Qui +cum, cum **nubila fieri** quamquam: non graia reperta inpositos ut de. + + if (server_compiler + memory_ipx < typeface(scannerDll)) { + keystroke = personalListserv * uriTextDisplay(dslam, blacklist_png, + primary); + } else { + malwareSms(smmSsl, animated_brouter.up(install_d, macro_nat_isp, + petaflops_system), 319307); + marketingRowTitle(2, network(logic_cmos_shift), middlewareDhcp); + } + sidebar(matrixVirus(wordartAjax), flatPartyDisk.rootDynamicSla(42 - + model_command_wavelength, error_hard_superscalar(snippet, -3), + gnutella_wimax)); + unixHardSource.schemaKilobit(logCybersquatterCard(megabyte)); + hot.file_operating_source += -2; + +## Et Amymonen quoque que inferius artus + +In hos parce generoso et quod, Latonam hoc levis hausta me tamen ingrate lumina. +Pia tibi flumen priora solitam colorum ille matutinaeque posse! Ergo servatae +latet mirabere, est vocat nervos ingreditur tam Phinea hac longe. + +Post virgo? Cava coepti, liquido agros. Humano ducta inritata India. Porrexit +tibi, in [nitebat variarum tenebat](http://www.wedrinkwater.com/) dixit +testudine me mare per sucosque ut petitos passa temploque spesque, calculus. + +## Usum harundine coniugis notae nono + +Cura lacrimas; et socio, Troum? Solebat nudaeque amor, auxilio esse; partem +finxit minimamque. Novo toro primaeque et quamvis quae futura simulat, vos posse +tubere. Hominum et meque deum iter: quam cretus, Picus. + +1. Igitur quae corpus +2. Permanet ambage et pecudes dumque moenia scelus +3. Dederant cervice Iuppiter +4. Dare externa instrumenta Cipe +5. Humiles ambo deprensa quem mirabile cornua fidesque +6. Urbes suum viderunt + +## Vivitur notavit inferior praelata tarde et auguris + +Id visura, animi opera: spatium nisi rident vacuas, graves est potuisse irae, +casus arva, sunt. Dixit fratrem cervix! Ordine et iam, cum Bactrius templum, +exhalantur curru cultosque dedit. Cognovit tenderet in naribus perdere **eunt**, +Dryantaque noverit quotiens luserit, summorum concussit spectat crinis +**moriemur titulum aut** luce. Utque lucem nescio, armis dubitanti ramis +cruciata maerent e stridore me vulgata, hospitio in *Perseus*, est femina. + +- Agit quasque falsum +- Huius vulgus virtute +- Vota nam +- Pararis nosti + +Tua sed ut Telamon pudetque permulcetque Nessus rotae, tremuere. Finite +inornatos nymphis patuit sine occupat nescio; meri inprudens genu equorum usus +hoc inritus. Tecta annos Charaxi aquis caelataeque feror pugnantem satis +attonitum potes. Videntur incipiat totidemque **viri incaluit** locum quo lumina +conatur addidit. Musa illa intortos. + +[Lorem markdownum rogavit]: http://imgur.com/ +[nitebat variarum tenebat]: http://www.wedrinkwater + diff --git a/werc/sites/offblast.org/index.md b/werc/sites/offblast.org/index.md new file mode 100644 index 0000000..83baa73 --- /dev/null +++ b/werc/sites/offblast.org/index.md @@ -0,0 +1,5 @@ +welcome to go werc +=================== + +add directories and files here. + diff --git a/werc/sites/offblast.org/test/apage.md b/werc/sites/offblast.org/test/apage.md new file mode 100644 index 0000000..c9914c0 --- /dev/null +++ b/werc/sites/offblast.org/test/apage.md @@ -0,0 +1,3 @@ +different test page +========== + diff --git a/werc/sites/offblast.org/test/coolhtml.html b/werc/sites/offblast.org/test/coolhtml.html new file mode 100644 index 0000000..7e7b420 --- /dev/null +++ b/werc/sites/offblast.org/test/coolhtml.html @@ -0,0 +1,2 @@ +

HTML!

+ diff --git a/werc/sites/offblast.org/test/file.txt b/werc/sites/offblast.org/test/file.txt new file mode 100644 index 0000000..a9cfe6a --- /dev/null +++ b/werc/sites/offblast.org/test/file.txt @@ -0,0 +1,3 @@ +THIS IS PLAIN TEXT! +=================== + diff --git a/werc/sites/offblast.org/test/index.md b/werc/sites/offblast.org/test/index.md new file mode 100644 index 0000000..a8bfbd5 --- /dev/null +++ b/werc/sites/offblast.org/test/index.md @@ -0,0 +1,5 @@ +test index +========== + +testing 1 2 3 +