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 CHANGED
@@ -1,66 +1,25 @@
1
1
  # Changelog
2
2
 
3
- ## 1.0.0 (2026-01-04)
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
- ## 1.1.0 (2026-01-08)
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
- ## 1.2.0 (2026-01-14)
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
- ### Bug Fixes
43
-
44
- * Fixed an issue where consecutive standalone blocks were not fully rendered when not separated by a blank line.
45
-
46
- ```ini
47
- [Block]
48
- This is a test.
49
- [end]
50
- [Block]
51
- This is another test.
52
- [end]
53
- ```
54
-
55
- * Added support for inline block content while keeping the original multiline syntax fully compatible.
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
- <span>Website (Coming Soon)</span>
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/badge/version-v1.0.0-blue?style=flat-square" />
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
- # SomMark v1
18
+ > [!WARNING]
19
+ > Old version is no longer supported.
32
20
 
33
- SomMark is a simple and extensible markup language designed for writing documentation and structured content. It is easy to read, easy to parse, and easy to convert into formats like HTML, Markdown, and MDX.
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
- SomMark is built around **clear syntax**, **explicit structure**, and a **mapping-based output system**.
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
- ## Core Syntax
32
+ # Syntax
40
33
 
41
- SomMark has **three main syntax types**.
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 **Block** is a container.
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
- [Block = arg1, arg2, arg3]
52
- This is the body.
53
- These texts are considered as children.
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
- * `Block` is the block name
58
- * Arguments are optional
59
- * Everything inside is treated as block content
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
- An **Inline Statement** is used inside text to apply formatting or behavior such as color, links, or styles.
61
+ Inline Statements are used to format specific parts of text.
66
62
 
63
+ **With Arguments**
67
64
  ```ini
68
- [Block]
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
- Inline statements modify specific parts of text without breaking the flow.
75
-
76
- ---
70
+ **Without Arguments**
71
+ ```ini
72
+ (Click here)->(Button)
73
+ ```
77
74
 
78
- ## 3. At Block
75
+ ## 3. At-Block
79
76
 
80
- Sometimes inline statements are not enough.
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
- [Block]
85
- @_table_@: month, revenue, expenses
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
- @_code_@: lua
92
- function add(a, b)
93
- return a + b
94
- end
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
- At Blocks give you full control over how structured data is handled.
146
+ # Documentation
100
147
 
101
- ---
148
+ Detailed guides and API references are available in the `docs/` directory:
102
149
 
103
- ## Modes
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
- * Comes with predefined identifiers such as `table`, `code`, `list`, and more
110
- * Can be directly transpiled to HTML or Markdown
111
- * Ideal for documentation
158
+ # Configuration (Only for CLI)
112
159
 
113
- ### Custom Mode
160
+ You can create a `smark.config.js` file to configure the CLI.
114
161
 
115
- * You define your own identifiers
116
- * Full control over behavior and output
117
- * Useful for custom formats or tools
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
- ## Mapping Concept
173
+ # Creating Custom Mappers
122
174
 
123
- SomMark uses a **mapping system**.
175
+ Mappers tell SomMark how to convert your content. You can define rules, options, and how arguments are handled.
124
176
 
125
- * You define how each block, inline statement, or at-block should be converted
126
- * Output is not fixed
127
- * The same SomMark file can generate different results (HTML, MD, MDX, etc.)
177
+ ## Basic Structure
128
178
 
129
- This makes SomMark highly extensible and future-proof.
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
- ## Escape Character
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
- To prevent SomMark from parsing syntax, use the escape character (`` ` ``):
215
+ ## Mapping Multiple Identifiers
136
216
 
137
- ```ini
138
- [Block]
139
- This is a text `[Hello]` not a block.
140
- Also this `(world)` is not inline syntax.
141
- [end]
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
- Escaped content is treated as plain text.
230
+ ## Reusing Existing Mappers
145
231
 
146
- ---
232
+ You can borrow rules from default mappers to avoid rewriting them.
147
233
 
148
- ## Purpose
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
- SomMark is designed for:
288
+ # License
151
289
 
152
- * Documentation
153
- * Structured writing
154
- * Tooling and transpilation
155
- * Extensible content systems
290
+ MIT