-
Notifications
You must be signed in to change notification settings - Fork 1
/
mod.ts
127 lines (111 loc) · 3.24 KB
/
mod.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import {
$display,
Displayable,
format,
makeDisplayable,
MediaBundle,
} from "./format.ts";
export { $display };
interface DisplayOptions {
raw?: boolean;
}
/**
* This function creates a tagged template function for a given media type.
* The tagged template function takes a template string and returns a displayable object.
*
* @param mediatype - The media type for the tagged template function.
* @returns A function that takes a template string and returns a displayable object.
*/
function createTaggedTemplate(mediatype: string) {
return (strings: TemplateStringsArray, ...values: unknown[]) => {
const payload = strings.reduce(
(acc, string, i) => acc + string + (values[i] || ""),
"",
);
return makeDisplayable({ [mediatype]: payload });
};
}
/**
* Markdown Tagged Template Function.
*
* Takes a template string and returns a displayable object for Jupyter frontends.
*
* Example usage:
*
* md`# Notebooks in TypeScript via Deno ![Deno logo](https://github.com/denoland.png?size=32)
*
* * TypeScript ${Deno.version.typescript}
* * V8 ${Deno.version.v8}
* * Deno ${Deno.version.deno} 🔜 1.37.0
*
* Interactive compute with Jupyter _built into Deno_!
* `
*/
export const md = createTaggedTemplate("text/markdown");
/**
* HTML Tagged Template Function.
*
* Takes a template string and returns a displayable object for Jupyter frontends.
*
* Example usage:
*
* html`<h1>Hello, world!</h1>`
*/
export const html = createTaggedTemplate("text/html");
export const plain = createTaggedTemplate("text/plain");
export const js = createTaggedTemplate("application/javascript");
/**
* SVG Tagged Template Function.
*
* Takes a template string and returns a displayable object for Jupyter frontends.
*
* Example usage:
*
* svg`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
* <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
* </svg>`
*/
export const svg = createTaggedTemplate("image/svg+xml");
function isMediaBundle(obj: unknown): obj is MediaBundle {
if (obj == null || typeof obj !== "object" || Array.isArray(obj)) {
return false;
}
// Check if all keys are strings
for (const key in obj) {
if (typeof key !== "string") {
return false;
}
}
return true;
}
/**
* Display function for Jupyter Deno Kernel.
* Mimics the behavior of IPython's display(obj, raw=True) while working with
* the limitations of the 1.37 release of Deno (for now).
*
* Given that we don't have a direct way to create `display_data` (yet) in Deno,
* at least from userspace, this function can only be used as the result in a cell.
*
* @param obj - The object to be displayed
* @param options - Display options with a default { raw: true }
* @returns An object that Deno can display
*/
export function display(
obj: unknown,
options: DisplayOptions = { raw: true },
): Displayable | unknown {
// Pass undefined and null through
if (obj == null) {
return obj;
}
const displayable = format(obj);
if (displayable) {
return displayable;
}
if (isMediaBundle(obj) && options.raw) {
return makeDisplayable(obj);
}
throw new Error(
"Object not supported. Please file an issue on https://github.com/rgbkrk/display.js",
);
}