1 /** Attributes.
2  *
3  * Only make T args const when they have value semantics (allAre!hasIndirections!T).
4  */
5 module nxt.attributes;
6 
7 import nxt.iso_639_1 : Language;
8 import nxt.lingua: TokenId, Usage;
9 
10 pure nothrow @safe @nogc
11 {
12 	/** Words. */
13 	struct AsWords(T...) { T args; } auto ref asWords(T...)(T args) { return AsWords!T(args); }
14 	/** Comma-Separated List. */
15 	struct AsCSL(T...) { T args; } auto ref asCSL(T...)(T args) { return AsCSL!T(args); }
16 
17 	/** Printed as Path. */
18 	struct AsPath(T) { T arg; } auto ref asPath(T)(T arg) { return AsPath!T(arg); }
19 	/** Printed as Name. */
20 	struct AsName(T) { T arg; } auto ref asName(T)(T arg) { return AsName!T(arg); }
21 	/** Printed as URL. */
22 	struct AsURL(T) { T arg; alias arg this; } auto ref asURL(T)(T arg) { return AsURL!T(arg); }
23 
24 	/* TODO: Turn these into an enum for more efficient parsing. */
25 	/** Printed as Italic/Slanted. */
26 	struct AsItalic(T...) { T args; } auto asItalic(T...)(T args) { return AsItalic!T(args); }
27 	/** Bold. */
28 	struct AsBold(T...) { T args; } auto asBold(T...)(T args) { return AsBold!T(args); }
29 	/** Monospaced. */
30 	struct AsMonospaced(T...) { T args; } auto asMonospaced(T...)(T args) { return AsMonospaced!T(args); }
31 
32 	/** Code. */
33 	struct AsCode(TokenId token = TokenId.unknown,
34 				  Language lang_ = Language.unknown, T...) {
35 		this(T args) { this.args = args; }
36 		T args;
37 		static lang = lang_;
38 		string language;
39 		TokenId tokenId;
40 		Usage usage;
41 		auto ref setLanguage(string language) {
42 			this.language = language;
43 			return this;
44 		}
45 	}
46 
47 	/* Instantiators */
48 	auto ref asCode(Language lang_ = Language.unknown, T...)(T args) { return AsCode!(TokenId.unknown, lang_, T)(args); }
49 	auto ref asKeyword(Language lang_ = Language.unknown, T...)(T args) { return AsCode!(TokenId.keyword, lang_, T)(args); } // Emacs: font-lock-keyword-face
50 	auto ref asType(Language lang_ = Language.unknown, T...)(T args) { return AsCode!(TokenId.type, lang_, T)(args); } // Emacs: font-lock-type-face
51 	auto ref asConstant(Language lang_ = Language.unknown, T...)(T args) { return AsCode!(TokenId.constant, lang_, T)(args); } // Emacs: font-lock-constant-face
52 	auto ref asVariable(Language lang_ = Language.unknown, T...)(T args) { return AsCode!(TokenId.variableName, lang_, T)(args); } // Emacs: font-lock-variable-name-face
53 	auto ref asComment(Language lang_ = Language.unknown, T...)(T args) { return AsCode!(TokenId.comment, lang_, T)(args); } // Emacs: font-lock-comment-face
54 
55 	auto ref asFunction(Language lang_ = Language.unknown, T...)(T args) { return AsCode!(TokenId.functionName, lang_, T)(args); } // Emacs: font-lock-function-name-face
56 	auto ref asFunctionCall(Language lang_ = Language.unknown, T...)(T args) { return AsCode!(TokenId.functionCall, lang_, T)(args); } // Emacs: font-lock-function-name-face
57 
58 	auto ref asConstructor(Language lang_ = Language.unknown, T...)(T args) { return AsCode!(TokenId.constructor, lang_, T)(args); } // constuctor
59 	auto ref asDestructor(Language lang_ = Language.unknown, T...)(T args) { return AsCode!(TokenId.destructor, lang_, T)(args); } // destructor
60 	auto ref asBuiltin(Language lang_ = Language.unknown, T...)(T args) { return AsCode!(TokenId.builtinName, lang_, T)(args); } // Emacs: font-lock-builtin-name-face
61 	auto ref asTemplate(Language lang_ = Language.unknown, T...)(T args) { return AsCode!(TokenId.templateName, lang_, T)(args); } // Emacs: font-lock-builtin-name-face
62 	auto ref asOperator(Language lang_ = Language.unknown, T...)(T args) { return AsCode!(TokenId.operator, lang_, T)(args); } // Emacs: font-lock-operator-face
63 	auto ref asMacro(Language lang_ = Language.unknown, T...)(T args) { return AsCode!(TokenId.macroName, lang_, T)(args); }
64 	auto ref asAlias(Language lang_ = Language.unknown, T...)(T args) { return AsCode!(TokenId.aliasName, lang_, T)(args); }
65 	auto ref asEnumeration(Language lang_ = Language.unknown, T...)(T args) { return AsCode!(TokenId.enumeration, lang_, T)(args); }
66 	auto ref asEnumerator(Language lang_ = Language.unknown, T...)(T args) { return AsCode!(TokenId.enumerator, lang_, T)(args); }
67 	alias asCtor = asConstructor;
68 	alias asDtor = asDestructor;
69 	alias asEnum = asEnumeration;
70 
71 	/** Emphasized. */
72 	struct AsEmphasized(T...) { T args; } auto ref asEmphasized(T...)(T args) { return AsEmphasized!T(args); }
73 
74 	/** Strongly Emphasized. */
75 	struct AsStronglyEmphasized(T...) { T args; } auto ref asStronglyEmphasized(T...)(T args) { return AsStronglyEmphasized!T(args); }
76 
77 	/** Strong. */
78 	struct AsStrong(T...) { T args; } auto ref asStrong(T...)(T args) { return AsStrong!T(args); }
79 	/** Citation. */
80 	struct AsCitation(T...) { T args; } auto ref asCitation(T...)(T args) { return AsCitation!T(args); }
81 	/** Deleted. */
82 	struct AsDeleted(T...) { T args; } auto ref asDeleted(T...)(T args) { return AsDeleted!T(args); }
83 	/** Inserted. */
84 	struct AsInserted(T...) { T args; } auto ref asInserted(T...)(T args) { return AsInserted!T(args); }
85 	/** Superscript. */
86 	struct AsSuperscript(T...) { T args; } auto ref asSuperscript(T...)(T args) { return AsSuperscript!T(args); }
87 	/** Subscript. */
88 	struct AsSubscript(T...) { T args; } auto ref asSubscript(T...)(T args) { return AsSubscript!T(args); }
89 
90 	/** Preformatted. */
91 	struct AsPreformatted(T...) { T args; } auto ref asPreformatted(T...)(T args) { return AsPreformatted!T(args); }
92 
93 	/** Scan hit with index `ix`. */
94 	struct AsHit(T...) { uint ix; T args; } auto ref asHit(T)(uint ix, T args) { return AsHit!T(ix, args); }
95 
96 	/** Scan hit context with index `ix`. */
97 	struct AsCtx(T...) { uint ix; T args; } auto ref asCtx(T)(uint ix, T args) { return AsCtx!T(ix, args); }
98 
99 	/** Header. */
100 	struct AsHeader(uint Level, T...) { T args; enum level = Level; }
101 	auto ref asHeader(uint Level, T...)(T args) { return AsHeader!(Level, T)(args); }
102 
103 	/** Paragraph. */
104 	struct AsParagraph(T...) { T args; } auto ref asParagraph(T...)(T args) { return AsParagraph!T(args); }
105 
106 	/** Multi-Paragraph Blockquote. */
107 	struct AsBlockquote(T...) { T args; } auto ref asBlockquote(T...)(T args) { return AsBlockquote!T(args); }
108 
109 	/** Single-Paragraph Blockquote. */
110 	struct AsBlockquoteSP(T...) { T args; } auto ref asBlockquoteSP(T...)(T args) { return AsBlockquoteSP!T(args); }
111 
112 	/** Unordered List.
113 		TODO: Should asUList, asOList autowrap args as AsItems when needed?
114 	*/
115 	struct AsUList(T...) { T args; } auto ref asUList(T...)(T args) { return AsUList!T(args); }
116 	/** Ordered List. */
117 	struct AsOList(T...) { T args; } auto ref asOList(T...)(T args) { return AsOList!T(args); }
118 
119 	/** Description. */
120 	struct AsDescription(T...) { T args; } auto ref asDescription(T...)(T args) { return AsDescription!T(args); }
121 
122 	/** Horizontal Ruler. */
123 	struct HorizontalRuler {} auto ref horizontalRuler() { return HorizontalRuler(); }
124 
125 	/** MDash. */
126 	struct MDash {} auto ref mDash() { return MDash(); }
127 
128 	enum RowNr { none, offsetZero, offsetOne }
129 
130 	/** Table.
131 		TODO: Should asTable autowrap args AsRows when needed?
132 	*/
133 	struct AsTable(T...) {
134 		string border;
135 		RowNr rowNr;
136 		bool recurseFlag;
137 		T args;
138 	}
139 	auto ref asTable(T...)(T args) { return AsTable!T(`"1"`, RowNr.none, false, args); }
140 	auto ref asTableTree(T...)(T args) { return AsTable!T(`"1"`, RowNr.none, true, args); }
141 	alias asTablesTable = asTableTree;
142 	auto ref asTableNr0(T...)(T args) { return AsTable!T(`"1"`, RowNr.offsetZero, false, args); }
143 	auto ref asTableNr1(T...)(T args) { return AsTable!T(`"1"`, RowNr.offsetOne, false, args); }
144 
145 	struct AsCols(T...) {
146 		RowNr rowNr;
147 		size_t rowIx;
148 		bool recurseFlag;
149 		T args;
150 	}
151 	auto ref asCols(T...)(T args) { return AsCols!T(RowNr.none, 0, false, args); }
152 
153 	/** Numbered Rows */
154 	struct AsRows(T...) {
155 		RowNr rowNr;
156 		bool recurseFlag;
157 		T args;
158 	}
159 	auto ref asRows(T...)(T args) { return AsRows!(T)(RowNr.none, false, args); }
160 
161 	/** Table Row. */
162 	struct AsRow(T...) { T args; } auto ref asRow(T...)(T args) { return AsRow!T(args); }
163 	/** Table Cell. */
164 	struct AsCell(T...) { T args; } auto ref asCell(T...)(T args) { return AsCell!T(args); }
165 
166 	/** Row/Column/... Span. */
167 	struct Span(T...) { uint _span; T args; }
168 	auto span(T...)(uint span, T args) { return span!T(span, args); }
169 
170 	/** Table Heading. */
171 	struct AsTHeading(T...) { T args; } auto ref asTHeading(T...)(T args) { return AsTHeading!T(args); }
172 
173 	/* /\** Unordered List Beginner. *\/ */
174 	/* struct UListBegin(T...) { T args; } */
175 	/* auto uListBegin(T...)(T args) { return UListBegin!T(args); } */
176 	/* /\** Unordered List Ender. *\/ */
177 	/* struct UListEnd(T...) { T args; } */
178 	/* auto uListEnd(T...)(T args) { return UListEnd!T(args); } */
179 	/* /\** Ordered List Beginner. *\/ */
180 	/* struct OListBegin(T...) { T args; } */
181 	/* auto oListBegin(T...)(T args) { return OListBegin!T(args); } */
182 	/* /\** Ordered List Ender. *\/ */
183 	/* struct OListEnd(T...) { T args; } */
184 	/* auto oListEnd(T...)(T args) { return OListEnd!T(args); } */
185 
186 	/** List Item. */
187 	struct AsItem(T...) { T args; } auto ref asItem(T...)(T args) { return AsItem!T(args); }
188 
189 	string lbr(bool useHTML) { return (useHTML ? `<br>` : ``); } // line break
190 
191 	/* HTML Aliases */
192 	alias asB = asBold;
193 	alias asI = asBold;
194 	alias asTT = asMonospaced;
195 	alias asP = asParagraph;
196 	alias asH = asHeader;
197 	alias asHR = horizontalRuler;
198 	alias asUL = asUList;
199 	alias asOL = asOList;
200 	alias asTR = asRow;
201 	alias asTD = asCell;
202 }
203 
204 struct As(Attribute, Things...) {
205 	Things things;
206 }
207 auto ref as(Attribute, Things...)(Things things) {
208 	return As!(Attribute, Things)(things);
209 }