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
|
@@ -1,48 +1,20 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import os from "node:os";
|
|
3
2
|
import fs from "node:fs/promises";
|
|
4
|
-
import { pathToFileURL
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
5
4
|
|
|
6
5
|
const CONFIG_FILE_NAME = "smark.config.js";
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
|
-
*
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
} else if (process.platform === "darwin") {
|
|
16
|
-
return path.join(homeDir, "Library", "Application Support", "sommark");
|
|
17
|
-
} else {
|
|
18
|
-
return path.join(process.env.XDG_CONFIG_HOME || path.join(homeDir, ".config"), "sommark");
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Recursively searches for smark.config.js up the directory tree starting from startDir.
|
|
24
|
-
*/
|
|
25
|
-
async function findConfig(startDir) {
|
|
26
|
-
let currentDir = startDir;
|
|
27
|
-
while (currentDir !== path.parse(currentDir).root) {
|
|
28
|
-
const configPath = path.join(currentDir, CONFIG_FILE_NAME);
|
|
29
|
-
try {
|
|
30
|
-
await fs.access(configPath);
|
|
31
|
-
return configPath;
|
|
32
|
-
} catch {
|
|
33
|
-
currentDir = path.dirname(currentDir);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Loads the configuration from a file.
|
|
8
|
+
* Loads a configuration object from a Javascript file.
|
|
9
|
+
* We add the current time to the file path. This makes Node.js read
|
|
10
|
+
* the file again instead of using an old copy from its memory.
|
|
11
|
+
*
|
|
12
|
+
* @param {string} configPath - The absolute path to the config file.
|
|
13
|
+
* @returns {Promise<Object|null>} - The configuration object or null on error.
|
|
41
14
|
*/
|
|
42
15
|
async function loadConfigFile(configPath) {
|
|
43
16
|
if (!configPath) return null;
|
|
44
17
|
try {
|
|
45
|
-
// Use a timestamp to bypass cache for dynamic updates in LSP
|
|
46
18
|
const configURL = `${pathToFileURL(configPath).href}?t=${Date.now()}`;
|
|
47
19
|
const loadedModule = await import(configURL);
|
|
48
20
|
return loadedModule.default || loadedModule;
|
|
@@ -52,48 +24,57 @@ async function loadConfigFile(configPath) {
|
|
|
52
24
|
}
|
|
53
25
|
|
|
54
26
|
/**
|
|
55
|
-
* Finds and loads the configuration
|
|
56
|
-
*
|
|
27
|
+
* Finds and loads the SomMark configuration file.
|
|
28
|
+
* It looks in the current folder or a specific path if provided.
|
|
29
|
+
*
|
|
30
|
+
* @param {string|null} targetPath - A specific file or folder to look in.
|
|
31
|
+
* @returns {Promise<Object>} - The final configuration merged with defaults.
|
|
57
32
|
*/
|
|
58
33
|
export async function findAndLoadConfig(targetPath) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (
|
|
64
|
-
// As a fallback, check the current working directory of the process
|
|
65
|
-
// This helps LSP find the project config when running in the project root
|
|
66
|
-
const localConfigPath = path.join(process.cwd(), CONFIG_FILE_NAME);
|
|
34
|
+
let startDir = process.cwd();
|
|
35
|
+
let configPath = null;
|
|
36
|
+
|
|
37
|
+
// 1. Check if targetPath is an explicit config file path
|
|
38
|
+
if (targetPath) {
|
|
67
39
|
try {
|
|
68
|
-
await fs.
|
|
69
|
-
|
|
40
|
+
const stats = await fs.stat(targetPath);
|
|
41
|
+
if (stats.isFile() && targetPath.endsWith(".js")) {
|
|
42
|
+
configPath = path.resolve(targetPath);
|
|
43
|
+
} else {
|
|
44
|
+
startDir = stats.isDirectory() ? targetPath : path.dirname(targetPath);
|
|
45
|
+
}
|
|
70
46
|
} catch {
|
|
71
|
-
//
|
|
47
|
+
// Path doesn't exist
|
|
72
48
|
}
|
|
73
49
|
}
|
|
74
50
|
|
|
51
|
+
// 2. Check the current folder
|
|
75
52
|
if (!configPath) {
|
|
76
|
-
const
|
|
53
|
+
const localConfig = path.join(startDir, CONFIG_FILE_NAME);
|
|
77
54
|
try {
|
|
78
|
-
await fs.access(
|
|
79
|
-
configPath =
|
|
55
|
+
await fs.access(localConfig);
|
|
56
|
+
configPath = localConfig;
|
|
80
57
|
} catch {
|
|
81
|
-
// No config found
|
|
58
|
+
// No local config found
|
|
82
59
|
}
|
|
83
60
|
}
|
|
84
|
-
|
|
61
|
+
|
|
85
62
|
const defaultConfig = {
|
|
86
63
|
outputFile: "output",
|
|
87
64
|
outputDir: startDir,
|
|
88
65
|
mappingFile: null,
|
|
89
|
-
|
|
90
|
-
priority: []
|
|
66
|
+
removeComments: true,
|
|
91
67
|
};
|
|
92
68
|
|
|
93
69
|
if (configPath) {
|
|
94
70
|
const loadedConfig = await loadConfigFile(configPath);
|
|
95
71
|
if (loadedConfig) {
|
|
96
|
-
|
|
72
|
+
const finalConfig = { ...defaultConfig, ...loadedConfig, resolvedConfigPath: configPath };
|
|
73
|
+
if (loadedConfig.outputDir) {
|
|
74
|
+
const configDir = path.dirname(configPath);
|
|
75
|
+
finalConfig.outputDir = path.resolve(configDir, loadedConfig.outputDir);
|
|
76
|
+
}
|
|
77
|
+
return finalConfig;
|
|
97
78
|
}
|
|
98
79
|
}
|
|
99
80
|
|
package/core/labels.js
CHANGED
|
@@ -1,27 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* These labels identify different parts of the code (like blocks or text)
|
|
3
|
+
* so the system knows how to handle them.
|
|
4
|
+
*/
|
|
1
5
|
export const BLOCK = "Block",
|
|
2
6
|
TEXT = "Text",
|
|
3
7
|
INLINE = "Inline",
|
|
4
8
|
ATBLOCK = "AtBlock",
|
|
5
9
|
COMMENT = "Comment",
|
|
6
10
|
IMPORT = "Import",
|
|
7
|
-
USE_MODULE = "$use-module"
|
|
8
|
-
|
|
11
|
+
USE_MODULE = "$use-module";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Names for symbols used to separate parts of the code (like commas and colons).
|
|
15
|
+
*/
|
|
16
|
+
export const SEMICOLON = "Semicolon",
|
|
9
17
|
BLOCKCOMMA = "Block-comma",
|
|
10
18
|
ATBLOCKCOMMA = "Atblock-comma",
|
|
11
19
|
INLINECOMMA = "Inline-comma",
|
|
12
20
|
BLOCKCOLON = "Block-colon",
|
|
13
21
|
ATBLOCKCOLON = "Atblock-colon",
|
|
14
|
-
INLINECOLON = "Inline-colon"
|
|
15
|
-
|
|
22
|
+
INLINECOLON = "Inline-colon";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* These names are used in error messages to tell you exactly which part
|
|
26
|
+
* of your code has a mistake.
|
|
27
|
+
*/
|
|
28
|
+
export const block_id = "Block Identifier",
|
|
16
29
|
block_value = "Block Value",
|
|
17
|
-
|
|
30
|
+
block_key = "Block Key",
|
|
18
31
|
block_end = "Block end",
|
|
19
32
|
inline_id = "Inline Identifier",
|
|
20
|
-
|
|
21
|
-
inline_id_2 = "Inline Identifier 2",
|
|
33
|
+
inline_text = "Inline Text",
|
|
22
34
|
at_id = "At Identifier",
|
|
23
35
|
at_value = "At Value",
|
|
24
|
-
|
|
36
|
+
atblock_key = "AtBlock Key",
|
|
25
37
|
at_end = "Atblock End",
|
|
26
|
-
|
|
38
|
+
/** Reserved keyword for closing blocks */
|
|
27
39
|
end_keyword = "end";
|