Skip to content

Commit

Permalink
feat(compile): update sass and json compiler
Browse files Browse the repository at this point in the history
  • Loading branch information
lc-soft committed Aug 21, 2023
1 parent 5f2d5e4 commit faf742e
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 40 deletions.
2 changes: 1 addition & 1 deletion lib/compiler/css.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default {
.split("\\n")
.join("\\\n");
return [
`const char *css_str_${identCount++} = "\\`,
`static const char *css_str_${identCount++} = "\\`,
`${cssCode.substring(1, cssCode.length - 1)}\\`,
'";\n',
].join("\n");
Expand Down
11 changes: 9 additions & 2 deletions lib/compiler/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,24 @@ function compileFile(filePath, options) {

let type = options.type;
if (type === "auto") {
type = Object.keys(compilers).find((c) => compilers[c].test.test(filePath));
type = Object.keys(compilers).find((c) => {
const { test } = compilers[c];
if (test instanceof Function) {
return test(filePath);
}
return test.test(filePath);
});
}

const compiler = compilers[type];
if (!compiler) {
return;
}

console.log(`[lcui.${type}] compile ${filePath}`);
const content = fs.readFileSync(filePath, { encoding: "utf-8" });
const result = compiler.compile(content, { filePath });
fs.writeFileSync(`${filePath}.c`, result, { encoding: "utf-8" });
fs.writeFileSync(`${filePath}.h`, result, { encoding: "utf-8" });
}

export function compile(file, options) {
Expand Down
71 changes: 38 additions & 33 deletions lib/compiler/json.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ function toIdent(str) {
return str.replace(/[^a-zA-Z0-9]/g, "_");
}

function compile(jsonData, { filePath }) {
function compile(jsonData, { filePath, indent = 8 }) {
let count = 0;
const { name: fileName, base: fileBase } = path.parse(filePath);
const identPrefix = toIdent(fileName);
const globalLines = [];
const initLines = [];
const resourceLines = [];
const refs = [];
const uiLines = [];
const indentStr = " ";
const templateLines = [];
const indentStr = " ".repeat(indent);

function translateNode(name, data) {
let ident;
Expand Down Expand Up @@ -52,33 +52,30 @@ function compile(jsonData, { filePath }) {
break;
case "resource":
if (attrs.type.startsWith("application/font")) {
initLines.push(
resourceLines.push(
`pd_font_library_load_file(${JSON.stringify(attrs.src)});`
);
return;
}
if (["text/css", "text/scss", "text/sass"].includes(attrs.type)) {
let cssFilePath;
let cssText;
const options = { filePath };
let cssText = text;

if (attrs.src) {
cssFilePath = path.resolve(filePath, "..", attrs.src);
cssText = fs.readFileSync(cssFilePath, {
options.filePath = path.resolve(filePath, "..", attrs.src);
cssText = fs.readFileSync(options.filePath, {
encoding: "utf-8",
});
} else {
cssFilePath = filePath;
cssText = text;
}
const cssCode =
attrs.type === "text/css"
? css.compile(cssText)
: sass.compile(cssText);
ident = cssCode.substring("const char *".length).split(" ")[0];
? css.compile(cssText, options)
: sass.compile(cssText, options);
ident = cssCode.substring("static const char *".length).split(" ")[0];
globalLines.push(cssCode);
initLines.push(
resourceLines.push(
`ui_load_css_string(${ident}, ${JSON.stringify(
path.parse(cssFilePath).base
path.parse(options.filePath).base
)});`
);
}
Expand All @@ -96,12 +93,12 @@ function compile(jsonData, { filePath }) {
} else {
ident = `w[${count++}]`;
}
uiLines.push(
templateLines.push(
`${ident} = ui_create_widget(${type ? `"${type}"` : "NULL"});`
);
Object.keys(attrs).forEach((attrName) => {
if (attrName === "class") {
uiLines.push(
templateLines.push(
`ui_widget_add_class(${ident}, ${JSON.stringify(
attrs[attrName]
)});`
Expand All @@ -111,19 +108,24 @@ function compile(jsonData, { filePath }) {
if (attrName === "ref") {
return;
}
uiLines.push(
templateLines.push(
`ui_widget_set_attr(${ident}, "${attrName}", ${JSON.stringify(
attrs[attrName]
)});`
);
});
if (text) {
templateLines.push(
`ui_widget_set_text(${ident}, ${JSON.stringify(text)});`
);
}
break;
}
children
.map(([childName, childData]) => translateNode(childName, childData))
.forEach((childIdent) => {
if (ident && childIdent) {
uiLines.push(`ui_widget_append(${ident}, ${childIdent});`);
templateLines.push(`ui_widget_append(${ident}, ${childIdent});`);
}
});
return ident;
Expand All @@ -144,21 +146,24 @@ function compile(jsonData, { filePath }) {
: []),
...globalLines,
"",
`static void ${identPrefix}_create(ui_widget_t *${identPrefix}_parent, ${identPrefix}_refs_t *refs)`,
"{",
...[
`ui_widget_t *w[${count}];`,
"",
...uiLines,
`return ${identPrefix}_parent;`,
].map((line) => (line ? `${indentStr}${line}` : line)),
"}",
"",
`static void ${identPrefix}_install(void)`,
`static void ${identPrefix}_load_template(ui_widget_t *${identPrefix}_parent${
refs.length > 0 ? `, ${identPrefix}_refs_t *refs` : ""
})`,
"{",
...initLines.map((line) => (line ? `${indentStr}${line}` : line)),
...[`ui_widget_t *w[${count}];`, "", ...templateLines].map((line) =>
line ? `${indentStr}${line}` : line
),
"}",
"",
...(resourceLines.length > 0
? [
`static void ${identPrefix}_load_resources(void)`,
"{",
...resourceLines.map((line) => (line ? `${indentStr}${line}` : line)),
"}",
"",
]
: []),
].join("\n");
}

Expand Down
34 changes: 30 additions & 4 deletions lib/compiler/sass.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,35 @@
import sass from "sass";
import fs from "fs-extra";
import path from "path";
import * as sass from "sass";
import css from "./css.js";

export function compileSass(input, filePath) {
const { dir, ext } = path.parse(filePath);
return sass.compileString(input, {
importer: {
findFileUrl(url) {
const resolvedUrl = path.resolve(dir, url);
const parsedUrl = path.parse(resolvedUrl);
const result = [
resolvedUrl,
`${resolvedUrl}${ext}`,
path.join(parsedUrl.dir, `_${parsedUrl.base}`),
path.join(parsedUrl.dir, `_${parsedUrl.base}${ext}`),
path.join(resolvedUrl, `index${ext}`),
].find((item) => fs.existsSync(item) && fs.statSync(item).isFile());
return result ? new URL(`file://${result}`) : null;
},
},
});
}

export default {
test: /\.s[ac]ss$/,
compile(file) {
return css.compile(sass.compile(file));
test(filePath) {
const { ext, name } = path.parse(filePath);
return (ext === ".sass" || ext === ".scss") && !name.startsWith("_");
},
compile(input, options) {
const result = compileSass(input, options.filePath);
return css.compile(result.css);
},
};

0 comments on commit faf742e

Please sign in to comment.