sommark 2.3.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -42
- package/SOMMARK-SPEC.md +483 -0
- package/cli/cli.mjs +42 -2
- package/cli/commands/color.js +36 -0
- package/cli/commands/help.js +7 -0
- package/cli/commands/init.js +2 -0
- package/cli/commands/list.js +119 -0
- package/cli/commands/print.js +61 -6
- package/cli/commands/show.js +24 -27
- package/cli/constants.js +1 -1
- package/cli/helpers/config.js +14 -4
- package/cli/helpers/transpile.js +28 -33
- package/constants/html_props.js +100 -0
- package/constants/html_tags.js +146 -0
- package/constants/void_elements.js +26 -0
- package/core/lexer.js +70 -39
- package/core/parser.js +102 -81
- package/core/pluginManager.js +139 -0
- package/core/plugins/comment-remover.js +47 -0
- package/core/plugins/module-system.js +137 -0
- package/core/plugins/quote-escaper.js +37 -0
- package/core/plugins/raw-content-plugin.js +72 -0
- package/core/plugins/rules-validation-plugin.js +197 -0
- package/core/plugins/sommark-format.js +211 -0
- package/core/transpiler.js +65 -198
- package/debug.js +9 -4
- package/format.js +23 -0
- package/formatter/mark.js +3 -3
- package/formatter/tag.js +6 -2
- package/grammar.ebnf +5 -5
- package/helpers/camelize.js +2 -0
- package/helpers/colorize.js +20 -14
- package/helpers/kebabize.js +2 -0
- package/helpers/utils.js +161 -0
- package/index.js +243 -44
- package/mappers/languages/html.js +200 -105
- package/mappers/languages/json.js +23 -4
- package/mappers/languages/markdown.js +88 -67
- package/mappers/languages/mdx.js +130 -2
- package/mappers/mapper.js +77 -246
- package/package.json +7 -5
- package/unformatted.smark +90 -0
- package/v3-todo.smark +75 -0
- package/CHANGELOG.md +0 -113
- package/helpers/loadCss.js +0 -46
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<img width="2000" height="491" alt="SomMark Cover" src="https://raw.githubusercontent.com/Adam-Elmi/SomMark/master/assets/smark_bg.png" />
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
SomMark is a
|
|
4
|
+
SomMark v3 is a simple, flexible markup language for structured content.
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
@@ -16,7 +16,7 @@ SomMark is a declarative, extensible markup language for structured content that
|
|
|
16
16
|
</a>
|
|
17
17
|
|
|
18
18
|
<!--Language Type-->
|
|
19
|
-
<img src="https://img.shields.io/badge/type-markup%20language-
|
|
19
|
+
<img src="https://img.shields.io/badge/type-markup%20language-orange?style=flat-square" />
|
|
20
20
|
|
|
21
21
|
<!--SomMark Playground-->
|
|
22
22
|
<a href="https://adam-elmi.github.io/SomMark-Playground" target="_blank">
|
|
@@ -26,81 +26,86 @@ alt="SomMark Playground Badge" />
|
|
|
26
26
|
</a>
|
|
27
27
|
</p>
|
|
28
28
|
|
|
29
|
-
|
|
30
29
|
----
|
|
31
30
|
|
|
32
31
|
## Try SomMark Playground
|
|
33
32
|
|
|
34
|
-
Test SomMark
|
|
33
|
+
Test SomMark live in your browser:
|
|
35
34
|
[https://adam-elmi.github.io/SomMark-Playground/](https://adam-elmi.github.io/SomMark-Playground/)
|
|
36
35
|
|
|
37
36
|
----
|
|
38
37
|
|
|
39
|
-
#
|
|
38
|
+
# What's new in v3?
|
|
40
39
|
|
|
41
|
-
|
|
42
|
-
> Old version(v1) is no longer supported.
|
|
40
|
+
SomMark v3 is faster, more powerful, and easier to extend.
|
|
43
41
|
|
|
44
|
-
**
|
|
42
|
+
- **HTML Support**: Full HTML5 Support
|
|
43
|
+
- **Markdown Support**: Full Markdown Support
|
|
44
|
+
- **JSON Support**: Full JSON Support
|
|
45
|
+
- **MDX Support**: Full MDX Support
|
|
46
|
+
- **Plugin System**: Add new features without changing the core code.
|
|
47
|
+
- **Modular Support**: Easily import files and use variables.
|
|
48
|
+
- **Type-Safe Rules**: Set requirements for tags and attributes.
|
|
49
|
+
- **Clean Syntax**: Simplified block, atblock & inline rules and better error handling.
|
|
45
50
|
|
|
46
51
|
# Installation
|
|
47
52
|
|
|
48
|
-
To install the Command Line Interface (CLI) globally:
|
|
49
|
-
|
|
50
53
|
```bash
|
|
51
54
|
npm install -g sommark
|
|
52
55
|
```
|
|
53
56
|
|
|
54
57
|
# Usage
|
|
55
58
|
|
|
56
|
-
##
|
|
59
|
+
## v3 Syntax Example
|
|
57
60
|
|
|
58
|
-
|
|
61
|
+
SomMark is designed to be readable and clear.
|
|
59
62
|
|
|
60
|
-
```
|
|
61
|
-
#
|
|
62
|
-
|
|
63
|
+
```ini
|
|
64
|
+
# Html
|
|
65
|
+
[h1]Welcome to SomMark v3[end]
|
|
63
66
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
[section = class: "hero", id: "main"]
|
|
68
|
+
[a = href: "https://sommark.org"]Visit Website[end]
|
|
69
|
+
[end]
|
|
70
|
+
|
|
71
|
+
# Markdown
|
|
72
|
+
[quote]
|
|
73
|
+
SomMark is simple and powerful.
|
|
74
|
+
[end]
|
|
75
|
+
|
|
76
|
+
[bold]Check out our syntax guide![end]
|
|
67
77
|
|
|
68
|
-
|
|
78
|
+
# Json
|
|
79
|
+
[Json= object]
|
|
80
|
+
[Object = "user"]
|
|
81
|
+
(name)->(string: "Adam Elmi")
|
|
82
|
+
(age)->(number: 25)
|
|
83
|
+
(is_active_user)->(bool: true)
|
|
84
|
+
[end]
|
|
85
|
+
[end]
|
|
86
|
+
```
|
|
69
87
|
|
|
70
|
-
|
|
88
|
+
## Using in JavaScript
|
|
71
89
|
|
|
72
90
|
```javascript
|
|
73
91
|
import SomMark from "sommark";
|
|
74
92
|
|
|
75
|
-
const source = `
|
|
76
|
-
[Block]
|
|
77
|
-
Hello World
|
|
78
|
-
[end]
|
|
79
|
-
`;
|
|
80
|
-
|
|
81
93
|
const smark = new SomMark({
|
|
82
|
-
src:
|
|
94
|
+
src: '[h1]Hello World[end]',
|
|
83
95
|
format: "html"
|
|
84
96
|
});
|
|
85
97
|
|
|
86
98
|
console.log(await smark.transpile());
|
|
87
99
|
```
|
|
88
100
|
|
|
89
|
-
## Supported Languages
|
|
90
|
-
|
|
91
|
-
* HTML
|
|
92
|
-
* Markdown
|
|
93
|
-
* MDX (Only ready components)
|
|
94
|
-
* JSON
|
|
95
|
-
|
|
96
|
-
|
|
97
101
|
# Documentation
|
|
98
102
|
|
|
99
|
-
|
|
103
|
+
Read our detailed guides in the `docs/` folder:
|
|
100
104
|
|
|
101
|
-
- **[Syntax Guide](docs/03.syntax.md)**:
|
|
102
|
-
- **[
|
|
103
|
-
- **[
|
|
104
|
-
- **[
|
|
105
|
-
- **[API
|
|
106
|
-
- **[
|
|
105
|
+
- **[Syntax Guide](docs/03.syntax.md)**: How to write SomMark (Blocks, Inline, At-Blocks).
|
|
106
|
+
- **[Plugin System](docs/19.plugin-system.md)**: How to create your own plugins.
|
|
107
|
+
- **[Built-in Plugins](docs/20.built-in-plugins.md)**: Guide to standard plugins.
|
|
108
|
+
- **[Core API](docs/09.core.md)**: How to use SomMark in your code.
|
|
109
|
+
- **[Mapper API](docs/13.mapper.md)**: How to create new output formats.
|
|
110
|
+
- **[CLI Reference](docs/11.cli.md)**: Terminal commands and flags.
|
|
111
|
+
- **[API Quick Reference](docs/api)**: Fast lookup for all functions.
|
package/SOMMARK-SPEC.md
ADDED
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
# SomMark Specification
|
|
2
|
+
|
|
3
|
+
**SomMark** is a lightweight structured markup language designed to support hierarchical content, inline transformations, and raw text embedding.
|
|
4
|
+
|
|
5
|
+
SomMark provides three primary constructs:
|
|
6
|
+
|
|
7
|
+
1. **Blocks** – hierarchical containers that support nesting
|
|
8
|
+
2. **Inline Statements** – inline value transformations
|
|
9
|
+
3. **AtBlocks** – raw text containers where parsing is disabled
|
|
10
|
+
|
|
11
|
+
Additionally, SomMark supports **comments** and **escape sequences**.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# 1. Identifiers
|
|
16
|
+
|
|
17
|
+
Identifiers are used to name **Blocks**, **Inline Statements**, and **AtBlocks**.
|
|
18
|
+
|
|
19
|
+
## Allowed Characters
|
|
20
|
+
|
|
21
|
+
Identifiers may contain:
|
|
22
|
+
|
|
23
|
+
* Letters (`a-z`, `A-Z`)
|
|
24
|
+
* Numbers (`0-9`)
|
|
25
|
+
* Dollar sign (`$`)
|
|
26
|
+
* Underscore (`_`)
|
|
27
|
+
* Hyphen (`-`)
|
|
28
|
+
|
|
29
|
+
Example valid identifiers:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
Block
|
|
33
|
+
section-1
|
|
34
|
+
user_profile
|
|
35
|
+
$template
|
|
36
|
+
note-2
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Example invalid identifiers:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
my block
|
|
43
|
+
test@
|
|
44
|
+
hello!
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Identifiers **must not contain spaces**.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
# 2. Blocks
|
|
52
|
+
|
|
53
|
+
> At the top level, only Blocks and comments are permitted.
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
Blocks are hierarchical containers that can contain other blocks, inline statements, or plain text.
|
|
57
|
+
|
|
58
|
+
Blocks are the primary structural element of SomMark.
|
|
59
|
+
|
|
60
|
+
## Block Syntax
|
|
61
|
+
|
|
62
|
+
### Block with Arguments
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
[Identifier = arg1, arg2, key:value]
|
|
66
|
+
Block body content...
|
|
67
|
+
[end]
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Example:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
[Note = important, level:2]
|
|
74
|
+
This is a note block.
|
|
75
|
+
[end]
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
### Block without Arguments
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
[Identifier]
|
|
84
|
+
Block body content...
|
|
85
|
+
[end]
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Example:
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
[Section]
|
|
92
|
+
This is a section.
|
|
93
|
+
[end]
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Block Behavior
|
|
99
|
+
|
|
100
|
+
* Blocks **support nesting**.
|
|
101
|
+
* Blocks can contain:
|
|
102
|
+
|
|
103
|
+
* plain text
|
|
104
|
+
* inline statements
|
|
105
|
+
* other blocks
|
|
106
|
+
* Arguments are optional.
|
|
107
|
+
* Arguments may be:
|
|
108
|
+
|
|
109
|
+
* **positional values**
|
|
110
|
+
* **key-value pairs**
|
|
111
|
+
|
|
112
|
+
Example:
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
[Article = author:Adam]
|
|
116
|
+
|
|
117
|
+
Welcome to the article.
|
|
118
|
+
|
|
119
|
+
[Section = title:Intro]
|
|
120
|
+
This is the introduction.
|
|
121
|
+
[end]
|
|
122
|
+
|
|
123
|
+
[end]
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
# 3. Inline Statements
|
|
129
|
+
|
|
130
|
+
Inline statements transform or process a **value** within text.
|
|
131
|
+
|
|
132
|
+
Inline statements **do not allow nested SomMark syntax**.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Inline Syntax
|
|
137
|
+
|
|
138
|
+
### Inline with Arguments
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
(Value)->(Identifier: arg1, arg2, arg3)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Example:
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
(hello world)->(uppercase)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
### Inline without Arguments
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
(Value)->(Identifier)
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Example:
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
(hello)->(bold)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Inline Behavior
|
|
167
|
+
|
|
168
|
+
* `(Value)` is the **input value**.
|
|
169
|
+
* `(Identifier)` specifies the operation.
|
|
170
|
+
* Inline arguments **cannot use key:value syntax**.
|
|
171
|
+
* Inline statements **cannot contain nested syntax**.
|
|
172
|
+
|
|
173
|
+
Example:
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
(This text)->(highlight: yellow)
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
# 4. AtBlocks (Raw Text Blocks)
|
|
182
|
+
|
|
183
|
+
AtBlocks are used when content must be treated as **plain text**.
|
|
184
|
+
|
|
185
|
+
No SomMark syntax inside an AtBlock is parsed.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## AtBlock Syntax
|
|
190
|
+
|
|
191
|
+
### AtBlock with Arguments
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
@_Identifier_@: arg1, arg2, key:value;
|
|
195
|
+
Raw content here.
|
|
196
|
+
Everything is treated as plain text.
|
|
197
|
+
@_end_@
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Example:
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
@_Code_@: lang:js;
|
|
204
|
+
|
|
205
|
+
function hello(){
|
|
206
|
+
console.log("hello");
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
@_end_@
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
### AtBlock without Arguments
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
@_Identifier_@;
|
|
218
|
+
content...
|
|
219
|
+
@_end_@
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Example:
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
@_Raw_@;
|
|
226
|
+
[This will not be parsed]
|
|
227
|
+
(Value)->(test)
|
|
228
|
+
@_end_@
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## AtBlock Behavior
|
|
234
|
+
|
|
235
|
+
* Content inside AtBlocks is **not parsed**.
|
|
236
|
+
* All characters inside are treated as **plain text**.
|
|
237
|
+
* Nested SomMark syntax is ignored.
|
|
238
|
+
* The AtBlock header **MUST end with a semicolon (`;`)**, even if no arguments are provided.
|
|
239
|
+
|
|
240
|
+
Example:
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
@_Template_@: engine:handlebars;
|
|
244
|
+
|
|
245
|
+
{{ user.name }}
|
|
246
|
+
|
|
247
|
+
@_end_@
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
# 5. Arguments
|
|
253
|
+
|
|
254
|
+
Arguments are used in **Blocks** and **AtBlocks**.
|
|
255
|
+
|
|
256
|
+
## Argument Types
|
|
257
|
+
|
|
258
|
+
### Positional Arguments
|
|
259
|
+
|
|
260
|
+
```
|
|
261
|
+
arg1, arg2, arg3
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Example:
|
|
265
|
+
|
|
266
|
+
```
|
|
267
|
+
[Block = first, second]
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
### Key-Value Arguments
|
|
273
|
+
|
|
274
|
+
```
|
|
275
|
+
key:value
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Example:
|
|
279
|
+
|
|
280
|
+
```
|
|
281
|
+
[Block = title:Intro, level:2]
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## Argument Restrictions
|
|
287
|
+
|
|
288
|
+
Arguments may contain most characters including:
|
|
289
|
+
|
|
290
|
+
```
|
|
291
|
+
[
|
|
292
|
+
]
|
|
293
|
+
(
|
|
294
|
+
)
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
However the following characters are restricted:
|
|
298
|
+
|
|
299
|
+
### Colon (`:`)
|
|
300
|
+
|
|
301
|
+
Colon is used to separate **key-value pairs**.
|
|
302
|
+
|
|
303
|
+
Example:
|
|
304
|
+
|
|
305
|
+
```
|
|
306
|
+
key:value
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
If a colon must appear in a value, it must be escaped.
|
|
310
|
+
|
|
311
|
+
Example:
|
|
312
|
+
|
|
313
|
+
```
|
|
314
|
+
x\:y
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Example block:
|
|
318
|
+
|
|
319
|
+
```
|
|
320
|
+
[Block = path:x\:y]
|
|
321
|
+
content
|
|
322
|
+
[end]
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
### Semicolon (`;`)
|
|
328
|
+
|
|
329
|
+
Semicolon is used **only in AtBlock arguments**.
|
|
330
|
+
|
|
331
|
+
It indicates the **end of the argument list**.
|
|
332
|
+
|
|
333
|
+
Example:
|
|
334
|
+
|
|
335
|
+
```
|
|
336
|
+
@_Code_@: lang:js, theme:dark;
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
Semicolons **have no special meaning** in Blocks or Inline Statements.
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
# 6. Escape Character
|
|
344
|
+
|
|
345
|
+
SomMark uses the **backslash (`\`)** as the escape character.
|
|
346
|
+
|
|
347
|
+
Escaping works similarly to JavaScript string escaping.
|
|
348
|
+
|
|
349
|
+
Example:
|
|
350
|
+
|
|
351
|
+
```
|
|
352
|
+
\[
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
This prevents a block from being parsed.
|
|
356
|
+
|
|
357
|
+
Example:
|
|
358
|
+
|
|
359
|
+
```
|
|
360
|
+
\[Not a block\]
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
Escaping can also be used inside arguments.
|
|
364
|
+
|
|
365
|
+
Example:
|
|
366
|
+
|
|
367
|
+
```
|
|
368
|
+
[Block = x\:y]
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
373
|
+
# 7. Comments
|
|
374
|
+
|
|
375
|
+
SomMark supports **single-line comments**.
|
|
376
|
+
|
|
377
|
+
## Syntax
|
|
378
|
+
|
|
379
|
+
```
|
|
380
|
+
# this is a comment
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
Everything following `#` until the end of the line is ignored by the parser.
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## Comment Rules
|
|
388
|
+
|
|
389
|
+
Comments may appear:
|
|
390
|
+
|
|
391
|
+
* on their own line
|
|
392
|
+
* between blocks
|
|
393
|
+
* after statements
|
|
394
|
+
|
|
395
|
+
Example:
|
|
396
|
+
|
|
397
|
+
```
|
|
398
|
+
# Article metadata
|
|
399
|
+
|
|
400
|
+
[Article = author:Adam]
|
|
401
|
+
|
|
402
|
+
# introduction
|
|
403
|
+
[Section = title:Intro]
|
|
404
|
+
Welcome to SomMark.
|
|
405
|
+
[end]
|
|
406
|
+
|
|
407
|
+
[end]
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
412
|
+
## Comments Inside AtBlocks
|
|
413
|
+
|
|
414
|
+
Inside AtBlocks, comments are treated as **plain text**.
|
|
415
|
+
|
|
416
|
+
Example:
|
|
417
|
+
|
|
418
|
+
```
|
|
419
|
+
@_Code_@: lang:js;
|
|
420
|
+
|
|
421
|
+
# This line is not treated as a comment
|
|
422
|
+
console.log("Hello")
|
|
423
|
+
|
|
424
|
+
@_end_@
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
---
|
|
428
|
+
|
|
429
|
+
# 8. Non-Empty Content Rules
|
|
430
|
+
|
|
431
|
+
The following elements **must not be empty**:
|
|
432
|
+
|
|
433
|
+
* Block body
|
|
434
|
+
* AtBlock body
|
|
435
|
+
* Inline value
|
|
436
|
+
|
|
437
|
+
Invalid examples:
|
|
438
|
+
|
|
439
|
+
```
|
|
440
|
+
()->(Identifier)
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
---
|
|
444
|
+
|
|
445
|
+
# 9. Flexible Formatting
|
|
446
|
+
|
|
447
|
+
SomMark allows flexible formatting and whitespace.
|
|
448
|
+
|
|
449
|
+
The following are equivalent.
|
|
450
|
+
|
|
451
|
+
## Compact Format
|
|
452
|
+
|
|
453
|
+
```
|
|
454
|
+
[Block]Hello World[end]
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
## Expanded Format
|
|
458
|
+
|
|
459
|
+
```
|
|
460
|
+
[
|
|
461
|
+
Block
|
|
462
|
+
]
|
|
463
|
+
|
|
464
|
+
Hello World
|
|
465
|
+
|
|
466
|
+
[
|
|
467
|
+
end
|
|
468
|
+
]
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
Inline and AtBlocks follow similar whitespace flexibility.
|
|
472
|
+
|
|
473
|
+
---
|
|
474
|
+
|
|
475
|
+
# 10. Construct Summary
|
|
476
|
+
|
|
477
|
+
| Construct | Nesting | Arguments | Key-Value Args | Parsing |
|
|
478
|
+
| ---------------- | ------- | --------- | -------------- | ---------- |
|
|
479
|
+
| Block | Yes | Optional | Yes | Parsed |
|
|
480
|
+
| Inline Statement | No | Optional | No | Parsed |
|
|
481
|
+
| AtBlock | No | Optional | Yes | Not parsed (Header ends with `;`) |
|
|
482
|
+
| Comment | No | No | No | Parsed but ignored by built-in "comment-remover" plugin during AST |
|
|
483
|
+
|
package/cli/cli.mjs
CHANGED
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { enableColor } from "../helpers/colorize.js";
|
|
2
3
|
import { getHelp } from "./commands/help.js";
|
|
3
4
|
import { printVersion, printHeader } from "./commands/version.js";
|
|
4
5
|
import { runBuild } from "./commands/build.js";
|
|
5
|
-
import { printOutput } from "./commands/print.js";
|
|
6
|
+
import { printOutput, printLex, printParse } from "./commands/print.js";
|
|
6
7
|
import { runInit } from "./commands/init.js";
|
|
7
8
|
import { runShow } from "./commands/show.js";
|
|
9
|
+
import { runColor } from "./commands/color.js";
|
|
8
10
|
import { extensions } from "./constants.js";
|
|
9
11
|
|
|
12
|
+
// ========================================================================== //
|
|
13
|
+
// Color Support //
|
|
14
|
+
// ========================================================================== //
|
|
15
|
+
import { isColorEnabled } from "./commands/color.js";
|
|
16
|
+
|
|
17
|
+
if (process.env.SOMMARK_COLOR === "true" || await isColorEnabled()) {
|
|
18
|
+
enableColor(true);
|
|
19
|
+
}
|
|
20
|
+
|
|
10
21
|
// ========================================================================== //
|
|
11
22
|
// Argument Parsing //
|
|
12
23
|
// ========================================================================== //
|
|
@@ -47,7 +58,36 @@ async function main() {
|
|
|
47
58
|
return;
|
|
48
59
|
}
|
|
49
60
|
|
|
50
|
-
//
|
|
61
|
+
// 5.5. Color
|
|
62
|
+
if (command === "color") {
|
|
63
|
+
runColor(args[1]);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// 5.6. List
|
|
68
|
+
if (command === "list") {
|
|
69
|
+
const { runListPlugins, runListPipeline } = await import("./commands/list.js");
|
|
70
|
+
if (args[1] === "pipeline") {
|
|
71
|
+
await runListPipeline();
|
|
72
|
+
} else {
|
|
73
|
+
await runListPlugins(args.slice(1));
|
|
74
|
+
}
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// 6. Lex
|
|
79
|
+
if (command === "--lex") {
|
|
80
|
+
await printLex(args[1]);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// 7. Parse
|
|
85
|
+
if (command === "--parse") {
|
|
86
|
+
await printParse(args[1]);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// 9. Print to Console ( -p or --print )
|
|
51
91
|
|
|
52
92
|
const format = command ? command.replace(/^--/, "") : "";
|
|
53
93
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { getConfigDir } from "./init.js";
|
|
4
|
+
|
|
5
|
+
// ========================================================================== //
|
|
6
|
+
// Color Command //
|
|
7
|
+
// ========================================================================== //
|
|
8
|
+
|
|
9
|
+
const COLOR_FILE = "color.json";
|
|
10
|
+
|
|
11
|
+
function getColorFilePath() {
|
|
12
|
+
return path.join(getConfigDir(), COLOR_FILE);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export async function isColorEnabled() {
|
|
16
|
+
try {
|
|
17
|
+
const data = await fs.readFile(getColorFilePath(), "utf-8");
|
|
18
|
+
return JSON.parse(data).enabled === true;
|
|
19
|
+
} catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function runColor(action) {
|
|
25
|
+
if (action === "on") {
|
|
26
|
+
fs.mkdir(getConfigDir(), { recursive: true })
|
|
27
|
+
.then(() => fs.writeFile(getColorFilePath(), JSON.stringify({ enabled: true }), "utf-8"))
|
|
28
|
+
.then(() => console.log("Colors enabled."));
|
|
29
|
+
} else if (action === "off") {
|
|
30
|
+
fs.mkdir(getConfigDir(), { recursive: true })
|
|
31
|
+
.then(() => fs.writeFile(getColorFilePath(), JSON.stringify({ enabled: false }), "utf-8"))
|
|
32
|
+
.then(() => console.log("Colors disabled."));
|
|
33
|
+
} else {
|
|
34
|
+
console.log("Usage: sommark color <on|off>");
|
|
35
|
+
}
|
|
36
|
+
}
|