Skip to content

Commit 41d2816

Browse files
committed
maint: add editor and prettier configs, unify js and css formatting
1 parent b6e3ee6 commit 41d2816

8 files changed

Lines changed: 209 additions & 176 deletions

File tree

.editorconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
root = true
2+
3+
# Unix-style newlines with a newline ending every file
4+
[*]
5+
end_of_line = lf
6+
insert_final_newline = true
7+
8+
# Matches multiple files with brace expansion notation
9+
# Set default charset
10+
[*.{js,py,json,css}]
11+
charset = utf-8
12+
indent_style = space
13+
indent_size = 4

.prettierrc.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"$schema": "https://json.schemastore.org/prettierrc",
3+
"semi": false,
4+
"tabWidth": 4,
5+
"singleQuote": false,
6+
"printWidth": 90,
7+
"trailingComma": "es5",
8+
"arrowParens": "always",
9+
"overrides": [
10+
{
11+
"files": ["*.qmd", "*.md"],
12+
"options": {
13+
"parser": "markdown"
14+
}
15+
}
16+
]
17+
}

packages/pyobsplot-js/main.js

Lines changed: 73 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,41 @@
22

33
/* jsdom rendering */
44

5-
import * as Plot from "@observablehq/plot";
6-
import * as d3 from "d3";
7-
import * as http from "node:http";
8-
import { JSDOM } from "jsdom";
9-
import { generate_plot } from "./plot.js";
5+
import * as Plot from "@observablehq/plot"
6+
import * as d3 from "d3"
7+
8+
import * as http from "node:http"
9+
import { JSDOM } from "jsdom"
10+
import { generate_plot } from "./plot.js"
1011

1112
// Create and initialize jsdom
12-
const jsdom = new JSDOM("");
13-
global.window = jsdom.window;
14-
global.document = jsdom.window.document;
15-
global.Event = jsdom.window.Event;
16-
global.Node = jsdom.window.Node;
17-
global.NodeList = jsdom.window.NodeList;
18-
global.HTMLCollection = jsdom.window.HTMLCollection;
13+
const jsdom = new JSDOM("")
14+
global.window = jsdom.window
15+
global.document = jsdom.window.document
16+
global.Event = jsdom.window.Event
17+
global.Node = jsdom.window.Node
18+
global.NodeList = jsdom.window.NodeList
19+
global.HTMLCollection = jsdom.window.HTMLCollection
1920
// Make Plot and d3 available in js()
20-
global.d3 = d3;
21-
global.Plot = Plot;
21+
global.d3 = d3
22+
global.Plot = Plot
2223

