import arsd.web; import std.file; import std.algorithm; import std.array; import std.regex; class Post : ApiObject { this(Blog parent, string id) { auto idx = id.lastIndexOf("/"); if(idx != -1) id = id[idx + 1 .. $]; text = readText("blog-posts/" ~ id); title = id; } string title; string text; Element makeHtmlElement(Document document = null) { auto holder = Element.make("div"); holder.addChild("h1", title.capitalize); auto content = holder.addChild("div"); foreach(para; std.string.split(text, "\n\n")) { auto p = content.addChild(std.string.indexOf(para, "\t") == -1 ? "p" : "pre"); string remaining = para; foreach(match; match(para, regex(r"\[\[[a-zA-Z0-9_\-]+\]\]"))) { p.appendText(match.pre); auto link = match.hit[2 .. $-2]; p.addChild("a", link, link); remaining = match.post; break; // we only support one match for now since blargh regex. } p.appendText(remaining); } return holder; } auto GET() { return makeHtmlElement(); } } class Blog : ApiProvider { string mySource() { return import("blog.d"); } alias Post post; auto GET() { Post[] posts; DirEntry[] dir; foreach(DirEntry wtf; dirEntries("blog-posts", SpanMode.breadth)) dir ~= wtf; foreach(file; sort!q{ a.timeLastModified() > b.timeLastModified() }(dir)) posts ~= new Post(this, file.name); return posts; } override string _style() const { return import("blog.css"); } } mixin FancyMain!Blog;