@lapis-notes/csv 0.0.0-stage → 0.2.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.
Files changed (105) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/LICENSE.md +4 -0
  3. package/README.md +19 -2
  4. package/dist/app.css +210 -0
  5. package/dist/csv-settings.d.ts +13 -0
  6. package/dist/csv-settings.js +28 -0
  7. package/dist/index.d.ts +7 -0
  8. package/dist/index.js +7 -0
  9. package/dist/lib/CsvSheet.svelte +58 -0
  10. package/dist/lib/CsvSheet.svelte.d.ts +11 -0
  11. package/dist/lib/CsvTable.svelte +58 -0
  12. package/dist/lib/CsvTable.svelte.d.ts +11 -0
  13. package/dist/lib/codemirror/csv-language-extensions.d.ts +3 -0
  14. package/dist/lib/codemirror/csv-language-extensions.js +11 -0
  15. package/dist/lib/codemirror/csv-language.d.ts +3 -0
  16. package/dist/lib/codemirror/csv-language.js +24 -0
  17. package/dist/lib/codemirror/csv-rainbow-theme.d.ts +3 -0
  18. package/dist/lib/codemirror/csv-rainbow-theme.js +15 -0
  19. package/dist/lib/codemirror/csv-source-extensions.d.ts +7 -0
  20. package/dist/lib/codemirror/csv-source-extensions.js +9 -0
  21. package/dist/lib/codemirror/csv.parser.d.ts +2 -0
  22. package/dist/lib/codemirror/csv.parser.js +16 -0
  23. package/dist/lib/codemirror/csv.parser.terms.d.ts +1 -0
  24. package/dist/lib/codemirror/csv.parser.terms.js +2 -0
  25. package/dist/lib/codemirror/syntax.grammar +36 -0
  26. package/dist/lib/components/csv-cell.svelte +137 -0
  27. package/dist/lib/components/csv-cell.svelte.d.ts +11 -0
  28. package/dist/lib/components/csv-data-table-column-head.svelte +76 -0
  29. package/dist/lib/components/csv-data-table-column-head.svelte.d.ts +17 -0
  30. package/dist/lib/components/csv-data-table-column-header.svelte +159 -0
  31. package/dist/lib/components/csv-data-table-column-header.svelte.d.ts +23 -0
  32. package/dist/lib/components/csv-data-table-data-cell.svelte +72 -0
  33. package/dist/lib/components/csv-data-table-data-cell.svelte.d.ts +18 -0
  34. package/dist/lib/components/csv-data-table-drag-overlay.svelte +119 -0
  35. package/dist/lib/components/csv-data-table-drag-overlay.svelte.d.ts +13 -0
  36. package/dist/lib/components/csv-data-table-row-actions.svelte +47 -0
  37. package/dist/lib/components/csv-data-table-row-actions.svelte.d.ts +8 -0
  38. package/dist/lib/components/csv-data-table-row-grip-cell.svelte +102 -0
  39. package/dist/lib/components/csv-data-table-row-grip-cell.svelte.d.ts +19 -0
  40. package/dist/lib/components/csv-data-table-row.svelte +38 -0
  41. package/dist/lib/components/csv-data-table-row.svelte.d.ts +11 -0
  42. package/dist/lib/components/csv-data-table.svelte +903 -0
  43. package/dist/lib/components/csv-data-table.svelte.d.ts +21 -0
  44. package/dist/lib/components/csv-find.svelte +382 -0
  45. package/dist/lib/components/csv-find.svelte.d.ts +24 -0
  46. package/dist/lib/components/csv-row-virtualizer.svelte.d.ts +9 -0
  47. package/dist/lib/components/csv-row-virtualizer.svelte.js +59 -0
  48. package/dist/lib/components/csv-source-view.svelte +127 -0
  49. package/dist/lib/components/csv-source-view.svelte.d.ts +10 -0
  50. package/dist/lib/components/csv-status-bar.svelte +101 -0
  51. package/dist/lib/components/csv-status-bar.svelte.d.ts +14 -0
  52. package/dist/lib/components/csv-table-dnd.d.ts +9 -0
  53. package/dist/lib/components/csv-table-dnd.js +12 -0
  54. package/dist/lib/components/csv-table-drag-measure.d.ts +7 -0
  55. package/dist/lib/components/csv-table-drag-measure.js +38 -0
  56. package/dist/lib/components/csv-table-selection.d.ts +28 -0
  57. package/dist/lib/components/csv-table-selection.js +178 -0
  58. package/dist/lib/components/csv-table-view.svelte +265 -0
  59. package/dist/lib/components/csv-table-view.svelte.d.ts +16 -0
  60. package/dist/lib/csv-plugin.d.ts +9 -0
  61. package/dist/lib/csv-plugin.js +107 -0
  62. package/dist/lib/csv-view-settings.d.ts +43 -0
  63. package/dist/lib/csv-view-settings.js +86 -0
  64. package/dist/lib/ids.d.ts +8 -0
  65. package/dist/lib/ids.js +19 -0
  66. package/dist/lib/model/csv-column-sort.d.ts +16 -0
  67. package/dist/lib/model/csv-column-sort.js +81 -0
  68. package/dist/lib/model/csv-grid.d.ts +31 -0
  69. package/dist/lib/model/csv-grid.js +161 -0
  70. package/dist/lib/model/csv-search.d.ts +38 -0
  71. package/dist/lib/model/csv-search.js +101 -0
  72. package/dist/lib/model/csv-table-model.d.ts +10 -0
  73. package/dist/lib/model/csv-table-model.js +18 -0
  74. package/dist/lib/model/parse-csv.d.ts +10 -0
  75. package/dist/lib/model/parse-csv.js +13 -0
  76. package/dist/lib/model/serialize-csv.d.ts +5 -0
  77. package/dist/lib/model/serialize-csv.js +10 -0
  78. package/dist/lib/sheet/csv-sheet-toolbar.svelte +244 -0
  79. package/dist/lib/sheet/csv-sheet-toolbar.svelte.d.ts +20 -0
  80. package/dist/lib/sheet/csv-sheet-view.svelte +444 -0
  81. package/dist/lib/sheet/csv-sheet-view.svelte.d.ts +18 -0
  82. package/dist/lib/sheet/csv-sheet.svelte +1121 -0
  83. package/dist/lib/sheet/csv-sheet.svelte.d.ts +37 -0
  84. package/dist/lib/sheet/sheet-glyph.svelte +57 -0
  85. package/dist/lib/sheet/sheet-glyph.svelte.d.ts +7 -0
  86. package/dist/lib/sheet/sheet-history.d.ts +14 -0
  87. package/dist/lib/sheet/sheet-history.js +33 -0
  88. package/dist/lib/sheet/sheet-layout.d.ts +121 -0
  89. package/dist/lib/sheet/sheet-layout.js +336 -0
  90. package/dist/lib/sheet/sheet-paint.d.ts +45 -0
  91. package/dist/lib/sheet/sheet-paint.js +274 -0
  92. package/dist/lib/sheet/sheet-theme.d.ts +2 -0
  93. package/dist/lib/sheet/sheet-theme.js +26 -0
  94. package/dist/lib/views/csv-view-mode.d.ts +3 -0
  95. package/dist/lib/views/csv-view-mode.js +6 -0
  96. package/dist/lib/views/csv-view.d.ts +24 -0
  97. package/dist/lib/views/csv-view.js +125 -0
  98. package/dist/styles/csv-find.css +313 -0
  99. package/dist/styles/csv-table.css +882 -0
  100. package/dist/styles.css +37 -0
  101. package/manifest.json +45 -0
  102. package/package.json +86 -3
  103. package/registry-content/overview.md +3 -0
  104. package/registry.json +322 -0
  105. package/styles.css +1 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,22 @@