2324
// jsdom plot generator
2425
function jsdom_plot(request) {
25-
request = JSON.parse(request);
26-
let el = generate_plot(request["spec"], "jsdom");
26+
request = JSON.parse(request)
27+
let el = generate_plot(request["spec"], "jsdom")
2728

2829
// foreground color
29-
const bg = { light: "#FFFFFF", dark: "#000000", current: "transparent" };
30+
const bg = { light: "#FFFFFF", dark: "#000000", current: "transparent" }
3031
// background color
31-
const fg = { light: "#000000", dark: "#FFFFFF", current: "currentColor" };
32+
const fg = { light: "#000000", dark: "#FFFFFF", current: "currentColor" }
3233
// caption color
33-
const caption = { light: "#777777", dark: "#888888", current: "currentColor" };
34-
const theme = request["theme"];
34+
const caption = {
35+
light: "#777777",
36+
dark: "#888888",
37+
current: "currentColor",
38+
}
39+
const theme = request["theme"]
3540

3641
for (const svg of el.tagName.toLowerCase() === "svg"
3742
? [el]
@@ -40,93 +45,93 @@ function jsdom_plot(request) {
4045
"http://www.w3.org/2000/xmlns/",
4146
"xmlns",
4247
"http://www.w3.org/2000/svg"
43-
);
48+
)
4449
svg.setAttributeNS(
4550
"http://www.w3.org/2000/xmlns/",
4651
"xmlns:xlink",
4752
"http://www.w3.org/1999/xlink"
48-
);
53+
)
4954
// theming
50-
svg.style.color ||= fg[theme];
51-
svg.style.backgroundColor ||= bg[theme];
55+
svg.style.color ||= fg[theme]
56+
svg.style.backgroundColor ||= bg[theme]
5257
}
5358
for (const figure of el.tagName.toLowerCase() === "figure"
5459
? [el]
5560
: el.querySelectorAll("figure")) {
56-
figure.style.padding ||= "0px 5px 5px 5px";
61+
figure.style.padding ||= "0px 5px 5px 5px"
5762
// theming
58-
figure.style.color ||= fg[theme];
59-
figure.style.backgroundColor ||= bg[theme];
63+
figure.style.color ||= fg[theme]
64+
figure.style.backgroundColor ||= bg[theme]
6065
// pass colors to typst via attributes
61-
figure.setAttribute("typstbg", bg[theme]);
62-
figure.setAttribute("typstfg", fg[theme]);
63-
figure.setAttribute("typstcaption", caption[theme]);
66+
figure.setAttribute("typstbg", bg[theme])
67+
figure.setAttribute("typstfg", fg[theme])
68+
figure.setAttribute("typstcaption", caption[theme])
6469
for (const h2 of figure.querySelectorAll("h2")) {
65-
h2.style.lineHeight = "28px";
66-
h2.style.fontSize = "20px";
67-
h2.style.fontWeight = "600";
68-
h2.style.margin = "0";
70+
h2.style.lineHeight = "28px"
71+
h2.style.fontSize = "20px"
72+
h2.style.fontWeight = "600"
73+
h2.style.margin = "0"
6974
}
7075
for (const h3 of figure.querySelectorAll("h3")) {
71-
h3.style.lineHeight = "24px";
72-
h3.style.fontSize = "16px";
73-
h3.style.fontWeight = "400";
74-
h3.style.margin = "0";
76+
h3.style.lineHeight = "24px"
77+
h3.style.fontSize = "16px"
78+
h3.style.fontWeight = "400"
79+
h3.style.margin = "0"
7580
}
7681
for (const figcaption of figure.querySelectorAll("figcaption")) {
77-
figcaption.style.lineHeight = "20px";
78-
figcaption.style.fontSize = "12px";
79-
figcaption.style.fontWeight = "500";
80-
figcaption.style.color = caption[theme];
82+
figcaption.style.lineHeight = "20px"
83+
figcaption.style.fontSize = "12px"
84+
figcaption.style.fontWeight = "500"
85+
figcaption.style.color = caption[theme]
8186
}
8287
}
8388

84-
return el.outerHTML;
89+
return el.outerHTML
8590
}
8691

8792
// Request listener for http server
8893
const requestListener = function (req, res) {
8994
// Send back plain text
90-
res.setHeader("Content-Type", "text/plain");
95+
res.setHeader("Content-Type", "text/plain")
9196
switch (req.url) {
9297
// plot entry point
9398
case "/plot":
94-
let body = "";
99+
let body = ""
95100
req.on("data", (chunk) => {
96-
body += chunk.toString();
97-
});
101+
body += chunk.toString()
102+
})
98103
req.on("end", () => {
99-
let output;
104+
let output
100105
try {
101-
output = jsdom_plot(body);
106+
output = jsdom_plot(body)
102107
} catch (error) {
103-
res.writeHead(500);
104-
res.end(`Server error: ${error.message}.`);
105-
return;
108+
res.writeHead(500)
109+
res.end(`Server error: ${error.message}.`)
110+
return
106111
}
107-
res.writeHead(200);
108-
res.end(output);
109-
});
110-
break;
112+
res.writeHead(200)
113+
res.end(output)
114+
})
115+
break
111116
// status entry point
112117
case "/status":
113-
res.writeHead(200);
114-
res.end("pyobsplot");
115-
break;
118+
res.writeHead(200)
119+
res.end("pyobsplot")
120+
break
116121
// else
117122
default:
118-
res.writeHead(404);
119-
res.end("Resource not found");
123+
res.writeHead(404)
124+
res.end("Resource not found")
120125
}
121-
};
126+
}
122127

123128
// let OS find a free port
124-
const port = 0;
125-
const host = "localhost";
129+
const port = 0
130+
const host = "localhost"
126131
// Launch server
127-
const server = http.createServer(requestListener);
132+
const server = http.createServer(requestListener)
128133
server.listen(port, host, () => {
129134
// send selected port to stdout
130-
const port = server.address().port;
131-
process.stdout.write(port + "\n");
132-
});
135+
const port = server.address().port
136+
process.stdout.write(port + "\n")
137+
})

packages/pyobsplot-js/parsing.js

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,103 @@
11
/* Plot specification parsing */
22

3-
import * as Plot from "@observablehq/plot";
4-
import * as d3 from "d3";
5-
import * as arrow from "apache-arrow";
3+
import * as Plot from "@observablehq/plot"
4+
import * as d3 from "d3"
5+
import * as arrow from "apache-arrow"
66

