1use std::fs;
2
3use anyhow::Result;
4use heck::ToPascalCase as _;
5use toml::Table;
6
7pub fn write() -> Result<()> {
8 let langs_dir = crate::WORKSPACE_DIR.join("syntastica-js/langs");
9 let _ = fs::remove_dir_all(&langs_dir);
10 fs::create_dir_all(&langs_dir)?;
11 fs::write(
12 langs_dir.join("README.md"),
13 include_str!("./js_langs_readme.md"),
14 )?;
15
16 for lang in &crate::LANGUAGE_CONFIG.languages {
17 if !lang.wasm {
18 continue;
19 }
20 let lang_dir = langs_dir.join(&lang.name);
21 let src_dir = lang_dir.join("src");
22 fs::create_dir_all(&src_dir)?;
23 fs::write(lang_dir.join("LICENSE"), include_str!("../../../LICENSE"))?;
24
25 let lang_name = &lang.name;
26 let lang_name_pascal = &lang.name.to_pascal_case();
27
28 fs::write(
29 lang_dir.join("README.md"),
30 format!(
31 r###"# `syntastica-js-{lang_name}`
32
33{lang_name_pascal} language support for
34[`syntastica-js`](https://www.npmjs.com/package/@syntastica/core).
35"###
36 ),
37 )?;
38
39 fs::write(
40 lang_dir.join("Cargo.toml"),
41 format!(
42 r###"[package]
43name = "syntastica-js-{lang_name}"
44version.workspace = true
45authors.workspace = true
46documentation = "https://rubixdev.github.io/syntastica/syntastica_js/"
47edition.workspace = true
48license.workspace = true
49repository.workspace = true
50description = "{lang_name_pascal} language support for syntastica-js"
51
52[lib]
53crate-type = ["cdylib"]
54
55[dependencies]
56syntastica-macros = {{ workspace = true, features = ["js"] }}
57syntastica-queries.workspace = true
58
59tree-sitter.workspace = true
60
61[build-dependencies]
62syntastica-macros = {{ workspace = true, features = ["js"] }}
63
64cc.workspace = true
65tree-sitter-generate.workspace = true
66"###
67 ),
68 )?;
69
70 fs::write(
71 lang_dir.join("build.rs"),
72 format!(
73 r###"const EMSCRIPTEN_FLAGS: &[&str] = &[
74 "-sTOTAL_MEMORY=33554432",
75 "-sSIDE_MODULE=2",
76 "-sWASM=1",
77 "-sNODEJS_CATCH_EXIT=0",
78];
79
80fn main() -> Result<(), Box<dyn std::error::Error>> {{
81 if std::env::var("TARGET").is_ok_and(|s| s == "wasm32-unknown-emscripten") {{
82 for flag in EMSCRIPTEN_FLAGS {{
83 println!("cargo::rustc-link-arg={{flag}}");
84 }}
85
86 syntastica_macros::js_lang_build!("{lang_name}");
87 }}
88 Ok(())
89}}
90
91include!("../../../syntastica-parsers-git/build_helper.rs");
92"###
93 ),
94 )?;
95
96 let syntastica_version = toml::from_str::<Table>(
97 &fs::read_to_string(crate::WORKSPACE_DIR.join("Cargo.toml")).unwrap(),
98 )
99 .unwrap()["workspace"]["package"]["version"]
100 .as_str()
101 .unwrap()
102 .to_string();
103 fs::write(
104 lang_dir.join("package.json"),
105 format!(
106 r###"{{
107 "$schema": "https://raw.githubusercontent.com/SchemaStore/schemastore/master/src/schemas/json/package.json",
108 "name": "@syntastica/lang-{lang_name}",
109 "version": "{syntastica_version}",
110 "description": "{lang_name_pascal} language support for syntastica-js",
111 "keywords": ["tree-sitter", "highlight", "parsing", "syntax"],
112 "homepage": "https://github.com/RubixDev/syntastica/tree/main/syntastica-js#readme",
113 "bugs": "https://github.com/RubixDev/syntastica/issues",
114 "license": "MPL-2.0",
115 "author": "RubixDev",
116 "funding": {{
117 "url": "https://ko-fi.com/rubixdev",
118 "type": "ko-fi"
119 }},
120 "files": ["{lang_name}.wasm"],
121 "repository": {{
122 "type": "git",
123 "url": "git+https://github.com/RubixDev/syntastica.git",
124 "directory": "syntastica-js/langs/{lang_name}"
125 }},
126 "publishConfig": {{
127 "access": "public"
128 }},
129 "scripts": {{
130 "build": "env CFLAGS=-fPIC cargo build --profile release-wasm --target wasm32-unknown-emscripten",
131 "postbuild": "cp \"${{CARGO_TARGET_DIR:-../../../target}}/wasm32-unknown-emscripten/release-wasm/syntastica_js_{lang_name}.wasm\" {lang_name}.wasm"
132 }}
133}}
134"###
135 ),
136 )?;
137
138 fs::write(
139 src_dir.join("lib.rs"),
140 format!(
141 r###"#![no_std]
142#![warn(rust_2018_idioms)]
143
144use tree_sitter::Language;
145
146syntastica_macros::js_lang_info!();
147syntastica_macros::js_lang_lib!("{lang_name}");
148"###
149 ),
150 )?;
151 }
152
153 Ok(())
154}