Skip to content

Instantly share code, notes, and snippets.

@patrickkh7788
Forked from WebFreak001/d_to_html.d
Created August 6, 2017 13:05
Show Gist options
  • Save patrickkh7788/0eb14989f175d382fbd66c095342da3a to your computer and use it in GitHub Desktop.
Save patrickkh7788/0eb14989f175d382fbd66c095342da3a to your computer and use it in GitHub Desktop.
Create websites using D, with a cool syntax
import std.conv;
import std.stdio;
import std.traits;
import std.range;
struct Element
{
string _name;
string[string] _attributes;
string _content;
this(string name)
{
_name = name;
}
Element opCall(Args...)(Args args)
{
import std.xml : encode;
foreach (arg; args)
{
alias T = typeof(arg);
static if (is(T == Attribute))
_attributes[arg.name] = arg.value;
else static if (is(T == CssAttribute))
{
_content ~= arg.toString;
}
else static if (is(T == HeadElemBodyAttr))
{
if (_name == "head")
_content ~= "<" ~ arg.tag.encode ~ ">" ~ encode(arg.value) ~ "</" ~ arg.tag.encode ~ ">";
else
_attributes["title"] = arg.value;
}
else static if (is(T == string[string]))
{
foreach (k, v; arg)
_attributes[k] = v;
}
else
{
if (_name == "style")
{
static if (is(T == Element))
{
_content ~= arg.makeCssName ~ '{' ~ arg._content ~ '}';
}
}
else
_content ~= toContent(arg);
}
}
return this;
}
Element opDispatch(string s, Args...)(Args args)
{
auto c = "class" in _attributes;
if (c)
_attributes["class"] ~= " " ~ s;
else
_attributes["class"] = s;
static if (Args.length)
return this.opCall(args);
else
return this;
}
auto opBinary(string op, T)(T rhs)
{
static if (op == "*" && isIntegral!T)
return repeat(this, cast(size_t) rhs);
else
static assert(false);
}
string makeCssName()
{
string ret = _name;
foreach (k, v; _attributes)
{
if (k == "class")
ret ~= '.' ~ v.split().join(".");
else if (k == "id")
ret ~= '#' ~ v;
}
return ret;
}
string toString() const
{
import std.xml : encode;
string attr;
foreach (k, v; _attributes)
attr ~= " " ~ k.encode ~ "=\"" ~ v.encode ~ "\"";
string ret = "<" ~ _name.encode ~ attr;
if (_content.length)
ret ~= ">" ~ _content ~ "</" ~ _name.encode ~ ">";
else
ret ~= "/>";
return ret;
}
}
struct Attribute
{
string name, value;
}
struct CssAttribute
{
string name, value;
this(string name)
{
this.name = name;
}
this(string name, string value)
{
this.name = name;
this.value = value;
}
CssAttribute opCall(T)(T val)
{
static if (isIntegral!T)
{
auto hex = val.to!string(16);
while (hex.length < 6)
hex = '0' ~ hex;
value = '#' ~ hex;
}
else
value = val.to!string;
return this;
}
alias opAssign = opCall;
CssAttribute opBinary(string op, T)(T rhs)
{
static if (op == "-")
{
static if (is(T == string))
return CssAttribute(name ~ '-' ~ rhs, value);
else static if (is(T == CssAttribute))
return CssAttribute(name ~ '-' ~ rhs.name, rhs.value);
else
static assert(false);
}
else
static assert(false);
}
CssAttribute opUnary(string op : "-")()
{
return CssAttribute('-' ~ name, value);
}
string toString() const
{
return name ~ ':' ~ value ~ ';';
}
}
struct Raw
{
string html;
}
string toContent(T)(T arg)
{
import std.xml : encode;
static if (is(T == Raw))
return arg.html;
else static if (is(T == Element))
return arg.toString;
else static if (isInputRange!T && !isSomeString!T)
{
string ret;
foreach (v; arg)
ret ~= toContent(v);
return ret;
}
else
return encode(arg.to!string);
}
Raw raw(string html)()
{
return Raw(html);
}
template attr(string name)
{
Attribute attr(T)(T value)
{
static if (is(T == string))
return Attribute(name, value);
else
{
string val;
static if (is(T == CssAttribute[]))
{
foreach (arg; value)
val ~= arg.toString;
}
else static if (is(T == CssAttribute))
{
val = arg.toString;
}
else static if (is(T == string[]))
{
foreach (arg; value)
val ~= arg;
}
else
static assert(false);
return Attribute(name, val);
}
}
}
struct HeadElemBodyAttr
{
string tag, value;
}
template headElemBodyAttr(string tag)
{
HeadElemBodyAttr headElemBodyAttr(string val)
{
return HeadElemBodyAttr(tag, val);
}
Element headElemBodyAttr(Args...)(Args args)
{
return Element(tag)(args);
}
}
alias title = headElemBodyAttr!"title";
alias style = headElemBodyAttr!"style";
enum html = Element("html");
enum head = Element("head");
enum
body = Element("body");
enum p = Element("p");
enum h1 = Element("h1");
enum h2 = Element("h2");
enum h3 = Element("h3");
enum h4 = Element("h4");
enum h5 = Element("h5");
enum h6 = Element("h6");
enum div = Element("div");
enum span = Element("span");
enum img = Element("img");
enum link = Element("link");
enum meta = Element("meta");
enum br = Element("br");
enum hr = Element("hr");
enum b = Element("b");
enum i = Element("i");
enum u = Element("u");
enum ul = Element("ul");
enum ol = Element("ol");
enum li = Element("li");
enum table = Element("table");
enum thead = Element("thead");
enum tbody = Element("tbody");
enum tr = Element("tr");
enum td = Element("td");
enum th = Element("th");
enum pre = Element("pre");
enum code = Element("code");
enum input = Element("input");
enum fieldset = Element("fieldset");
enum legend = Element("legend");
enum script = Element("script");
enum canvas = Element("canvas");
enum select = Element("select");
enum option = Element("option");
enum button = Element("button");
enum svg = Element("svg");
enum font = CssAttribute("font");
enum family = CssAttribute("family");
enum size = CssAttribute("size");
enum color = CssAttribute("color");
enum width = CssAttribute("width");
enum height = CssAttribute("height");
enum border = CssAttribute("border");
enum text = CssAttribute("text");
enum decoration = CssAttribute("decoration");
enum radius = CssAttribute("radius");
enum transition = CssAttribute("transition");
enum background = CssAttribute("background");
enum margin = CssAttribute("margin");
enum padding = CssAttribute("padding");
enum left = CssAttribute("left");
enum top = CssAttribute("top");
enum right = CssAttribute("right");
enum bottom = CssAttribute("bottom");
enum max = CssAttribute("max");
enum min = CssAttribute("min");
enum box = CssAttribute("box");
enum shadow = CssAttribute("shadow");
enum sizing = CssAttribute("sizing");
alias class_ = attr!"class";
alias id = attr!"id";
alias name = attr!"name";
alias src = attr!"src";
alias href = attr!"href";
alias rel = attr!"rel";
alias type = attr!"type";
alias minLength = attr!"minLength";
alias maxLength = attr!"maxLength";
alias pattern = attr!"pattern";
alias required = attr!"required";
alias disabled = attr!"disabled";
alias placeholder = attr!"placeholder";
alias role = attr!"role";
alias for_ = attr!"for";
alias media = attr!"media";
alias content = attr!"content";
alias property = attr!"property";
alias tabindex = attr!"tabindex";
enum aliceBlue = "aliceBlue";
enum antiqueWhite = "antiqueWhite";
enum aqua = "aqua";
enum aquamarine = "aquamarine";
enum azure = "azure";
enum beige = "beige";
enum bisque = "bisque";
enum black = "black";
enum blanchedAlmond = "blanchedAlmond";
enum blue = "blue";
enum blueViolet = "blueViolet";
enum brown = "brown";
enum burlyWood = "burlyWood";
enum cadetBlue = "cadetBlue";
enum chartreuse = "chartreuse";
enum chocolate = "chocolate";
enum coral = "coral";
enum cornflowerBlue = "cornflowerBlue";
enum cornsilk = "cornsilk";
enum crimson = "crimson";
enum cyan = "cyan";
enum darkBlue = "darkBlue";
enum darkCyan = "darkCyan";
enum darkGoldenRod = "darkGoldenRod";
enum darkGray = "darkGray";
enum darkGreen = "darkGreen";
enum darkKhaki = "darkKhaki";
enum darkMagenta = "darkMagenta";
enum darkOliveGreen = "darkOliveGreen";
enum darkOrange = "darkOrange";
enum darkOrchid = "darkOrchid";
enum darkRed = "darkRed";
enum darkSalmon = "darkSalmon";
enum darkSeaGreen = "darkSeaGreen";
enum darkSlateBlue = "darkSlateBlue";
enum darkSlateGray = "darkSlateGray";
enum darkTurquoise = "darkTurquoise";
enum darkViolet = "darkViolet";
enum deepPink = "deepPink";
enum deepSkyBlue = "deepSkyBlue";
enum dimGray = "dimGray";
enum dodgerBlue = "dodgerBlue";
enum fireBrick = "fireBrick";
enum floralWhite = "floralWhite";
enum forestGreen = "forestGreen";
enum fuchsia = "fuchsia";
enum gainsboro = "gainsboro";
enum ghostWhite = "ghostWhite";
enum gold = "gold";
enum goldenRod = "goldenRod";
enum gray = "gray";
enum green = "green";
enum greenYellow = "greenYellow";
enum honeyDew = "honeyDew";
enum hotPink = "hotPink";
enum indianRed = "indianRed";
enum indigo = "indigo";
enum ivory = "ivory";
enum khaki = "khaki";
enum lavender = "lavender";
enum lavenderBlush = "lavenderBlush";
enum lawnGreen = "lawnGreen";
enum lemonChiffon = "lemonChiffon";
enum lightBlue = "lightBlue";
enum lightCoral = "lightCoral";
enum lightCyan = "lightCyan";
enum lightGoldenRodYellow = "lightGoldenRodYellow";
enum lightGray = "lightGray";
enum lightGreen = "lightGreen";
enum lightPink = "lightPink";
enum lightSalmon = "lightSalmon";
enum lightSeaGreen = "lightSeaGreen";
enum lightSkyBlue = "lightSkyBlue";
enum lightSlateGray = "lightSlateGray";
enum lightSteelBlue = "lightSteelBlue";
enum lightYellow = "lightYellow";
enum lime = "lime";
enum limeGreen = "limeGreen";
enum linen = "linen";
enum magenta = "magenta";
enum maroon = "maroon";
enum mediumAquaMarine = "mediumAquaMarine";
enum mediumBlue = "mediumBlue";
enum mediumOrchid = "mediumOrchid";
enum mediumPurple = "mediumPurple";
enum mediumSeaGreen = "mediumSeaGreen";
enum mediumSlateBlue = "mediumSlateBlue";
enum mediumSpringGreen = "mediumSpringGreen";
enum mediumTurquoise = "mediumTurquoise";
enum mediumVioletRed = "mediumVioletRed";
enum midnightBlue = "midnightBlue";
enum mintCream = "mintCream";
enum mistyRose = "mistyRose";
enum moccasin = "moccasin";
enum navajoWhite = "navajoWhite";
enum navy = "navy";
enum oldLace = "oldLace";
enum olive = "olive";
enum oliveDrab = "oliveDrab";
enum orange = "orange";
enum orangeRed = "orangeRed";
enum orchid = "orchid";
enum paleGoldenRod = "paleGoldenRod";
enum paleGreen = "paleGreen";
enum paleTurquoise = "paleTurquoise";
enum paleVioletRed = "paleVioletRed";
enum papayaWhip = "papayaWhip";
enum peachPuff = "peachPuff";
enum peru = "peru";
enum pink = "pink";
enum plum = "plum";
enum powderBlue = "powderBlue";
enum purple = "purple";
enum rebeccaPurple = "rebeccaPurple";
enum red = "red";
enum rosyBrown = "rosyBrown";
enum royalBlue = "royalBlue";
enum saddleBrown = "saddleBrown";
enum salmon = "salmon";
enum sandyBrown = "sandyBrown";
enum seaGreen = "seaGreen";
enum seaShell = "seaShell";
enum sienna = "sienna";
enum silver = "silver";
enum skyBlue = "skyBlue";
enum slateBlue = "slateBlue";
enum slateGray = "slateGray";
enum snow = "snow";
enum springGreen = "springGreen";
enum steelBlue = "steelBlue";
enum tan = "tan";
enum teal = "teal";
enum thistle = "thistle";
enum tomato = "tomato";
enum turquoise = "turquoise";
enum violet = "violet";
enum wheat = "wheat";
enum white = "white";
enum whiteSmoke = "whiteSmoke";
enum yellow = "yellow";
enum yellowGreen = "yellowGreen";
enum auto_ = "auto";
enum inherit = "inherit";
enum center = "center";
enum justify = "justify";
string px(double d)
{
return d.to!string ~ "px";
}
string pt(double d)
{
return d.to!string ~ "pt";
}
string em(double d)
{
return d.to!string ~ "em";
}
string cm(double d)
{
return d.to!string ~ "cm";
}
void main()
{
//dfmt off
string page = html(
head(
title("wtf is this"),
style(
html(
font-family = "Roboto",
background = 0xEFEFEF
),
div.content(
max-width = 800.px,
margin = auto_,
margin-top = 32.px,
box-shadow = "0 2px 5px rgba(0, 0, 0, 0.3)",
background = white,
padding = 32.px
),
div.footer(
text-"align" = center
)
)
),
body(
div.content(
h1("The most crappy HTML generator ever"),
div.teaser(
p("Super fast")
),
hr,
p("Reasons why you should use d_to_html:"),
ul(
li("TODO: no reason yet") * 5
)
),
div.footer(
p(raw!"&copy; 2017 webfreak.org")
)
)
).toString;
//dfmt on
writeln(page);
auto f = File("test.html", "w");
f.write(page);
f.close();
import std.process;
import std.file;
import std.path;
browse(buildPath(getcwd, "test.html"));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment