sommark 3.3.3 → 4.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 +98 -82
- package/assets/logo.json +28 -0
- package/assets/smark.logo.png +0 -0
- package/assets/smark.logo.svg +21 -0
- package/cli/cli.mjs +8 -16
- package/cli/commands/build.js +24 -4
- package/cli/commands/color.js +22 -26
- package/cli/commands/help.js +10 -10
- package/cli/commands/init.js +19 -42
- package/cli/commands/print.js +20 -12
- package/cli/commands/show.js +4 -0
- package/cli/commands/version.js +6 -0
- package/cli/constants.js +9 -5
- package/cli/helpers/config.js +11 -0
- package/cli/helpers/file.js +17 -6
- package/cli/helpers/transpile.js +7 -8
- package/core/errors.js +49 -25
- package/core/formats.js +7 -3
- package/core/formatter.js +215 -0
- package/core/helpers/config-loader.js +37 -56
- package/core/labels.js +21 -9
- package/core/lexer.js +491 -212
- package/core/modules.js +164 -0
- package/core/parser.js +516 -389
- package/core/tokenTypes.js +36 -1
- package/core/transpiler.js +237 -151
- package/core/validator.js +79 -0
- package/formatter/mark.js +203 -43
- package/formatter/tag.js +202 -32
- package/grammar.ebnf +57 -50
- package/helpers/colorize.js +26 -13
- package/helpers/escapeHTML.js +13 -6
- package/helpers/kebabize.js +6 -0
- package/helpers/peek.js +9 -0
- package/helpers/removeChar.js +26 -13
- package/helpers/safeDataParser.js +114 -0
- package/helpers/utils.js +140 -158
- package/index.js +198 -188
- package/mappers/languages/html.js +105 -213
- package/mappers/languages/json.js +122 -171
- package/mappers/languages/markdown.js +355 -108
- package/mappers/languages/mdx.js +76 -114
- package/mappers/languages/xml.js +114 -0
- package/mappers/mapper.js +152 -123
- package/mappers/shared/index.js +22 -0
- package/package.json +26 -6
- package/SOMMARK-SPEC.md +0 -481
- package/cli/commands/list.js +0 -124
- package/constants/html_tags.js +0 -146
- package/core/pluginManager.js +0 -149
- package/core/plugins/comment-remover.js +0 -47
- package/core/plugins/module-system.js +0 -176
- package/core/plugins/raw-content-plugin.js +0 -78
- package/core/plugins/rules-validation-plugin.js +0 -231
- package/core/plugins/sommark-format.js +0 -244
- package/coverage_test.js +0 -21
- package/debug.js +0 -15
- package/helpers/camelize.js +0 -2
- package/helpers/defaultTheme.js +0 -3
- package/test_format_fix.js +0 -42
- package/v3-todo.smark +0 -73
package/README.md
CHANGED
|
@@ -1,118 +1,134 @@
|
|
|
1
|
-
<img
|
|
1
|
+
# SomMark v4 <img src="assets/smark.logo.png" width="80" align="right">
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
SomMark
|
|
5
|
-
</p>
|
|
3
|
+
[](https://www.npmjs.com/package/sommark)
|
|
4
|
+
[](https://github.com/Adam-Elmi/SomMark/blob/master/LICENSE)
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
<!--License-->
|
|
9
|
-
<a href="https://www.npmjs.com/package/sommark" target="_blank">
|
|
10
|
-
<img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" />
|
|
11
|
-
</a>
|
|
6
|
+
SomMark is a high-performance markup language designed for structured content. It acts as an extensible source language that can be transformed into multiple formats like HTML, JSON, MDX, XML, and Markdown.
|
|
12
7
|
|
|
13
|
-
|
|
14
|
-
<a href="https://www.npmjs.com/package/sommark" target="_blank">
|
|
15
|
-
<img src="https://img.shields.io/npm/v/sommark?style=flat-square" />
|
|
16
|
-
</a>
|
|
8
|
+
SomMark uses explicit structural boundaries to ensure your document remains stable and predictable. It enables infinite nesting and provides total control over your contents.
|
|
17
9
|
|
|
18
|
-
|
|
19
|
-
<img src="https://img.shields.io/badge/type-markup%20language-orange?style=flat-square" />
|
|
10
|
+
---
|
|
20
11
|
|
|
21
|
-
|
|
22
|
-
<a href="https://adam-elmi.github.io/SomMark-Playground" target="_blank">
|
|
23
|
-
<img
|
|
24
|
-
src="https://img.shields.io/badge/SomMark-Playground-blue?style=flat-square"
|
|
25
|
-
alt="SomMark Playground Badge" />
|
|
26
|
-
</a>
|
|
27
|
-
</p>
|
|
12
|
+
## Simple Showcase
|
|
28
13
|
|
|
29
|
-
|
|
14
|
+
SomMark uses blocks for structure. A block starts with `[identifier]` and must end with `[end]`.
|
|
30
15
|
|
|
31
|
-
|
|
16
|
+
### HTML
|
|
17
|
+
```ini
|
|
18
|
+
[h1]Welcome to SomMark[end]
|
|
19
|
+
|
|
20
|
+
[div = class: "main"]
|
|
21
|
+
This is content inside a container block.
|
|
22
|
+
[p]
|
|
23
|
+
Blocks are the most important part of SomMark.
|
|
24
|
+
(This is a span-like inline statement)->(css: "color: green")
|
|
25
|
+
[end]
|
|
26
|
+
[end]
|
|
27
|
+
```
|
|
32
28
|
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
### JSON
|
|
30
|
+
SomMark can represent complex data structures through its specialized mappers.
|
|
31
|
+
```ini
|
|
32
|
+
[object]
|
|
33
|
+
[string = key: "name"]Adam Elmi[end]
|
|
34
|
+
[number = key: "age"]25[end]
|
|
35
|
+
[array = key: "skills"]
|
|
36
|
+
[string]JavaScript[end]
|
|
37
|
+
[string]SomMark[end]
|
|
38
|
+
[end]
|
|
39
|
+
[end]
|
|
40
|
+
```
|
|
35
41
|
|
|
36
|
-
|
|
42
|
+
### XML
|
|
43
|
+
SomMark produces clean, structured XML ideal for configuration and data manifests.
|
|
44
|
+
```ini
|
|
45
|
+
[xml = version: "1.0"][end]
|
|
46
|
+
[project = name: "SomMark-App"]
|
|
47
|
+
[metadata]
|
|
48
|
+
[author]Adam Elmi[end]
|
|
49
|
+
[version]4.0.0[end]
|
|
50
|
+
[end]
|
|
51
|
+
[settings]
|
|
52
|
+
[database = type: "postgres"]
|
|
53
|
+
[host]localhost[end]
|
|
54
|
+
[port]5432[end]
|
|
55
|
+
[end]
|
|
56
|
+
[end]
|
|
57
|
+
[end]
|
|
58
|
+
```
|
|
37
59
|
|
|
38
|
-
|
|
60
|
+
### MDX
|
|
61
|
+
Use the JavaScript data layer to pass native data to your components.
|
|
62
|
+
```ini
|
|
63
|
+
[h1]MDX Portfolio[end]
|
|
39
64
|
|
|
40
|
-
|
|
65
|
+
[Gallery =
|
|
66
|
+
images: js{["nature.jpg", "tech.jpg"]},
|
|
67
|
+
active: js{true}
|
|
68
|
+
]
|
|
69
|
+
This block uses native JS arrays and booleans.
|
|
70
|
+
[end]
|
|
71
|
+
```
|
|
41
72
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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.
|
|
73
|
+
### Markdown
|
|
74
|
+
Use placeholders to inject dynamic text into your templates.
|
|
75
|
+
```ini
|
|
76
|
+
[h1]Hello p{username}[end]
|
|
50
77
|
|
|
51
|
-
|
|
78
|
+
[quote]
|
|
79
|
+
You are reading documentation on p{siteName}.
|
|
80
|
+
SomMark is an extensible language.
|
|
81
|
+
[end]
|
|
52
82
|
|
|
53
|
-
|
|
54
|
-
npm install -g sommark
|
|
83
|
+
[hr][end]
|
|
55
84
|
```
|
|
56
85
|
|
|
57
|
-
|
|
86
|
+
---
|
|
58
87
|
|
|
59
|
-
##
|
|
88
|
+
## How It Works
|
|
60
89
|
|
|
61
|
-
SomMark is
|
|
90
|
+
SomMark is an extensible language that processes content through a four-stage pipeline:
|
|
62
91
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
[h1]
|
|
92
|
+
1. **Lexing**: The engine scans the source and converts it into a stream of tokens.
|
|
93
|
+
2. **Parsing**: Tokens are organized into a hierarchical tree called an **AST** (Abstract Syntax Tree).
|
|
94
|
+
3. **Mapping**: This is the translation layer. You define how identifiers (like `[h1]`) look in the target language.
|
|
95
|
+
4. **Transpilation**: The engine walks the AST and uses the Mapper to generate the final string output.
|
|
66
96
|
|
|
67
|
-
|
|
68
|
-
[a = href: "https://sommark.org"]Visit Website[end]
|
|
69
|
-
[end]
|
|
97
|
+
The **Module System** enables a "Declare-then-Inject" pattern, allowing you to import mappers and create scalable projects with full recursive support.
|
|
70
98
|
|
|
71
|
-
|
|
72
|
-
[quote]
|
|
73
|
-
SomMark is simple and powerful.
|
|
74
|
-
[end]
|
|
99
|
+
---
|
|
75
100
|
|
|
76
|
-
|
|
101
|
+
## Installation
|
|
77
102
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
(age)->(number: 25)
|
|
83
|
-
(is_active_user)->(bool: true)
|
|
84
|
-
[end]
|
|
85
|
-
[end]
|
|
103
|
+
Install the SomMark CLI globally:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
npm install -g sommark
|
|
86
107
|
```
|
|
87
108
|
|
|
88
|
-
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Usage in Node.js
|
|
89
112
|
|
|
90
113
|
```javascript
|
|
91
114
|
import SomMark from "sommark";
|
|
92
115
|
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
116
|
+
const sm = new SomMark({
|
|
117
|
+
src: "[h1]Hello World[end]",
|
|
118
|
+
format: "html"
|
|
96
119
|
});
|
|
97
120
|
|
|
98
|
-
|
|
121
|
+
const output = await sm.transpile();
|
|
122
|
+
// <h1>Hello World</h1>
|
|
99
123
|
```
|
|
100
124
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
Read our detailed guides in the `docs/` folder:
|
|
104
|
-
|
|
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.
|
|
125
|
+
---
|
|
112
126
|
|
|
113
|
-
|
|
127
|
+
## Documentation
|
|
114
128
|
|
|
115
|
-
|
|
116
|
-
High-quality syntax highlighting and diagnostics are provided via **LSP Semantic Tokens**. This ensures perfect coloring in any editor that supports the Language Server Protocol (e.g., VS Code, Neovim, CoC).
|
|
129
|
+
Read the full guides in the `docs/` folder:
|
|
117
130
|
|
|
118
|
-
|
|
131
|
+
* **[Syntax Guide](docs/syntax/syntax.md)**: Rules for writing Blocks, At-Blocks, and Inlines.
|
|
132
|
+
* **[Core Logic](docs/core/core.md)**: Deep dive into the engine architecture.
|
|
133
|
+
* **[Mapper API](docs/core/mapper.md)**: How to create your own translation layers.
|
|
134
|
+
* **[Module System](docs/core/module-system.md)**: Managing multi-file projects.
|
package/assets/logo.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"letter": {
|
|
3
|
+
"font": "jaro",
|
|
4
|
+
"color": "#FFFFFF",
|
|
5
|
+
"stroke-color": "#110B52",
|
|
6
|
+
"stroke-transparent": "13%"
|
|
7
|
+
},
|
|
8
|
+
"background": {
|
|
9
|
+
"colors": {
|
|
10
|
+
"color-1": {
|
|
11
|
+
"color": "#F80753",
|
|
12
|
+
"gradient-stop-position": "0%",
|
|
13
|
+
"transparent": "100%"
|
|
14
|
+
},
|
|
15
|
+
"color-2": {
|
|
16
|
+
"color": "#920431",
|
|
17
|
+
"gradient-stop-position": "100%",
|
|
18
|
+
"transparent": "100%"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"arrow": {
|
|
23
|
+
"font": "Karantina",
|
|
24
|
+
"color": "#FFFFFF",
|
|
25
|
+
"stroke-color": "#585394",
|
|
26
|
+
"stroke-transparent": "26%"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<svg width="60" height="66" viewBox="0 0 60 66" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<rect y="1" width="60" height="60" rx="5" fill="url(#paint0_linear_103_13)"/>
|
|
3
|
+
<mask id="path-2-outside-1_103_13" maskUnits="userSpaceOnUse" x="8" y="15" width="17" height="34" fill="black">
|
|
4
|
+
<rect fill="white" x="8" y="15" width="17" height="34"/>
|
|
5
|
+
<path d="M9.76 48C9.36 48 9.16 47.8 9.16 47.4V42.888C9.16 42.68 9.168 42.512 9.184 42.384C9.216 42.256 9.312 42.152 9.472 42.072L15.76 39.192V34.92L9.568 31.08C9.296 30.92 9.16 30.68 9.16 30.36V21.552C9.16 21.296 9.176 21.112 9.208 21C9.24 20.872 9.36 20.736 9.568 20.592L15.88 16.32C16.04 16.224 16.184 16.152 16.312 16.104C16.456 16.04 16.632 16.008 16.84 16.008H23.32C23.72 16.008 23.92 16.208 23.92 16.608V20.688C23.92 21.04 23.8 21.28 23.56 21.408L17.272 24V28.44L23.56 32.04C23.8 32.152 23.92 32.408 23.92 32.808V43.248C23.92 43.376 23.896 43.512 23.848 43.656C23.816 43.8 23.736 43.904 23.608 43.968L16.072 47.712C15.976 47.76 15.856 47.824 15.712 47.904C15.584 47.968 15.456 48 15.328 48H9.76Z"/>
|
|
6
|
+
</mask>
|
|
7
|
+
<path d="M9.76 48C9.36 48 9.16 47.8 9.16 47.4V42.888C9.16 42.68 9.168 42.512 9.184 42.384C9.216 42.256 9.312 42.152 9.472 42.072L15.76 39.192V34.92L9.568 31.08C9.296 30.92 9.16 30.68 9.16 30.36V21.552C9.16 21.296 9.176 21.112 9.208 21C9.24 20.872 9.36 20.736 9.568 20.592L15.88 16.32C16.04 16.224 16.184 16.152 16.312 16.104C16.456 16.04 16.632 16.008 16.84 16.008H23.32C23.72 16.008 23.92 16.208 23.92 16.608V20.688C23.92 21.04 23.8 21.28 23.56 21.408L17.272 24V28.44L23.56 32.04C23.8 32.152 23.92 32.408 23.92 32.808V43.248C23.92 43.376 23.896 43.512 23.848 43.656C23.816 43.8 23.736 43.904 23.608 43.968L16.072 47.712C15.976 47.76 15.856 47.824 15.712 47.904C15.584 47.968 15.456 48 15.328 48H9.76Z" fill="#F5F5F5"/>
|
|
8
|
+
<path d="M9.184 42.384L8.21386 42.1415L8.19921 42.2L8.19172 42.26L9.184 42.384ZM9.472 42.072L9.05558 41.1628L9.04006 41.1699L9.02479 41.1776L9.472 42.072ZM15.76 39.192L16.1764 40.1012L16.76 39.8339V39.192H15.76ZM15.76 34.92H16.76V34.3635L16.287 34.0702L15.76 34.92ZM9.568 31.08L10.095 30.2302L10.0851 30.224L10.075 30.2181L9.568 31.08ZM9.208 21L10.1695 21.2747L10.1741 21.2587L10.1781 21.2425L9.208 21ZM9.568 20.592L9.00747 19.7638L8.99879 19.7698L9.568 20.592ZM15.88 16.32L15.3655 15.4625L15.3421 15.4765L15.3195 15.4918L15.88 16.32ZM16.312 16.104L16.6631 17.0403L16.691 17.0299L16.7181 17.0178L16.312 16.104ZM23.56 21.408L23.9411 22.3325L23.9869 22.3137L24.0306 22.2904L23.56 21.408ZM17.272 24L16.8909 23.0755L16.272 23.3306V24H17.272ZM17.272 28.44H16.272V29.0198L16.7751 29.3078L17.272 28.44ZM23.56 32.04L23.0631 32.9078L23.0993 32.9286L23.1371 32.9462L23.56 32.04ZM23.848 43.656L22.8993 43.3398L22.883 43.3887L22.8718 43.4391L23.848 43.656ZM23.608 43.968L24.0529 44.8636L24.0552 44.8624L23.608 43.968ZM16.072 47.712L15.6271 46.8164L15.6248 46.8176L16.072 47.712ZM15.712 47.904L16.1592 48.7984L16.1786 48.7887L16.1976 48.7782L15.712 47.904ZM9.76 48V47C9.71414 47 9.86343 46.9892 10.0171 47.1429C10.1708 47.2966 10.16 47.4459 10.16 47.4H9.16H8.16C8.16 47.7541 8.24921 48.2034 8.60289 48.5571C8.95657 48.9108 9.40586 49 9.76 49V48ZM9.16 47.4H10.16V42.888H9.16H8.16V47.4H9.16ZM9.16 42.888H10.16C10.16 42.6997 10.1676 42.5778 10.1763 42.508L9.184 42.384L8.19172 42.26C8.16844 42.4462 8.16 42.6603 8.16 42.888H9.16ZM9.184 42.384L10.1541 42.6265C10.1265 42.737 10.072 42.8263 10.0148 42.8883C9.96234 42.9451 9.92001 42.966 9.91921 42.9664L9.472 42.072L9.02479 41.1776C8.70151 41.3392 8.33947 41.639 8.21386 42.1415L9.184 42.384ZM9.472 42.072L9.88842 42.9812L16.1764 40.1012L15.76 39.192L15.3436 38.2828L9.05558 41.1628L9.472 42.072ZM15.76 39.192H16.76V34.92H15.76H14.76V39.192H15.76ZM15.76 34.92L16.287 34.0702L10.095 30.2302L9.568 31.08L9.04097 31.9298L15.233 35.7698L15.76 34.92ZM9.568 31.08L10.075 30.2181C10.0699 30.2151 10.0768 30.2184 10.0896 30.2309C10.1029 30.244 10.1184 30.2629 10.132 30.287C10.162 30.3399 10.16 30.3751 10.16 30.36H9.16H8.16C8.16 31.0282 8.47828 31.5992 9.06098 31.9419L9.568 31.08ZM9.16 30.36H10.16V21.552H9.16H8.16V30.36H9.16ZM9.16 21.552H10.16C10.16 21.4428 10.1635 21.3632 10.1682 21.3086C10.1735 21.248 10.1782 21.2444 10.1695 21.2747L9.208 21L8.24648 20.7253C8.1732 20.9817 8.16 21.2868 8.16 21.552H9.16ZM9.208 21L10.1781 21.2425C10.1435 21.381 10.0801 21.4542 10.0718 21.4636C10.062 21.4748 10.0757 21.4568 10.1372 21.4142L9.568 20.592L8.99879 19.7698C8.75056 19.9417 8.36299 20.2569 8.23786 20.7575L9.208 21ZM9.568 20.592L10.1285 21.4202L16.4405 17.1482L15.88 16.32L15.3195 15.4918L9.0075 19.7638L9.568 20.592ZM15.88 16.32L16.3945 17.1775C16.5199 17.1022 16.6081 17.061 16.6631 17.0403L16.312 16.104L15.9609 15.1677C15.7599 15.243 15.5601 15.3458 15.3655 15.4625L15.88 16.32ZM16.312 16.104L16.7181 17.0178C16.7004 17.0257 16.7293 17.008 16.84 17.008V16.008V15.008C16.5347 15.008 16.2116 15.0543 15.9059 15.1902L16.312 16.104ZM16.84 16.008V17.008H23.32V16.008V15.008H16.84V16.008ZM23.32 16.008V17.008C23.3659 17.008 23.2166 17.0188 23.0629 16.8651C22.9092 16.7114 22.92 16.5621 22.92 16.608H23.92H24.92C24.92 16.2539 24.8308 15.8046 24.4771 15.4509C24.1234 15.0972 23.6741 15.008 23.32 15.008V16.008ZM23.92 16.608H22.92V20.688H23.92H24.92V16.608H23.92ZM23.92 20.688H22.92C22.92 20.7553 22.908 20.74 22.9356 20.6848C22.95 20.6559 22.972 20.623 23.0027 20.5917C23.0332 20.5605 23.0642 20.5391 23.0894 20.5256L23.56 21.408L24.0306 22.2904C24.6949 21.936 24.92 21.2824 24.92 20.688H23.92ZM23.56 21.408L23.1789 20.4835L16.8909 23.0755L17.272 24L17.6531 24.9245L23.9411 22.3325L23.56 21.408ZM17.272 24H16.272V28.44H17.272H18.272V24H17.272ZM17.272 28.44L16.7751 29.3078L23.0631 32.9078L23.56 32.04L24.0569 31.1722L17.7689 27.5722L17.272 28.44ZM23.56 32.04L23.1371 32.9462C23.0914 32.9248 23.0442 32.8927 23.0027 32.8503C22.9618 32.8085 22.9375 32.7681 22.9245 32.7404C22.902 32.6924 22.92 32.698 22.92 32.808H23.92H24.92C24.92 32.243 24.7403 31.4873 23.9829 31.1338L23.56 32.04ZM23.92 32.808H22.92V43.248H23.92H24.92V32.808H23.92ZM23.92 43.248H22.92C22.92 43.2507 22.9195 43.2793 22.8993 43.3398L23.848 43.656L24.7967 43.9722C24.8725 43.7447 24.92 43.5013 24.92 43.248H23.92ZM23.848 43.656L22.8718 43.4391C22.8836 43.3861 22.9117 43.3099 22.9714 43.2323C23.0316 43.1539 23.1021 43.1029 23.1608 43.0736L23.608 43.968L24.0552 44.8624C24.462 44.659 24.7292 44.3004 24.8242 43.8729L23.848 43.656ZM23.608 43.968L23.1631 43.0724L15.6271 46.8164L16.072 47.712L16.5169 48.6076L24.0529 44.8636L23.608 43.968ZM16.072 47.712L15.6248 46.8176C15.5109 46.8745 15.3771 46.9461 15.2264 47.0298L15.712 47.904L16.1976 48.7782C16.3349 48.7019 16.4411 48.6455 16.5192 48.6064L16.072 47.712ZM15.712 47.904L15.2648 47.0096C15.2606 47.0117 15.265 47.009 15.2775 47.0059C15.2903 47.0026 15.3078 47 15.328 47V48V49C15.6288 49 15.9089 48.9236 16.1592 48.7984L15.712 47.904ZM15.328 48V47H9.76V48V49H15.328V48Z" fill="#110B52" fill-opacity="0.13" mask="url(#path-2-outside-1_103_13)"/>
|
|
9
|
+
<mask id="path-4-outside-2_103_13" maskUnits="userSpaceOnUse" x="30" y="25" width="26" height="23" fill="black">
|
|
10
|
+
<rect fill="white" x="30" y="25" width="26" height="23"/>
|
|
11
|
+
<path d="M40.048 42.944L43.312 39.68H31.28V33.728H43.248L40.048 30.528L43.76 26.88L53.616 36.736L43.76 46.592L40.048 42.944Z"/>
|
|
12
|
+
</mask>
|
|
13
|
+
<path d="M40.048 42.944L43.312 39.68H31.28V33.728H43.248L40.048 30.528L43.76 26.88L53.616 36.736L43.76 46.592L40.048 42.944Z" fill="#F5F5F5"/>
|
|
14
|
+
<path d="M40.048 42.944L39.3409 42.2369L38.6276 42.9502L39.3471 43.6572L40.048 42.944ZM43.312 39.68L44.0191 40.3871L45.7262 38.68H43.312V39.68ZM31.28 39.68H30.28V40.68H31.28V39.68ZM31.28 33.728V32.728H30.28V33.728H31.28ZM43.248 33.728V34.728H45.6622L43.9551 33.0209L43.248 33.728ZM40.048 30.528L39.3471 29.8148L38.6276 30.5218L39.3409 31.2351L40.048 30.528ZM43.76 26.88L44.4671 26.1729L43.7661 25.4719L43.0591 26.1668L43.76 26.88ZM53.616 36.736L54.3231 37.4431L55.0302 36.736L54.3231 36.0289L53.616 36.736ZM43.76 46.592L43.0591 47.3052L43.7661 48.0001L44.4671 47.2991L43.76 46.592ZM40.048 42.944L40.7551 43.6511L44.0191 40.3871L43.312 39.68L42.6049 38.9729L39.3409 42.2369L40.048 42.944ZM43.312 39.68V38.68H31.28V39.68V40.68H43.312V39.68ZM31.28 39.68H32.28V33.728H31.28H30.28V39.68H31.28ZM31.28 33.728V34.728H43.248V33.728V32.728H31.28V33.728ZM43.248 33.728L43.9551 33.0209L40.7551 29.8209L40.048 30.528L39.3409 31.2351L42.5409 34.4351L43.248 33.728ZM40.048 30.528L40.7489 31.2412L44.4609 27.5932L43.76 26.88L43.0591 26.1668L39.3471 29.8148L40.048 30.528ZM43.76 26.88L43.0529 27.5871L52.9089 37.4431L53.616 36.736L54.3231 36.0289L44.4671 26.1729L43.76 26.88ZM53.616 36.736L52.9089 36.0289L43.0529 45.8849L43.76 46.592L44.4671 47.2991L54.3231 37.4431L53.616 36.736ZM43.76 46.592L44.4609 45.8788L40.7489 42.2308L40.048 42.944L39.3471 43.6572L43.0591 47.3052L43.76 46.592Z" fill="#585394" fill-opacity="0.26" mask="url(#path-4-outside-2_103_13)"/>
|
|
15
|
+
<defs>
|
|
16
|
+
<linearGradient id="paint0_linear_103_13" x1="30" y1="1" x2="30" y2="61" gradientUnits="userSpaceOnUse">
|
|
17
|
+
<stop stop-color="#F80753"/>
|
|
18
|
+
<stop offset="1" stop-color="#920431"/>
|
|
19
|
+
</linearGradient>
|
|
20
|
+
</defs>
|
|
21
|
+
</svg>
|
package/cli/cli.mjs
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* SomMark CLI Entry Point
|
|
4
|
+
* Reads your command-line arguments and runs the right tool.
|
|
5
|
+
*/
|
|
2
6
|
import { enableColor } from "../helpers/colorize.js";
|
|
7
|
+
|
|
3
8
|
import { getHelp } from "./commands/help.js";
|
|
4
9
|
import { printVersion, printHeader } from "./commands/version.js";
|
|
5
10
|
import { runBuild } from "./commands/build.js";
|
|
@@ -46,12 +51,14 @@ async function main() {
|
|
|
46
51
|
return;
|
|
47
52
|
}
|
|
48
53
|
|
|
49
|
-
// 4. Init
|
|
54
|
+
// 4. Init (Always Local)
|
|
50
55
|
if (command === "init") {
|
|
51
56
|
await runInit();
|
|
52
57
|
return;
|
|
53
58
|
}
|
|
54
59
|
|
|
60
|
+
|
|
61
|
+
|
|
55
62
|
// 5. Show
|
|
56
63
|
if (command === "show") {
|
|
57
64
|
await runShow(args[1]);
|
|
@@ -64,16 +71,6 @@ async function main() {
|
|
|
64
71
|
return;
|
|
65
72
|
}
|
|
66
73
|
|
|
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
74
|
|
|
78
75
|
// 6. Lex
|
|
79
76
|
if (command === "--lex") {
|
|
@@ -94,14 +91,9 @@ async function main() {
|
|
|
94
91
|
if (extensions[format]) {
|
|
95
92
|
// Build or Print
|
|
96
93
|
if (args[1] === "-p" || args[1] === "--print") {
|
|
97
|
-
// smark --format -p file
|
|
98
|
-
// args[0]=--format, args[1]=-p, args[2]=file
|
|
99
94
|
await printOutput(format, args[2]);
|
|
100
95
|
process.exit(0);
|
|
101
96
|
} else {
|
|
102
|
-
// smark --format file [options]
|
|
103
|
-
// args[0]=--format, args[1]=file, args[2]=-o, args[3]=output...
|
|
104
|
-
|
|
105
97
|
await runBuild(
|
|
106
98
|
command, // format_option (--markdown)
|
|
107
99
|
args[1], // sourcePath
|
package/cli/commands/build.js
CHANGED
|
@@ -5,6 +5,7 @@ import HTML from "../../mappers/languages/html.js";
|
|
|
5
5
|
import MARKDOWN from "../../mappers/languages/markdown.js";
|
|
6
6
|
import MDX from "../../mappers/languages/mdx.js";
|
|
7
7
|
import Json from "../../mappers/languages/json.js";
|
|
8
|
+
import XML from "../../mappers/languages/xml.js";
|
|
8
9
|
import { extensions } from "../constants.js";
|
|
9
10
|
import { isExist, readContent, createFile } from "../helpers/file.js";
|
|
10
11
|
import { loadConfig } from "../helpers/config.js";
|
|
@@ -13,11 +14,20 @@ import { transpile } from "../helpers/transpile.js";
|
|
|
13
14
|
// ========================================================================== //
|
|
14
15
|
// Generate Output File //
|
|
15
16
|
// ========================================================================== //
|
|
16
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Helper to generate and save the created code.
|
|
19
|
+
* @param {string} outputDir - Directory to save the file.
|
|
20
|
+
* @param {string} outputFile - Output filename (without extension).
|
|
21
|
+
* @param {string} format - Target format (html, markdown, etc.).
|
|
22
|
+
* @param {string} sourcePath - Path to the source .smark file.
|
|
23
|
+
* @param {Mapper|null} mappingFile - Custom mapped rules.
|
|
24
|
+
* @returns {Promise<string>} - The full path to the created file.
|
|
25
|
+
*/
|
|
26
|
+
async function generateOutput(outputDir, outputFile, format, sourcePath, mappingFile, config) {
|
|
17
27
|
let source_code = await readContent(sourcePath);
|
|
18
28
|
source_code = source_code.toString();
|
|
19
29
|
const absolutePath = path.resolve(process.cwd(), sourcePath);
|
|
20
|
-
const output = await transpile({ src: source_code, format, filename: absolutePath, mappingFile });
|
|
30
|
+
const output = await transpile({ src: source_code, format, filename: absolutePath, mappingFile, config });
|
|
21
31
|
const finalPath = path.join(outputDir, `${outputFile}.${extensions[format]}`);
|
|
22
32
|
await createFile(outputDir, `${outputFile}.${extensions[format]}`, output);
|
|
23
33
|
return finalPath;
|
|
@@ -26,6 +36,16 @@ async function generateOutput(outputDir, outputFile, format, sourcePath, mapping
|
|
|
26
36
|
// ========================================================================== //
|
|
27
37
|
// Run Build Process //
|
|
28
38
|
// ========================================================================== //
|
|
39
|
+
/**
|
|
40
|
+
* The starting point for the build process.
|
|
41
|
+
* Checks the file type, loads settings, and creates the output code.
|
|
42
|
+
*
|
|
43
|
+
* @param {string} format_option - The file format to output (like '--html').
|
|
44
|
+
* @param {string} sourcePath - The path to the file you want to build.
|
|
45
|
+
* @param {string} outputFlag - The '-o' flag.
|
|
46
|
+
* @param {string} outputFileArg - The custom filename.
|
|
47
|
+
* @param {string} outputDirArg - The custom directory.
|
|
48
|
+
*/
|
|
29
49
|
export async function runBuild(format_option, sourcePath, outputFlag, outputFileArg, outputDirArg) {
|
|
30
50
|
try {
|
|
31
51
|
const format = format_option.replaceAll("-", "") ?? "";
|
|
@@ -58,7 +78,7 @@ export async function runBuild(format_option, sourcePath, outputFlag, outputFile
|
|
|
58
78
|
let mappingFile = config.mappingFile;
|
|
59
79
|
|
|
60
80
|
if (!mappingFile) {
|
|
61
|
-
mappingFile = format === "html" ? HTML : format === "markdown" ? MARKDOWN : format === "mdx" ? MDX : format === "json" ? Json : null;
|
|
81
|
+
mappingFile = format === "html" ? HTML : format === "markdown" ? MARKDOWN : format === "mdx" ? MDX : format === "json" ? Json : format === "xml" ? XML : null;
|
|
62
82
|
}
|
|
63
83
|
|
|
64
84
|
// CLI Overrides
|
|
@@ -69,7 +89,7 @@ export async function runBuild(format_option, sourcePath, outputFlag, outputFile
|
|
|
69
89
|
}
|
|
70
90
|
}
|
|
71
91
|
|
|
72
|
-
const createdFilePath = await generateOutput(finalOutputDir, finalOutputFile, format, sourcePath, mappingFile);
|
|
92
|
+
const createdFilePath = await generateOutput(finalOutputDir, finalOutputFile, format, sourcePath, mappingFile, config);
|
|
73
93
|
const stats = await fs.stat(createdFilePath);
|
|
74
94
|
const date = new Date().toLocaleString();
|
|
75
95
|
|
package/cli/commands/color.js
CHANGED
|
@@ -1,36 +1,32 @@
|
|
|
1
|
-
import
|
|
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
|
-
}
|
|
1
|
+
import { formatMessage } from "../../core/errors.js";
|
|
14
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Checks if colors are turned on in your settings.
|
|
5
|
+
* @returns {Promise<boolean>}
|
|
6
|
+
*/
|
|
15
7
|
export async function isColorEnabled() {
|
|
16
|
-
|
|
17
|
-
const data = await fs.readFile(getColorFilePath(), "utf-8");
|
|
18
|
-
return JSON.parse(data).enabled === true;
|
|
19
|
-
} catch {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
8
|
+
return process.env.SOMMARK_COLOR === "true";
|
|
22
9
|
}
|
|
23
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Shows the user how to turn colors on or off.
|
|
13
|
+
* @param {string} action - 'on' or 'off'.
|
|
14
|
+
*/
|
|
24
15
|
export function runColor(action) {
|
|
25
16
|
if (action === "on") {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
17
|
+
console.log(formatMessage([
|
|
18
|
+
`{line}<$yellow:SomMark uses Environment Variables for colors:$>{line}`,
|
|
19
|
+
`<$blue:Set this in your current shell:$>`,
|
|
20
|
+
` <$cyan:export SOMMARK_COLOR=true$>{line}`,
|
|
21
|
+
`<$blue:Add it to your .bashrc or .zshrc for permanent effect.$>{line}`
|
|
22
|
+
].join("")));
|
|
29
23
|
} else if (action === "off") {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
console.log(formatMessage([
|
|
25
|
+
`{line}<$yellow:To disable colors, run:$>{line}`,
|
|
26
|
+
` <$cyan:export SOMMARK_COLOR=false$>{line}`,
|
|
27
|
+
`<$blue:(Or remove the SOMMARK_COLOR variable from your shell config)$>{line}`
|
|
28
|
+
].join("")));
|
|
33
29
|
} else {
|
|
34
|
-
console.log(
|
|
30
|
+
console.log(formatMessage(`Usage: <$blue:sommark color on|off$>`));
|
|
35
31
|
}
|
|
36
32
|
}
|
package/cli/commands/help.js
CHANGED
|
@@ -5,6 +5,11 @@ import { options } from "../constants.js";
|
|
|
5
5
|
// Help Command //
|
|
6
6
|
// ========================================================================== //
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Displays the CLI help message.
|
|
10
|
+
* @param {boolean} [unknown_option=true] - Whether to show the "Unrecognized option" prefix if an invalid flag is passed.
|
|
11
|
+
* @returns {string} - The formatted help message.
|
|
12
|
+
*/
|
|
8
13
|
export function getHelp(unknown_option = true) {
|
|
9
14
|
const msg = [
|
|
10
15
|
`${unknown_option && process.argv[2] ? `<$red:Unrecognized option$> <$blue: '${process.argv[2]}'$>` : ""}`,
|
|
@@ -13,32 +18,27 @@ export function getHelp(unknown_option = true) {
|
|
|
13
18
|
"{N}{N}<$yellow:Global Options:$>",
|
|
14
19
|
"{N} <$green:-h, --help$> <$cyan: Show help message$>",
|
|
15
20
|
"{N} <$green:-v, --version$> <$cyan: Show version information$>",
|
|
16
|
-
"{N} <$green:init$> <$cyan: Initialize
|
|
21
|
+
"{N} <$green:init$> <$cyan: Initialize local SomMark configuration file (smark.config.js)$>",
|
|
17
22
|
"{N} <$green:show config$> <$cyan: Display the absolute paths to the active SomMark configuration files$>",
|
|
18
|
-
"{N} <$green:color on|off$> <$cyan:
|
|
19
|
-
"{N} <$green:list plugins$> <$cyan: List all enabled plugins with author and description$>",
|
|
20
|
-
"{N} <$green:list -i plugins$> <$cyan: List only internal (built-in) plugins$>",
|
|
21
|
-
"{N} <$green:list -e plugins$> <$cyan: List only external (user-defined) plugins$>",
|
|
22
|
-
"{N} <$green:list pipeline$> <$cyan: Show the execution order of all active plugin phases$>",
|
|
23
|
+
"{N} <$green:color on|off$> <$cyan: Help on enabling colors via Environment Variables$>",
|
|
23
24
|
|
|
24
25
|
"{N}{N}<$yellow:Transpilation Options:$>",
|
|
25
26
|
"{N}<$yellow:Usage:$> <$blue:sommark [option] [targetFile] [option] [outputFile] [outputDir]$>",
|
|
26
27
|
"{N} <$green:--html$> <$cyan: Transpile to HTML$>",
|
|
27
28
|
"{N} <$green:--markdown$> <$cyan: Transpile to Markdown$>",
|
|
28
29
|
"{N} <$green:--mdx$> <$cyan: Transpile to MDX$>",
|
|
29
|
-
"{N} <$green:--json$> <$cyan: Transpile to
|
|
30
|
+
"{N} <$green:--json$> <$cyan: Transpile to JSON$>",
|
|
30
31
|
"{N} <$green:--text$> <$cyan: Transpile to plain text$>",
|
|
31
32
|
"{N} <$green:--lex$> <$cyan: Print lexer tokens to console$>",
|
|
32
33
|
"{N} <$green:--parse$> <$cyan: Print parser AST to console$>",
|
|
33
34
|
|
|
34
|
-
"{N}{N}<$yellow:Output
|
|
35
|
+
"{N}{N}<$yellow:Output & Config Overrides:$>",
|
|
35
36
|
"{N} <$green:-p, --print$> <$cyan: Print output to console (stdout)$>",
|
|
36
37
|
"{N} <$green:-o$> <$cyan: Specify output filename (and optionally directory)$>",
|
|
37
38
|
|
|
38
39
|
"{N}{N}<$yellow:Examples:$>",
|
|
39
40
|
"{N} <$magenta:1. Basic usage:$> <$blue:sommark --html input.smark$>",
|
|
40
|
-
"{N} <$magenta:2.
|
|
41
|
-
"{N} <$magenta:3. Custom output:$> <$blue:sommark --html input.smark -o myOutput ./dist/$>"
|
|
41
|
+
"{N} <$magenta:2. Custom output:$> <$blue:sommark --html input.smark -o myOutput ./dist/$>"
|
|
42
42
|
].join("");
|
|
43
43
|
const help_msg = formatMessage(msg);
|
|
44
44
|
|
package/cli/commands/init.js
CHANGED
|
@@ -1,60 +1,37 @@
|
|
|
1
|
-
import fs from "node:fs/promises";
|
|
2
1
|
import path from "node:path";
|
|
3
|
-
import os from "node:os";
|
|
4
2
|
import { cliError, formatMessage } from "../../core/errors.js";
|
|
3
|
+
import { isExist, createFile } from "../helpers/file.js";
|
|
5
4
|
|
|
6
5
|
// ========================================================================== //
|
|
7
6
|
// Init Command //
|
|
8
7
|
// ========================================================================== //
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return path.join(process.env.APPDATA || path.join(homeDir, "AppData", "Roaming"), "sommark");
|
|
14
|
-
} else if (process.platform === "darwin") {
|
|
15
|
-
return path.join(homeDir, "Library", "Application Support", "sommark");
|
|
16
|
-
} else {
|
|
17
|
-
return path.join(process.env.XDG_CONFIG_HOME || path.join(homeDir, ".config"), "sommark");
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Initializes a new SomMark configuration file (smark.config.js) in the current directory.
|
|
11
|
+
*/
|
|
21
12
|
export async function runInit() {
|
|
22
13
|
try {
|
|
23
|
-
const configDir =
|
|
14
|
+
const configDir = process.cwd();
|
|
24
15
|
const configFilePath = path.join(configDir, "smark.config.js");
|
|
25
16
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
//
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
outputDir: "",
|
|
38
|
-
outputFile: "output",
|
|
39
|
-
mappingFile: "",
|
|
40
|
-
plugins: [],
|
|
41
|
-
priority: [],
|
|
17
|
+
const defaultConfigContent = `/**
|
|
18
|
+
* SomMark Configuration File
|
|
19
|
+
* Generated by 'smark init'
|
|
20
|
+
*/
|
|
21
|
+
export default {
|
|
22
|
+
format: "html", // Target output format (html, markdown, mdx, json, xml)
|
|
23
|
+
removeComments: true, // Strip SomMark comments from the final output
|
|
24
|
+
customProps: [], // Whitelisted HTML attributes (prevents CSS hijacking)
|
|
25
|
+
placeholders: {}, // Global p{key} variables for content injection
|
|
26
|
+
outputDir: "./", // Where to save the transpiled files
|
|
27
|
+
outputFile: "output", // Default output filename
|
|
42
28
|
};
|
|
43
29
|
`;
|
|
44
30
|
|
|
45
|
-
|
|
46
|
-
// Check if config file already exists
|
|
47
|
-
// ======================================================
|
|
48
|
-
|
|
49
|
-
try {
|
|
50
|
-
await fs.access(configFilePath);
|
|
31
|
+
if (await isExist(configFilePath)) {
|
|
51
32
|
console.log(formatMessage(`<$yellow:Configuration already exists at:$> <$cyan:${configFilePath}$>`));
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Create default config file if it doesn't exist
|
|
55
|
-
// ======================================================
|
|
56
|
-
|
|
57
|
-
await fs.writeFile(configFilePath, defaultConfigContent, "utf-8");
|
|
33
|
+
} else {
|
|
34
|
+
await createFile(configDir, "smark.config.js", defaultConfigContent);
|
|
58
35
|
console.log(formatMessage(`<$green:Initialized SomMark configuration at:$> <$cyan:${configFilePath}$>`));
|
|
59
36
|
}
|
|
60
37
|
} catch (error) {
|