summaryrefslogtreecommitdiffhomepage
path: root/dlang/src/write/rgx.d
diff options
context:
space:
mode:
Diffstat (limited to 'dlang/src/write/rgx.d')
-rw-r--r--dlang/src/write/rgx.d104
1 files changed, 104 insertions, 0 deletions
diff --git a/dlang/src/write/rgx.d b/dlang/src/write/rgx.d
new file mode 100644
index 0000000..23c848d
--- /dev/null
+++ b/dlang/src/write/rgx.d
@@ -0,0 +1,104 @@
+module write.rgx;
+
+/+ ↓ the internal markup, as regular expressions.
+ .
+ An object's text is *spine's internal representation*, not the author's
+ markup and not any output: the markers are single Unicode characters
+ chosen not to occur in text. A writer's first job is to turn them into
+ something the target format understands, so every writer needs these
+ and they live in one place.
+ .
+ Taken from the specification's description of object text and matched
+ against spine's own outputs/io_out/rgx.d, which is normative. The
+ characters are load bearing: do not "tidy" them into ASCII.
++/
+
+import std.regex;
+
+static struct Rgx {
+ /+ ↓ spacing and line breaks +/
+ static nbsp_char = ctRegex!(`░`, "mg");
+ static br_line = ctRegex!(`\s*┘\s*`, "mg");
+ static br_line_inline = ctRegex!(`\s*┙\s*`, "mg");
+ static br_line_spaced = ctRegex!(`\s*┚\s*`, "mg");
+
+ /+ ↓ font face, each ⑆<mark>┨ text ┣<mark> +/
+ static inline_strike = ctRegex!(`⑆[-]┨(?P<text>.+?)┣[-]`, "mg");
+ static inline_insert = ctRegex!(`⑆[+]┨(?P<text>.+?)┣[+]`, "mg");
+ static inline_cite = ctRegex!(`⑆[‖]┨(?P<text>.+?)┣[‖]`, "mg");
+ static inline_emphasis = ctRegex!(`⑆[*]┨(?P<text>.+?)┣[*]`, "mg");
+ static inline_bold = ctRegex!(`⑆[!]┨(?P<text>.+?)┣[!]`, "mg");
+ static inline_italics = ctRegex!(`⑆[/]┨(?P<text>.+?)┣[/]`, "mg");
+ static inline_underscore = ctRegex!(`⑆[_]┨(?P<text>.+?)┣[_]`, "mg");
+ static inline_superscript = ctRegex!(`⑆\^┨(?P<text>.+?)┣\^`, "mg");
+ static inline_subscript = ctRegex!(`⑆[,]┨(?P<text>.+?)┣[,]`, "mg");
+ static inline_mono = ctRegex!(`⑆[■]┨(?P<text>.+?)┣[■]`, "mg");
+
+ /+ ↓ links and images. Capture 1 is the text, 3 the target without its
+ leading "#" where it has one +/
+ static inline_link = ctRegex!(`┥(?P<text>.+?)┝┤(?P<link>#?(\S+?))├`, "mg");
+ static inline_image = ctRegex!(`(?P<pre>┥)☼(?P<imginf>(?P<img>[a-zA-Z0-9._-]+?\.(?:jpg|gif|png)),w(?P<width>\d+)h(?P<height>\d+))\s*(?P<post>.*?┝┤.*?├)`, "mg");
+
+ /+ ↓ notes, carried inline in the object that refers to them +/
+ static inline_notes_al_gen = ctRegex!(`【.+?】`, "m");
+ static inline_notes_al_regular_number_note = ctRegex!(`【(?P<num>\d+)\s+(?P<note>.+?)\s*】`, "mg");
+ /+ ↓ and the same for a note marked with a run of stars or pluses
+ instead of a number, which the markup also allows +/
+ static inline_notes_al_all_note = ctRegex!(`【(?P<num>\d+|(?:[*]|[+])+)\s+(?P<note>.+?)\s*】`, "mg");
+
+ /+ ↓ tables: the object's text is rows and columns in one string +/
+ static table_delimiter_row = ctRegex!("[ ]*\n", "mg");
+ static table_delimiter_col = ctRegex!("[ ]*[┊][ ]*", "mg");
+
+ /+ ↓ the book index, whose entries carry their own links +/
+ static find_bookindex_ocn_link_and_comma = ctRegex!(`[, ]*┥.+?┝┤#?\S+?├`, "mg");
+
+ /+ ↓ end of *input*, not end of line: spine's table layout strips the
+ whole accumulated string after every cell +/
+ static trailing_whitespace_all = ctRegex!(`\s*$`);
+ static trailing_backslash = ctRegex!(`\s*\\`, "mg");
+
+ /+ ↓ a link before its url has been substituted in: the number is an index
+ into the object's .stow_link list, not a target +/
+ static inline_link_number_only = ctRegex!(`(?P<linked_text>┥.+?┝)┤(?P<num>[0-9]+)├`, "mg");
+ static inline_link_empty = ctRegex!(`┥(?P<text>.+?)┝┤├`, "mg");
+
+ /+ ↓ an anchor the markup placed in the text, ┃name┃ +/
+ static inline_link_anchor = ctRegex!(`┃(?P<anchor>\S+?)┃`, "mg");
+
+ /+ ↓ "¤" marks a link that is internal to the document collection, and
+ ".fnSuffix" stands where an output's file suffix goes +/
+ static mark_internal_site_lnk = ctRegex!(`¤`, "mg");
+ static inline_seg_link = ctRegex!(`(¤)(?:.+?)\.fnSuffix`, "mg");
+
+ /+ ↓ the same target taken apart: the segment it names and whatever
+ follows it, which is what a segmented output needs +/
+ static internal_target = ctRegex!(`^¤(?P<seg>.+?)\.fnSuffix(?P<frag>.*)$`);
+
+ /+ ↓ an image's alt text, which the markup carries as a quoted string
+ following the image +/
+ static inline_image_alt = ctRegex!(`^\s*[“"](?P<alt>[^”"]*)[”"]`, "m");
+
+ /+ ↓ a line break the markup asked for, " \\" +/
+ static line_break = ctRegex!(` [\\]{2}`, "m");
+
+ /+ ↓ the leading markers of a line inside a group: indent, hang, bullet.
+ "_2 " is indent two, "_2*" a bullet at indent two, "_2_1 " a hanging
+ indent. They are line-leading and so anchored, with "m".
+ +/
+ static grouped_para_indent = ctRegex!(`^_(?P<indent>[1-9])[ ]`, "m");
+ static grouped_para_bullet = ctRegex!(`^_[*] `, "m");
+ static grouped_para_bullet_at = ctRegex!(`^_(?P<indent>[1-9])[*] `, "m");
+ static grouped_para_indent_hang = ctRegex!(`^_(?P<hang>[0-9])_(?P<indent>[0-9])[ ]`, "m");
+
+ /+ ↓ an internal link target as the abstraction writes it, with or without
+ the segment prefix a segmented output would use. Read to decide whether
+ a table of contents entry points at anything this writer renders. +/
+ static any_internal_target = ctRegex!(`┤(?:¤.+?\.fnSuffix)?#(?P<frag>[^├]+)├`, "mg");
+
+ /+ ↓ the four characters html reserves +/
+ static ampersand = ctRegex!(`[&]`, "mg");
+ static quotation = ctRegex!(`["]`, "mg");
+ static less_than = ctRegex!(`[<]`, "mg");
+ static greater_than = ctRegex!(`[>]`, "mg");
+}