77
export function unserialize_data(data, renderer) {
8-
let result = Array();
8+
let result = Array()
99
for (let d of data) {
1010
if (d["pyobsplot-type"] == "DataFrame") {
11-
let value = d["value"];
11+
let value = d["value"]
1212
if (renderer == "jsdom") {
13-
value = Buffer.from(value, "base64");
13+
value = Buffer.from(value, "base64")
1414
}
15-
let table = arrow.tableFromIPC(value);
16-
result.push(table);
15+
let table = arrow.tableFromIPC(value)
16+
result.push(table)
1717
} else {
18-
result.push(d);
18+
result.push(d)
1919
}
2020
}
21-
return result;
21+
return result
2222
}
2323

2424
// Main function : recursively parse a JSON specification
2525
export function parse_spec(code, data) {
2626
// If null, return null
2727
if (code === null) {
28-
return null;
28+
return null
2929
}
3030
// If Array, recursively parse elements
3131
if (Array.isArray(code)) {
32-
return code.map((d) => parse_spec(d, data));
32+
return code.map((d) => parse_spec(d, data))
3333
}
3434
// If a string, returns as is
3535
if (typeof code === "string" || code instanceof String) {
36-
return code;
36+
return code
3737
}
3838
// If not dict-like, returns as is
3939
if (Object.entries(code).length == 0) {
40-
return code;
40+
return code
4141
}
4242
// If DataFrame-ref type, get deserializes Arrow IPC from cache
4343
if (code["pyobsplot-type"] == "DataFrame-ref") {
44-
return data[code["value"]];
44+
return data[code["value"]]
4545
}
4646
// If a JS function with arguments type, get function from name and call it
4747
if (code["pyobsplot-type"] == "function") {
48-
let fun = get_fun(code["module"], code["method"]);
49-
return fun.call(null, ...parse_spec(code["args"], data));
48+
let fun = get_fun(code["module"], code["method"])
49+
return fun.call(null, ...parse_spec(code["args"], data))
5050
}
5151
// If a JS function object type, get function from name and call it
5252
if (code["pyobsplot-type"] == "function-object") {
53-
return get_fun(code["module"], code["method"]);
53+
return get_fun(code["module"], code["method"])
5454
}
5555
// If JavaScript code, eval it
5656
if (code["pyobsplot-type"] == "js") {
5757
// Use indirect eval to avoid bundling issues
5858
// See https://esbuild.github.io/content-types/#direct-eval
59-
let indirect_eval = eval;
60-
return indirect_eval(code["value"]);
59+
let indirect_eval = eval
60+
return indirect_eval(code["value"])
6161
}
6262
// If datetime, create a new Date object form iso format
6363
if (code["pyobsplot-type"] == "datetime") {
64-
return new Date(code["value"]);
64+
return new Date(code["value"])
6565
}
6666
// If Geojson, returns as is
6767
if (code["pyobsplot-type"] == "GeoJson") {
68-
return code["value"];
68+
return code["value"]
6969
}
7070
// If GeoJson-ref, returns as is from cache
7171
if (code["pyobsplot-type"] == "GeoJson-ref") {
72-
return data[code["value"]];
72+
return data[code["value"]]
7373
}
7474

7575
// If dict-like with entries, parse entries recursively
76-
let ret = {};
76+
let ret = {}
7777
for (const [key, value] of Object.entries(code)) {
78-
ret[key] = parse_spec(value, data);
78+
ret[key] = parse_spec(value, data)
7979
}
80-
return ret;
80+
return ret
8181
}
8282

8383
// Returns JavaScript method object from module and method names
8484
export function get_fun(mod, method) {
85-
let fun;
85+
let fun
8686
switch (mod) {
8787
case "Plot":
88-
fun = Plot[method];
89-
break;
88+
fun = Plot[method]
89+
break
9090
case "d3":
91-
fun = d3[method];
92-
break;
91+
fun = d3[method]
92+
break
9393
case "Math":
94-
fun = Math[method];
95-
break;
94+
fun = Math[method]
95+
break
9696
default:
97-
throw new Error(`Invalid module: ${mod}`);
97+
throw new Error(`Invalid module: ${mod}`)
9898
}
9999
if (fun === undefined) {
100-
throw new Error(`${mod}.${method} is not defined`);
100+
throw new Error(`${mod}.${method} is not defined`)
101101
}
102-
return fun;
102+
return fun
103103
}

0 commit comments

Comments
 (0)