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