1
+ # CSV
2
+
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#28](https://github.com/lapismd/lapis-plugins/pull/28) [`3b2e5df`](https://github.com/lapismd/lapis-plugins/commit/3b2e5df4a5753461a2561c67f9fc42d22e96a896) Thanks [@stevejuma](https://github.com/stevejuma)! - Add a Storybook CSV and TSV table view and note embed for a seeded sample.
8
+
9
+ ### Patch Changes
10
+
11
+ - [#28](https://github.com/lapismd/lapis-plugins/pull/28) [`8b06759`](https://github.com/lapismd/lapis-plugins/commit/8b067595fe863310e586566b1e99409fb4f79ae0) Thanks [@stevejuma](https://github.com/stevejuma)! - Mirror the workspace-host binding and the Svelte events/reactivity renderer
12
+ modules that the CSV runtime already imports in the plugin archive's shared
13
+ dependency metadata, so the packaged runtime resolves them from the host
14
+ allowlist like every other Svelte component package.
15
+
16
+ - [#28](https://github.com/lapismd/lapis-plugins/pull/28) [`c9febb1`](https://github.com/lapismd/lapis-plugins/commit/c9febb1c8b431db30ecdcf7507cfff8f727bc4ed) Thanks [@stevejuma](https://github.com/stevejuma)! - Consume the published Notes next packages, Mira 0.1.2, and Design Core 0.7.0 through the existing semver floors. Markdown dependents accept ^0.2.0. History keeps its public repository entrypoints, and Bases keeps the file-icon contract on API 0.2.0.
17
+
18
+ ## 0.1.0
19
+
20
+ ### Minor Changes
21
+
22
+ - Add a Storybook CSV and TSV table view and note embed for a seeded sample.
package/LICENSE.md ADDED
@@ -0,0 +1,4 @@
1
+ Apache-2.0
2
+
3
+ This project is licensed under the Apache License 2.0.
4
+ See <https://www.apache.org/licenses/LICENSE-2.0>.
package/README.md CHANGED
@@ -1,3 +1,20 @@
1
- # Temporary Holding Version
1
+ # CSV
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ CSV and TSV table view and note embed for Lapis applications
4
+
5
+ ## Install for static composition
6
+
7
+ ```sh
8
+ pnpm add @lapis-notes/csv
9
+ ```
10
+
11
+ Register the exported plugin class in the application's `PluginProfile`. Import
12
+ `@lapis-notes/csv/styles.css?inline` and pass the CSS through the static
13
+ registration so the host owns its lifecycle.
14
+
15
+ The runtime plugin ID is `lapis-csv`. A matching signed
16
+ `lapis-csv-0.2.0.lapis-plugin` archive is attached to the
17
+ package-scoped GitHub release for manual or registry installation.
18
+
19
+ See the [repository README](https://github.com/lapismd/lapis-plugins#readme) for
20
+ development, validation, and release-gate details.
package/dist/app.css ADDED
@@ -0,0 +1,210 @@
1
+ @import "./styles/csv-table.css";
2
+
3
+ .csv-view,
4
+ .csv-table-view,
5
+ .csv-sheet-view,
6
+ .csv-source-pane {
7
+ /* Mira rebinds `--font-mono` inside notes. The theme face stays on `--studio-font-mono`. */
8
+ --csv-font-mono: var(
9
+ --studio-font-mono,
10
+ "Source Code Pro Variable",
11
+ "Source Code Pro",
12
+ ui-monospace,
13
+ SFMono-Regular,
14
+ Menlo,
15
+ Monaco,
16
+ Consolas,
17
+ "Liberation Mono",
18
+ monospace
19
+ );
20
+ --csv-col-1: oklch(0.53 0.19 25);
21
+ --csv-col-2: oklch(0.49 0.16 145);
22
+ --csv-col-3: oklch(0.49 0.14 230);
23
+ --csv-col-4: oklch(0.53 0.17 310);
24
+ --csv-col-5: oklch(0.52 0.15 85);
25
+ --csv-separator: var(--text-muted, var(--muted-foreground));
26
+ --csv-shell-background: var(--background-primary, var(--background));
27
+ --csv-surface-border: var(--background-modifier-border, var(--border));
28
+ --csv-text-color: var(--text-normal, var(--foreground));
29
+ --csv-muted-color: var(--text-muted, var(--muted-foreground));
30
+ --csv-error-color: var(--text-error, var(--destructive));
31
+ --csv-header-background: var(
32
+ --background-secondary,
33
+ var(--background-primary, var(--background))
34
+ );
35
+ --csv-index-background: var(
36
+ --background-secondary-alt,
37
+ var(--background-secondary, var(--background))
38
+ );
39
+ --table-selection: hsla(var(--color-accent-hsl, 250 60% 50%), 0.12);
40
+ --table-selection-border-color: var(
41
+ --interactive-accent,
42
+ var(--accent, hsl(250 60% 50%))
43
+ );
44
+ --table-drag-handle-color: var(--text-faint, var(--muted-foreground));
45
+ --table-drag-handle-background: transparent;
46
+ }
47
+
48
+ .dark .csv-view,
49
+ .dark .csv-table-view,
50
+ .dark .csv-sheet-view,
51
+ .dark .csv-source-pane {
52
+ --csv-col-1: oklch(0.72 0.16 25);
53
+ --csv-col-2: oklch(0.74 0.14 145);
54
+ --csv-col-3: oklch(0.74 0.12 230);
55
+ --csv-col-4: oklch(0.74 0.14 310);
56
+ --csv-col-5: oklch(0.78 0.13 85);
57
+ }
58
+
59
+ .csv-view {
60
+ display: flex;
61
+ height: 100%;
62
+ min-height: 0;
63
+ flex-direction: column;
64
+ overflow: hidden;
65
+ color: var(--csv-text-color);
66
+ background: var(--csv-shell-background);
67
+ }
68
+
69
+ .csv-view__editor,
70
+ .csv-view__table {
71
+ height: 100%;
72
+ min-height: 0;
73
+ }
74
+
75
+ .csv-source-view .cm-csv-cell1,
76
+ .csv-source-view .cm-content .cm-csv-cell1 {
77
+ color: var(--csv-col-1);
78
+ }
79
+
80
+ .csv-source-view .cm-csv-cell2 {
81
+ color: var(--csv-col-2);
82
+ }
83
+
84
+ .csv-source-view .cm-csv-cell3 {
85
+ color: var(--csv-col-3);
86
+ }
87
+
88
+ .csv-source-view .cm-csv-cell4 {
89
+ color: var(--csv-col-4);
90
+ }
91
+
92
+ .csv-source-view .cm-csv-cell5 {
93
+ color: var(--csv-col-5);
94
+ }
95
+
96
+ .csv-source-view .cm-csv-separator {
97
+ color: var(--csv-separator);
98
+ opacity: 0.75;
99
+ }
100
+
101
+ .csv-source-pane {
102
+ display: flex;
103
+ flex: 1 1 auto;
104
+ flex-direction: column;
105
+ width: 100%;
106
+ height: 100%;
107
+ min-width: 0;
108
+ min-height: 0;
109
+ color: var(--csv-text-color);
110
+ background: var(--csv-shell-background);
111
+ }
112
+
113
+ .csv-source-pane__editor {
114
+ flex: 1 1 auto;
115
+ min-height: 0;
116
+ overflow: auto;
117
+ }
118
+
119
+ .csv-source-pane__editor :global(.cm-editor) {
120
+ height: 100%;
121
+ background: transparent;
122
+ }
123
+
124
+ .csv-source-pane .cm-editor.csv-source-view,
125
+ .csv-source-pane .cm-editor.csv-source-view .cm-scroller,
126
+ .csv-source-pane .cm-editor.csv-source-view .cm-content,
127
+ .csv-source-pane .cm-editor.csv-source-view .cm-line {
128
+ font-family: var(--csv-font-mono);
129
+ }
130
+
131
+ .csv-table-view__errors {
132
+ padding: 0.5rem 0.75rem;
133
+ border-bottom: 1px solid var(--csv-surface-border);
134
+ color: var(--csv-error-color);
135
+ font-size: 0.875rem;
136
+ }
137
+
138
+ .csv-table-view__errors p {
139
+ margin: 0;
140
+ }
141
+
142
+ .csv-table-view__scroll {
143
+ flex: 1 1 auto;
144
+ height: auto;
145
+ min-height: 0;
146
+ }
147
+
148
+ .csv-status-bar {
149
+ box-sizing: border-box;
150
+ display: flex;
151
+ flex: 0 0 2rem;
152
+ align-items: center;
153
+ gap: 0.375rem;
154
+ width: 100%;
155
+ height: 2rem;
156
+ min-width: 0;
157
+ padding-inline: 0.5rem;
158
+ border-block-start: 1px solid var(--ui-workspace-border, var(--border));
159
+ background: var(--background);
160
+ color: var(--ui-workspace-muted-foreground, var(--muted-foreground));
161
+ font-size: 0.75rem;
162
+ line-height: 1;
163
+ user-select: none;
164
+ }
165
+
166
+ .csv-status-bar__text {
167
+ padding-inline: 0.25rem;
168
+ white-space: nowrap;
169
+ font-variant-numeric: tabular-nums;
170
+ }
171
+
172
+ .csv-status-bar__icon {
173
+ display: inline-flex;
174
+ align-items: center;
175
+ justify-content: center;
176
+ width: 1.5rem;
177
+ height: 1.5rem;
178
+ border: 0;
179
+ border-radius: var(--ui-workspace-radius-small, 0.25rem);
180
+ padding: 0;
181
+ background: transparent;
182
+ color: inherit;
183
+ line-height: 1;
184
+ }
185
+
186
+ .csv-status-bar__icon:hover {
187
+ color: var(--foreground);
188
+ background: color-mix(in srgb, var(--foreground) 8%, transparent);
189
+ }
190
+
191
+ .csv-status-bar__icon--pressed {
192
+ color: var(--foreground);
193
+ background: color-mix(in srgb, var(--foreground) 8%, transparent);
194
+ }
195
+
196
+ .csv-status-bar__modes {
197
+ display: inline-flex;
198
+ align-items: center;
199
+ gap: 0.125rem;
200
+ margin-inline-start: auto;
201
+ }
202
+
203
+ .csv-status-bar__mode {
204
+ margin-inline-start: 0;
205
+ }
206
+
207
+ .csv-status-bar__icon svg {
208
+ width: 0.875rem;
209
+ height: 0.875rem;
210
+ }
@@ -0,0 +1,13 @@
1
+ export type CsvDelimiter = "," | "\t" | ";" | "|";
2
+ export type CsvDelimiterMode = "auto" | CsvDelimiter;
3
+ export type CsvPluginSettings = {
4
+ headerRow: boolean;
5
+ delimiter: CsvDelimiterMode;
6
+ showRowNumbers: boolean;
7
+ };
8
+ export type CsvPluginSettingsPatch = Partial<CsvPluginSettings>;
9
+ export declare const DEFAULT_CSV_SETTINGS: CsvPluginSettings;
10
+ export declare function mergeCsvSettings(data: Partial<CsvPluginSettings> | null | undefined): CsvPluginSettings;
11
+ export declare function patchCsvSettings(current: CsvPluginSettings, patch: CsvPluginSettingsPatch): CsvPluginSettings;
12
+ export declare function delimiterForExtension(extension: string): CsvDelimiter;
13
+ export declare function resolveDelimiter(settings: CsvPluginSettings, extension: string): CsvDelimiter;
@@ -0,0 +1,28 @@
1
+ export const DEFAULT_CSV_SETTINGS = {
2
+ headerRow: true,
3
+ delimiter: "auto",
4
+ showRowNumbers: true,
5
+ };
6
+ export function mergeCsvSettings(data) {
7
+ return {
8
+ ...DEFAULT_CSV_SETTINGS,
9
+ ...data,
10
+ };
11
+ }
12
+ export function patchCsvSettings(current, patch) {
13
+ return mergeCsvSettings({ ...current, ...patch });
14
+ }
15
+ export function delimiterForExtension(extension) {
16
+ switch (extension.toLowerCase()) {
17
+ case "tsv":
18
+ return "\t";
19
+ default:
20
+ return ",";
21
+ }
22
+ }
23
+ export function resolveDelimiter(settings, extension) {
24
+ if (settings.delimiter === "auto") {
25
+ return delimiterForExtension(extension);
26
+ }
27
+ return settings.delimiter;
28
+ }
@@ -0,0 +1,7 @@
1
+ import "./styles.css";
2
+ export { default as manifest } from "../manifest.json";
3
+ export { CSV_EXTENSIONS, CSV_FILENAME_PATTERNS, CSV_PLUGIN_ID, CSV_VIEW_TYPE, SAMPLE_CSV_PATH, SAMPLE_PLAIN_NOTE_PATH, SAMPLE_READING_NOTE_PATH, sampleReadingMarkdown, } from "./lib/ids";
4
+ export { default as CsvTable } from "./lib/CsvTable.svelte";
5
+ export { CSVPlugin } from "./lib/csv-plugin";
6
+ export { default } from "./lib/csv-plugin";
7
+ export { CsvFileView } from "./lib/views/csv-view";
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ import "./styles.css";
2
+ export { default as manifest } from "../manifest.json";
3
+ export { CSV_EXTENSIONS, CSV_FILENAME_PATTERNS, CSV_PLUGIN_ID, CSV_VIEW_TYPE, SAMPLE_CSV_PATH, SAMPLE_PLAIN_NOTE_PATH, SAMPLE_READING_NOTE_PATH, sampleReadingMarkdown, } from "./lib/ids";
4
+ export { default as CsvTable } from "./lib/CsvTable.svelte";
5
+ export { CSVPlugin } from "./lib/csv-plugin";
6
+ export { default } from "./lib/csv-plugin";
7
+ export { CsvFileView } from "./lib/views/csv-view";
@@ -0,0 +1,58 @@
1
+ <script lang="ts">
2
+ import type { App, TFile } from "@lapis-notes/api";
3
+ import {
4
+ DEFAULT_CSV_SETTINGS,
5
+ patchCsvSettings,
6
+ type CsvPluginSettings,
7
+ type CsvPluginSettingsPatch,
8
+ } from "../csv-settings";
9
+ import CsvSheetView from "./sheet/csv-sheet-view.svelte";
10
+
11
+ let {
12
+ app,
13
+ file,
14
+ role = "file",
15
+ onShowTable,
16
+ onToggleSource,
17
+ }: {
18
+ app: App;
19
+ file: TFile;
20
+ role?: "file" | "embed";
21
+ onShowTable?: () => void;
22
+ onToggleSource?: () => void;
23
+ } = $props();
24
+
25
+ let settings = $state<CsvPluginSettings>({ ...DEFAULT_CSV_SETTINGS });
26
+ const loaded = $derived.by(() => app.vault.cachedRead(file));
27
+
28
+ function handleContentChange(text: string) {
29
+ void app.vault.modify(file, text);
30
+ }
31
+
32
+ function handleSettingsChange(patch: CsvPluginSettingsPatch) {
33
+ settings = patchCsvSettings(settings, patch);
34
+ }
35
+ </script>
36
+
37
+ <div class="csv-table-frame" data-testid="csv-canvas" data-csv-role={role}>
38
+ {#key file.path}
39
+ {#await loaded}
40
+ <p class="csv-table-status">Reading this table.</p>
41
+ {:then content}
42
+ <CsvSheetView
43
+ {app}
44
+ {file}
45
+ {content}
46
+ {settings}
47
+ onContentChange={handleContentChange}
48
+ onSettingsChange={handleSettingsChange}
49
+ {onShowTable}
50
+ {onToggleSource}
51
+ />
52
+ {:catch reason}
53
+ <p class="csv-table-status" data-csv-error="true">
54
+ {reason instanceof Error ? reason.message : "Unable to read this table."}
55
+ </p>
56
+ {/await}
57
+ {/key}
58
+ </div>
@@ -0,0 +1,11 @@
1
+ import type { App, TFile } from "@lapis-notes/api";
2
+ type $$ComponentProps = {
3
+ app: App;
4
+ file: TFile;
5
+ role?: "file" | "embed";
6
+ onShowTable?: () => void;
7
+ onToggleSource?: () => void;
8
+ };
9
+ declare const CsvSheet: import("svelte").Component<$$ComponentProps, {}, "">;
10
+ type CsvSheet = ReturnType<typeof CsvSheet>;
11
+ export default CsvSheet;
@@ -0,0 +1,58 @@
1
+ <script lang="ts">
2
+ import type { App, TFile } from "@lapis-notes/api";
3
+ import CsvTableView from "./components/csv-table-view.svelte";
4
+ import {
5
+ DEFAULT_CSV_SETTINGS,
6
+ patchCsvSettings,
7
+ type CsvPluginSettings,
8
+ type CsvPluginSettingsPatch,
9
+ } from "../csv-settings";
10
+
11
+ let {
12
+ app,
13
+ file,
14
+ role = "file",
15
+ onToggleSource,
16
+ onShowCanvas,
17
+ }: {
18
+ app: App;
19
+ file: TFile;
20
+ role?: "file" | "embed";
21
+ onToggleSource?: () => void;
22
+ onShowCanvas?: () => void;
23
+ } = $props();
24
+
25
+ let settings = $state<CsvPluginSettings>({ ...DEFAULT_CSV_SETTINGS });
26
+ const loaded = $derived.by(() => app.vault.cachedRead(file));
27
+
28
+ function handleContentChange(text: string) {
29
+ void app.vault.modify(file, text);
30
+ }
31
+
32
+ function handleSettingsChange(patch: CsvPluginSettingsPatch) {
33
+ settings = patchCsvSettings(settings, patch);
34
+ }
35
+ </script>
36
+
37
+ <div class="csv-table-frame" data-testid="csv-table" data-csv-role={role}>
38
+ {#key file.path}
39
+ {#await loaded}
40
+ <p class="csv-table-status">Reading this table.</p>
41
+ {:then content}
42
+ <CsvTableView
43
+ {app}
44
+ {file}
45
+ {content}
46
+ {settings}
47
+ onContentChange={handleContentChange}
48
+ onSettingsChange={handleSettingsChange}
49
+ {onToggleSource}
50
+ {onShowCanvas}
51
+ />
52
+ {:catch reason}
53
+ <p class="csv-table-status" data-csv-error="true">
54
+ {reason instanceof Error ? reason.message : "Unable to read this table."}
55
+ </p>
56
+ {/await}
57
+ {/key}
58
+ </div>
@@ -0,0 +1,11 @@
1
+ import type { App, TFile } from "@lapis-notes/api";
2
+ type $$ComponentProps = {
3
+ app: App;
4
+ file: TFile;
5
+ role?: "file" | "embed";
6
+ onToggleSource?: () => void;
7
+ onShowCanvas?: () => void;
8
+ };
9
+ declare const CsvTable: import("svelte").Component<$$ComponentProps, {}, "">;
10
+ type CsvTable = ReturnType<typeof CsvTable>;
11
+ export default CsvTable;
@@ -0,0 +1,3 @@
1
+ import type { Extension } from "@codemirror/state";
2
+ /** CSV language and column colours, without the Lapis editor shell. */
3
+ export declare function csvLanguageExtensions(): Extension[];
@@ -0,0 +1,11 @@
1
+ import { EditorView } from "@codemirror/view";
2
+ import { csv } from "./csv-language";
3
+ import { csvRainbowTheme } from "./csv-rainbow-theme";
4
+ /** CSV language and column colours, without the Lapis editor shell. */
5
+ export function csvLanguageExtensions() {
6
+ return [
7
+ csv(),
8
+ csvRainbowTheme(),
9
+ EditorView.editorAttributes.of({ class: "csv-source-view" }),
10
+ ];
11
+ }
@@ -0,0 +1,3 @@
1
+ import { LRLanguage, LanguageSupport } from "@codemirror/language";
2
+ export declare const csvLanguage: LRLanguage;
3
+ export declare function csv(): LanguageSupport;
@@ -0,0 +1,24 @@
1
+ import { LRLanguage, LanguageSupport } from "@codemirror/language";
2
+ import { styleTags, tags as t } from "@lezer/highlight";
3
+ import { parser } from "./csv.parser";
4
+ const csvParser = parser.configure({
5
+ props: [
6
+ styleTags({
7
+ "Cell1/...": t.content,
8
+ "Cell2/...": t.typeName,
9
+ "Cell3/...": t.propertyName,
10
+ "Cell4/...": t.labelName,
11
+ "Cell5/...": t.name,
12
+ Separator: t.separator,
13
+ string: t.string,
14
+ value: t.variableName,
15
+ }),
16
+ ],
17
+ });
18
+ export const csvLanguage = LRLanguage.define({
19
+ name: "csv",
20
+ parser: csvParser,
21
+ });
22
+ export function csv() {
23
+ return new LanguageSupport(csvLanguage);
24
+ }
@@ -0,0 +1,3 @@
1
+ import { HighlightStyle } from "@codemirror/language";
2
+ export declare const csvHighlightStyle: HighlightStyle;
3
+ export declare function csvRainbowTheme(): import("@codemirror/state").Extension;
@@ -0,0 +1,15 @@
1
+ import { HighlightStyle, syntaxHighlighting } from "@codemirror/language";
2
+ import { tags } from "@lezer/highlight";
3
+ export const csvHighlightStyle = HighlightStyle.define([
4
+ { tag: tags.content, class: "cm-csv-cell1" },
5
+ { tag: tags.typeName, class: "cm-csv-cell2" },
6
+ { tag: tags.propertyName, class: "cm-csv-cell3" },
7
+ { tag: tags.labelName, class: "cm-csv-cell4" },
8
+ { tag: tags.name, class: "cm-csv-cell5" },
9
+ { tag: tags.string, class: "cm-csv-string" },
10
+ { tag: tags.variableName, class: "cm-csv-value" },
11
+ { tag: tags.separator, class: "cm-csv-separator" },
12
+ ]);
13
+ export function csvRainbowTheme() {
14
+ return syntaxHighlighting(csvHighlightStyle);
15
+ }
@@ -0,0 +1,7 @@
1
+ import type { Extension } from "@codemirror/state";
2
+ import type { App } from "@lapis-notes/api";
3
+ /**
4
+ * Lapis markup editor with the CSV language layered on top.
5
+ * Line numbers, wrapping, indent, and the monospace face come from the host.
6
+ */
7
+ export declare function csvSourceExtensions(app: App): Extension;
@@ -0,0 +1,9 @@
1
+ import { markupEditor } from "@lapis-notes/api/editor/core";
2
+ import { csvLanguageExtensions } from "./csv-language-extensions";
3
+ /**
4
+ * Lapis markup editor with the CSV language layered on top.
5
+ * Line numbers, wrapping, indent, and the monospace face come from the host.
6
+ */
7
+ export function csvSourceExtensions(app) {
8
+ return markupEditor({ language: "csv", app }, ...csvLanguageExtensions());
9
+ }
@@ -0,0 +1,2 @@
1
+ import { LRParser } from "@lezer/lr";
2
+ export declare const parser: LRParser;
@@ -0,0 +1,16 @@
1
+ // This file was generated by lezer-generator. You probably shouldn't edit it.
2
+ import { LRParser } from "@lezer/lr";
3
+ export const parser = LRParser.deserialize({
4
+ version: 14,
5
+ states: "$[OQOPOOOOOO'#Ci'#CiOOOO'#C_'#C_OcOPO'#ChOOOO'#C^'#C^OnOPO'#CeOQOPOOOQOPO,59SQOOO,59P,59PQOOOOOOOOO-E6c-E6cOOOO'#Ca'#CaOvOPO1G.nP!ROPO'#CeOQOPO7+$YOOOO'#Cb'#CbO!WOPO<<GtOQOPOAN=`OOOO'#Cc'#CcO!cOPOG22zOQOPOLD(fOOOO'#Cd'#CdO!nOPO!$'LQOQOPO!)9AlOOOO!.K7W!.K7W",
6
+ stateData: "#O~O^PO_POS]P`]Pa]P~OSVO`[Xa[X~O`WOaXO~OS^O`[ia[i~O`WO~OSaO`[ya[y~OSdO`[!Za[!Z~OSgO`[!ka[!k~O^S_S~",
7
+ goto: "!d^PP_cPhknqtPPz!RTTOUVROUgR[VR`^RcaRfdQUORYUSSOURhgUQOUgQZVQ_^QbaRed",
8
+ nodeNames: "⚠ Program Row Cell1 Separator Cell2 Cell3 Cell4 Cell5",
9
+ maxTerm: 17,
10
+ skippedNodes: [0],
11
+ repeatNodeCount: 1,
12
+ tokenData: "(p~RbOX!ZXY#OYZ#TZ]!Z]^#Y^r!Zrs#`s|!Z|}#O}!]!Z!]!^#O!^#p!Z#p#q#O#q;'S!Z;'S;=`!x<%l~!Z~O!Z~~(k~!`W_~OX!ZZ]!Z^|!Z}!]!Z!^#p!Z#q;'S!Z;'S;=`!x<%lO!Z~!{P;=`<%l!Z~#TOS~~#YO`~~#]PYZ#T~#ea_~OX#`XZ$jZ]#`]^$j^r#`rs&Ws|#`|}$j}!]#`!]!^$j!^#O#`#O#P&w#P#p#`#p#q$j#q;'S#`;'S;=`(e<%lO#`~$mVOr$jrs%Ss#O$j#O#P%X#P;'S$j;'S;=`&Q<%lO$j~%XO^~~%[RO;'S$j;'S;=`%e;=`O$j~%hWOr$jrs%Ss#O$j#O#P%X#P;'S$j;'S;=`&Q;=`<%l$j<%lO$j~&TP;=`<%l$j~&_W^~_~OX!ZZ]!Z^|!Z}!]!Z!^#p!Z#q;'S!Z;'S;=`!x<%lO!Z~&|^_~OX#`XZ$jZ]#`]^$j^|#`|}$j}!]#`!]!^$j!^#p#`#p#q$j#q;'S#`;'S;=`'x;=`<%l$j<%lO#`~'{WOr$jrs%Ss#O$j#O#P%X#P;'S$j;'S;=`&Q;=`<%l#`<%lO$j~(hP;=`<%l#`~(pOa~",
13
+ tokenizers: [0],
14
+ topRules: { Program: [0, 1] },
15
+ tokenPrec: 87,
16
+ });
@@ -0,0 +1 @@
1
+ export declare const Program = 1, Row = 2, Cell1 = 3, Separator = 4, Cell2 = 5, Cell3 = 6, Cell4 = 7, Cell5 = 8;
@@ -0,0 +1,2 @@
1
+ // This file was generated by lezer-generator. You probably shouldn't edit it.
2
+ export const Program = 1, Row = 2, Cell1 = 3, Separator = 4, Cell2 = 5, Cell3 = 6, Cell4 = 7, Cell5 = 8;
@@ -0,0 +1,36 @@
1
+ @top Program { (Row newline)* (Row (newline | eof)) }
2
+
3
+ @skip {}
4
+
5
+ Row { group }
6
+
7
+ group { Cell1 (Separator Cell2 (Separator Cell3 (Separator Cell4 (Separator Cell5 (Separator group)?)?)?)?)? }
8
+
9
+ Cell1 { expression }
10
+ Cell2 { expression }
11
+ Cell3 { expression }
12
+ Cell4 { expression }
13
+ Cell5 { expression }
14
+
15
+ expression {
16
+ empty |
17
+ string |
18
+ value
19
+ }
20
+
21
+ empty { }
22
+
23
+ @tokens {
24
+ Separator { $[,;\t|] }
25
+
26
+ value { ![,;\t|\r\n]+ }
27
+
28
+ string { '"' (!["\\] | "\\" _)* '"' }
29
+
30
+ newline { '\r'? '\n' }
31
+ eof { @eof }
32
+
33
+ @precedence { string, Separator, value }
34
+ }
35
+
36
+ @detectDelim