sommark 1.2.0 → 2.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/CHANGELOG.md +19 -60
- package/README.md +224 -89
- package/cli/cli.mjs +52 -169
- package/cli/commands/build.js +91 -0
- package/cli/commands/help.js +43 -0
- package/cli/commands/print.js +18 -0
- package/cli/commands/version.js +24 -0
- package/cli/constants.js +12 -0
- package/cli/helpers/config.js +43 -0
- package/cli/helpers/file.js +39 -0
- package/cli/helpers/transpile.js +55 -0
- package/core/{validator.js → errors.js} +14 -9
- package/core/formats.js +8 -0
- package/core/labels.js +24 -0
- package/core/lexer.js +474 -171
- package/core/parser.js +564 -233
- package/core/tokenTypes.js +3 -1
- package/core/transpiler.js +156 -62
- package/debug.js +11 -0
- package/formatter/mark.js +48 -18
- package/formatter/tag.js +54 -26
- package/grammar.ebnf +67 -24
- package/helpers/loadCss.js +46 -0
- package/helpers/loadHighlightStyle.js +28 -0
- package/index.js +25 -35
- package/lib/highlight.js +118 -118
- package/mappers/languages/html.js +80 -0
- package/mappers/languages/markdown.js +88 -0
- package/mappers/languages/mdx.js +5 -0
- package/mappers/mapper.js +171 -63
- package/package.json +3 -3
- package/core/ids.js +0 -2
- package/core/names.js +0 -13
- package/helpers/loadStyle.js +0 -25
- package/mappers/default_mode/smark.html.js +0 -78
- package/mappers/default_mode/smark.md.js +0 -72
- package/mappers/default_mode/smark.mdx.js +0 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,66 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
4
|
-
- Initial release
|
|
5
|
-
- Supports HTML, MD, MDX output
|
|
6
|
-
- CLI ready
|
|
7
|
-
- Lightweight 61 KB package
|
|
3
|
+
## v2.0.0 (2026-02-01)
|
|
8
4
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
### Features
|
|
12
|
-
|
|
13
|
-
- **Highlight.js Integration**:
|
|
14
|
-
- Added support for highlight.js themes.
|
|
15
|
-
- Added `codeThemes` and `selectedTheme` to Mapper configuration.
|
|
16
|
-
- Default theme for HTML output is now `atom-one-dark`.
|
|
17
|
-
- Added `helpers/loadStyle.js` to dynamically load theme CSS (isomorphic: supports both Node.js via `fs` and browser via `fetch`).
|
|
18
|
-
- Automatically injects selected theme CSS into HTML output when code blocks are present.
|
|
19
|
-
|
|
20
|
-
- **Mappers**:
|
|
21
|
-
- Added `includesId(id)` helper method to `Mapper` class for checking output mapping existence.
|
|
22
|
-
|
|
23
|
-
### Bug Fixes
|
|
24
|
-
|
|
25
|
-
- **Core/Parser**: Fixed a critical issue where global state variables (`block_stack`, `line`, etc.) were not reset between parse calls, causing errors on subsequent runs.
|
|
26
|
-
- **Core/Transpiler**: Removed leftover debug `console.log` calls.
|
|
27
|
-
- **Mappers/Markdown**: Fixed `Heading` block ignoring inner content (text/comments) in MD/MDX output. Now appends nested content after the heading.
|
|
28
|
-
- **Security**: Refactored HTML escaping architecture.
|
|
29
|
-
- **Transpiler**: `AtBlock` content is now **escaped by default** in the transpiler to prevent XSS.
|
|
30
|
-
- **Mapper**: Added `options` to `Mapper.create` (e.g., `{ escape: false }`) to allow specific blocks (like `Code`, `List`, `Table`) to opt-out of automatic escaping when they handle raw content safely or require it for parsing.
|
|
31
|
-
- **Parser**: Removed manual escaping from Parser to support the new transpiler-based architecture.
|
|
32
|
-
|
|
33
|
-
## 1.1.1 (2026-01-10)
|
|
34
|
-
|
|
35
|
-
### Bug Fixes
|
|
36
|
-
|
|
37
|
-
- **CLI**: Fixed a bug where passing a Mapper object in `smark.config.js` (Custom Mode) caused a crash. The CLI now correctly handles both file path strings and imported Mapper objects.
|
|
5
|
+
> [!WARNING]
|
|
6
|
+
> Old version is no longer supported.
|
|
38
7
|
|
|
8
|
+
### Breaking Changes
|
|
39
9
|
|
|
40
|
-
|
|
10
|
+
- **At-Blocks Terminator**: At-Blocks now require a semicolon (`;`) at the end of the argument list to support multi-line headers.
|
|
41
11
|
|
|
42
|
-
###
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
```yaml
|
|
58
|
-
[Block]Hello World[end]
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
---
|
|
62
|
-
|
|
63
|
-
### Code Improvements
|
|
64
|
-
|
|
65
|
-
* Removed unnecessary code
|
|
66
|
-
* Improved internal implementation
|
|
12
|
+
### Features
|
|
13
|
+
- **Flexible Inline Syntax**: Support for newlines and whitespace within inline syntax.
|
|
14
|
+
- **Flexible Block Definitions**: Support for multi-line headers in block definitions.
|
|
15
|
+
- **Named Arguments**: Blocks and At-Blocks now support Key-Value (named) arguments, allowing for order-independent and optional parameters.
|
|
16
|
+
- **Multi-Value Inlines**: Inline identifiers now support multiple comma-separated values (e.g., `(Text)->(gradient: red, blue)`).
|
|
17
|
+
- **Escape Character Support**: Added support for escaping special characters in arguments using a backslash (`\`).
|
|
18
|
+
- **Text Output Rendering**: Added functionality to render pure text output.
|
|
19
|
+
- **Mapper Validation**: Mappers can now define validation rules (self-rules) that are enforced by the transpiler.
|
|
20
|
+
|
|
21
|
+
### Improvements
|
|
22
|
+
- **Lexer Refactor**: The lexer now treats commas (`,`) as distinct tokens, also colons (`:`) are now treated as distinct tokens..
|
|
23
|
+
- **Mapper Logic**: General improvements to mapper internal logic.
|
|
24
|
+
- **API References**: Improved documentation and API references.
|
|
25
|
+
- **Testing**: Updated tests for new syntax and added coverage for new features.
|
package/README.md
CHANGED
|
@@ -1,155 +1,290 @@
|
|
|
1
|
-
|
|
2
1
|
<img width="2000" height="491" alt="SomMark Cover" src="https://raw.githubusercontent.com/Adam-Elmi/SomMark/master/assets/smark_bg.png" />
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
<p align="center">
|
|
7
|
-
SomMark is a lightweight, custom documentation markup language designed to be simple, readable, and easy to process.
|
|
8
|
-
</p>
|
|
9
|
-
|
|
10
3
|
<p align="center">
|
|
11
|
-
|
|
12
|
-
·
|
|
13
|
-
<span>Docs (Coming Soon)</span>
|
|
14
|
-
·
|
|
15
|
-
<span>Community (Coming Soon)</span>
|
|
4
|
+
SomMark is a structural markup language designed for technical documentation. It focuses on explicit structure and flexibility.
|
|
16
5
|
</p>
|
|
17
6
|
|
|
18
|
-
|
|
19
7
|
<p align="center">
|
|
20
8
|
<img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" />
|
|
21
|
-
<img src="https://img.shields.io/
|
|
9
|
+
<img src="https://img.shields.io/npm/v/sommark?style=flat-square" />
|
|
22
10
|
<img src="https://img.shields.io/badge/type-markup%20language-purple?style=flat-square" />
|
|
23
11
|
<img src="https://img.shields.io/badge/html-supported-orange?style=flat-square" />
|
|
24
12
|
<img src="https://img.shields.io/badge/markdown-supported-lightyellow?style=flat-square" />
|
|
25
13
|
<img src="https://img.shields.io/badge/mdx-supported-lightblue?style=flat-square" />
|
|
26
|
-
|
|
27
14
|
</p>
|
|
28
15
|
|
|
29
|
-
|
|
16
|
+
# SomMark v2.0.0
|
|
30
17
|
|
|
31
|
-
|
|
18
|
+
> [!WARNING]
|
|
19
|
+
> Old version is no longer supported.
|
|
32
20
|
|
|
33
|
-
SomMark
|
|
21
|
+
SomMark provides a way to write structured content that can be converted into other formats like HTML or Markdown. It is different from standard Markdown because it uses explicit syntax for blocks and elements, which makes it easier to process and customize.
|
|
34
22
|
|
|
35
|
-
|
|
23
|
+
# Features
|
|
36
24
|
|
|
37
|
-
|
|
25
|
+
* **Explicit Syntax**: Every element has a clear start and end, which reduces parsing errors.
|
|
26
|
+
* **Customizable Mappers**: You can convert SomMark content into any format (HTML, Markdown, JSON, etc.) by using Mappers.
|
|
27
|
+
* **Validation**: You can define rules to check your content, such as limiting the number of arguments or requiring specific keys.
|
|
28
|
+
* **MDX Support**: SomMark can map to existing React components ("Only Ready Components").
|
|
29
|
+
> [!NOTE]
|
|
30
|
+
> SomMark does not parse raw JSX. It only maps to ready components.
|
|
38
31
|
|
|
39
|
-
|
|
32
|
+
# Syntax
|
|
40
33
|
|
|
41
|
-
SomMark
|
|
42
|
-
|
|
43
|
-
---
|
|
34
|
+
SomMark uses three main types of elements: Blocks, Inline Statements, and At-Blocks.
|
|
44
35
|
|
|
45
36
|
## 1. Block
|
|
46
37
|
|
|
47
|
-
A
|
|
48
|
-
It holds arguments and child content.
|
|
38
|
+
A Block is a container that holds content. It can contain text or other nested blocks.
|
|
49
39
|
|
|
40
|
+
**With Arguments**
|
|
41
|
+
You can pass data to a block using arguments. Arguments can have keys.
|
|
50
42
|
```ini
|
|
51
|
-
[
|
|
52
|
-
|
|
53
|
-
|
|
43
|
+
[Alert = urgent, title: Warning]
|
|
44
|
+
System maintenance in 10 minutes.
|
|
45
|
+
This block uses a flag (urgent) and a key-value pair (title).
|
|
54
46
|
[end]
|
|
55
47
|
```
|
|
48
|
+
> [!NOTE]
|
|
49
|
+
> The colon `:` separates keys and values.
|
|
50
|
+
> Keys are optional.
|
|
56
51
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
52
|
+
**Without Arguments**
|
|
53
|
+
```ini
|
|
54
|
+
[Note]
|
|
55
|
+
This is a simple block.
|
|
56
|
+
[end]
|
|
57
|
+
```
|
|
62
58
|
|
|
63
59
|
## 2. Inline Statement
|
|
64
60
|
|
|
65
|
-
|
|
61
|
+
Inline Statements are used to format specific parts of text.
|
|
66
62
|
|
|
63
|
+
**With Arguments**
|
|
67
64
|
```ini
|
|
68
|
-
|
|
69
|
-
This is the (text)->(color:red).
|
|
70
|
-
These words are (important)->(bold).
|
|
71
|
-
[end]
|
|
65
|
+
This text is (bold)->(bold) and this is (red)->(color: red).
|
|
72
66
|
```
|
|
67
|
+
> [!NOTE]
|
|
68
|
+
> Inline arguments are values only. Keys are not supported.
|
|
73
69
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
70
|
+
**Without Arguments**
|
|
71
|
+
```ini
|
|
72
|
+
(Click here)->(Button)
|
|
73
|
+
```
|
|
77
74
|
|
|
78
|
-
## 3. At
|
|
75
|
+
## 3. At-Block
|
|
79
76
|
|
|
80
|
-
|
|
81
|
-
**At Blocks** are used for complex structures like tables, lists, code blocks, and custom content.
|
|
77
|
+
At-Blocks are used for specific content like code snippets or tables. The content inside an At-Block is treated as plain text and cannot contain other SomMark elements.
|
|
82
78
|
|
|
79
|
+
**With Arguments**
|
|
83
80
|
```ini
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
- January, 1200, 400
|
|
87
|
-
- February, 1400, 600
|
|
88
|
-
- March, 2000, 800
|
|
81
|
+
@_Code_@: javascript;
|
|
82
|
+
console.log("This is raw code.");
|
|
89
83
|
@_end_@
|
|
84
|
+
```
|
|
85
|
+
> [!NOTE]
|
|
86
|
+
> You must use a semi-colon `;` to end the argument list.
|
|
90
87
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
88
|
+
**Without Arguments**
|
|
89
|
+
```ini
|
|
90
|
+
@_Raw_@
|
|
91
|
+
Raw content here.
|
|
95
92
|
@_end_@
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## General Rules
|
|
96
|
+
|
|
97
|
+
* **Identifiers**: Names can only contain letters and numbers.
|
|
98
|
+
* **Escape Character**: Use the backslash `\` to escape special characters (like colons or commas) inside arguments.
|
|
99
|
+
* **Colons**: inside Block and At-Block arguments, the colon (`:`) separates names from values.
|
|
100
|
+
* **Semi-Colons**: The semi-colon (`;`) is only used in At-Blocks to assert the end of the argument list.
|
|
101
|
+
* **Whitespace**: SomMark ignores extra spaces and newlines, so you can format your code however you like.
|
|
102
|
+
|
|
103
|
+
# Installation
|
|
104
|
+
|
|
105
|
+
To install the Command Line Interface (CLI) globally:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
npm install -g sommark
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
# Usage
|
|
112
|
+
|
|
113
|
+
## Using the CLI
|
|
114
|
+
|
|
115
|
+
You can convert files using the terminal.
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# Convert to HTML
|
|
119
|
+
sommark --html input.smark -o output
|
|
120
|
+
|
|
121
|
+
# Convert to Markdown
|
|
122
|
+
sommark --markdown input.smark -o output.md
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Using in Code
|
|
126
|
+
|
|
127
|
+
You can use SomMark in your JavaScript or Node.js projects.
|
|
128
|
+
|
|
129
|
+
```javascript
|
|
130
|
+
import SomMark from "sommark";
|
|
131
|
+
|
|
132
|
+
const source = `
|
|
133
|
+
[Block]
|
|
134
|
+
Hello World
|
|
96
135
|
[end]
|
|
136
|
+
`;
|
|
137
|
+
|
|
138
|
+
const smark = new SomMark({
|
|
139
|
+
src: source,
|
|
140
|
+
format: "html"
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
console.log(await smark.transpile());
|
|
97
144
|
```
|
|
98
145
|
|
|
99
|
-
|
|
146
|
+
# Documentation
|
|
100
147
|
|
|
101
|
-
|
|
148
|
+
Detailed guides and API references are available in the `docs/` directory:
|
|
102
149
|
|
|
103
|
-
|
|
150
|
+
* **[Syntax Guide](docs/syntax.md)**: Master SomMark syntax (Blocks, Inline, At-Blocks).
|
|
151
|
+
* **[Core API](docs/core.md)**: Programmatic usage of the library (`transpile`, `lex`, `parse`).
|
|
152
|
+
* **[Mapper API](docs/mapper.md)**: Guide for creating custom mappers and rules.
|
|
153
|
+
* **[CLI Reference](docs/cli.md)**: Command line options and configurations.
|
|
154
|
+
* **[API Quick Reference](docs/api.md)**: Fast lookup for all classes and functions.
|
|
104
155
|
|
|
105
|
-
SomMark has **two modes**:
|
|
106
156
|
|
|
107
|
-
### Default Mode
|
|
108
157
|
|
|
109
|
-
|
|
110
|
-
* Can be directly transpiled to HTML or Markdown
|
|
111
|
-
* Ideal for documentation
|
|
158
|
+
# Configuration (Only for CLI)
|
|
112
159
|
|
|
113
|
-
|
|
160
|
+
You can create a `smark.config.js` file to configure the CLI.
|
|
114
161
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
162
|
+
```javascript
|
|
163
|
+
/* smark.config.js */
|
|
164
|
+
import myMapper from "./my-mapper.js";
|
|
118
165
|
|
|
119
|
-
|
|
166
|
+
export default {
|
|
167
|
+
outputFile: "output", // Default output filename
|
|
168
|
+
outputDir: "./dist", // Where to save files
|
|
169
|
+
mappingFile: myMapper // Use a custom mapper by default
|
|
170
|
+
};
|
|
171
|
+
```
|
|
120
172
|
|
|
121
|
-
|
|
173
|
+
# Creating Custom Mappers
|
|
122
174
|
|
|
123
|
-
SomMark
|
|
175
|
+
Mappers tell SomMark how to convert your content. You can define rules, options, and how arguments are handled.
|
|
124
176
|
|
|
125
|
-
|
|
126
|
-
* Output is not fixed
|
|
127
|
-
* The same SomMark file can generate different results (HTML, MD, MDX, etc.)
|
|
177
|
+
## Basic Structure
|
|
128
178
|
|
|
129
|
-
|
|
179
|
+
```javascript
|
|
180
|
+
import { Mapper } from "sommark";
|
|
181
|
+
const myMapper = new Mapper();
|
|
182
|
+
const { tag } = myMapper;
|
|
130
183
|
|
|
131
|
-
|
|
184
|
+
// Define a Block
|
|
185
|
+
myMapper.register("Alert", ({ args, content }) => {
|
|
186
|
+
// Access arguments by index or name
|
|
187
|
+
const type = args[0] || args.type || "info";
|
|
188
|
+
|
|
189
|
+
// Use TagBuilder to create HTML elements safely
|
|
190
|
+
return myMapper.tag("div")
|
|
191
|
+
.attributes({ class: `alert ${type}` })
|
|
192
|
+
.body(content);
|
|
193
|
+
});
|
|
132
194
|
|
|
133
|
-
|
|
195
|
+
export default myMapper;
|
|
196
|
+
```
|
|
197
|
+
> [!WARNING]
|
|
198
|
+
> The `.body()` and `.selfClose()` methods return the final HTML string. You must treat them as the end of the builder chain. If you forget to call them, you will return a builder object instead of a string.
|
|
199
|
+
|
|
200
|
+
You also skip tag builder and use raw HTML.
|
|
201
|
+
|
|
202
|
+
```javascript
|
|
203
|
+
import { Mapper } from "sommark";
|
|
204
|
+
const myMapper = new Mapper();
|
|
205
|
+
|
|
206
|
+
myMapper.register("Alert", ({ args, content }) => {
|
|
207
|
+
// Access arguments by index or name
|
|
208
|
+
const type = args[0] || args.type || "info";
|
|
209
|
+
|
|
210
|
+
// Use raw HTML
|
|
211
|
+
return `<div class="alert ${type}">${content}</div>`;
|
|
212
|
+
});
|
|
213
|
+
```
|
|
134
214
|
|
|
135
|
-
|
|
215
|
+
## Mapping Multiple Identifiers
|
|
136
216
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
217
|
+
You can use an array of strings to map multiple names to the same output function.
|
|
218
|
+
|
|
219
|
+
```javascript
|
|
220
|
+
import { Mapper } from "sommark";
|
|
221
|
+
const myMapper = new Mapper();
|
|
222
|
+
const { tag } = myMapper;
|
|
223
|
+
|
|
224
|
+
// Both [code] and [Code] will use this mapper
|
|
225
|
+
myMapper.register(["code", "Code"], ({ content }) => {
|
|
226
|
+
return tag("pre").body(tag("code").body(content));
|
|
227
|
+
});
|
|
142
228
|
```
|
|
143
229
|
|
|
144
|
-
|
|
230
|
+
## Reusing Existing Mappers
|
|
145
231
|
|
|
146
|
-
|
|
232
|
+
You can borrow rules from default mappers to avoid rewriting them.
|
|
147
233
|
|
|
148
|
-
|
|
234
|
+
```javascript
|
|
235
|
+
import { Mapper, HTML } from "sommark";
|
|
236
|
+
const myMapper = new Mapper();
|
|
237
|
+
|
|
238
|
+
// Reuse the "Code" block from the default HTML mapper
|
|
239
|
+
const codeOutput = HTML.get("Code");
|
|
240
|
+
if (codeOutput) {
|
|
241
|
+
myMapper.register(codeOutput.id, codeOutput.render, codeOutput.options);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Add your own custom blocks...
|
|
245
|
+
myMapper.register("MyBlock", ({ content }) => {
|
|
246
|
+
return content;
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
export default myMapper;
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Using Rules (Validation)
|
|
253
|
+
|
|
254
|
+
You can force strict rules on your content. If a rule is broken, SomMark will stop and show an error.
|
|
255
|
+
|
|
256
|
+
```javascript
|
|
257
|
+
import { Mapper } from "sommark";
|
|
258
|
+
const myMapper = new Mapper();
|
|
259
|
+
const { tag } = myMapper;
|
|
260
|
+
|
|
261
|
+
myMapper.register("User", ({ args }) => {
|
|
262
|
+
return tag("div").body(`User: ${args[0]}`);
|
|
263
|
+
}, {
|
|
264
|
+
rules: {
|
|
265
|
+
args: {
|
|
266
|
+
min: 1, // Must have at least 1 argument
|
|
267
|
+
required: ["id"] // The "id" key is required
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
```
|
|
272
|
+
*Example input that passes:* `[User = Adam, id:123] ... [end]`
|
|
273
|
+
|
|
274
|
+
## Using Options
|
|
275
|
+
|
|
276
|
+
Options change how SomMark processes the content inside the block.
|
|
277
|
+
|
|
278
|
+
```javascript
|
|
279
|
+
import { Mapper } from "sommark";
|
|
280
|
+
const myMapper = new Mapper();
|
|
281
|
+
const { tag } = myMapper;
|
|
282
|
+
|
|
283
|
+
myMapper.register("Code", ({ content }) => {
|
|
284
|
+
return tag("pre").body(content);
|
|
285
|
+
});
|
|
286
|
+
```
|
|
149
287
|
|
|
150
|
-
|
|
288
|
+
# License
|
|
151
289
|
|
|
152
|
-
|
|
153
|
-
* Structured writing
|
|
154
|
-
* Tooling and transpilation
|
|
155
|
-
* Extensible content systems
|
|
290
|
+
MIT
|