@riebeckite/plugin-bases 0.0.27 → 0.0.28

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.
package/README.md CHANGED
@@ -2,181 +2,165 @@
2
2
 
3
3
  <!-- Generated from docs/docs/plugins/bases.md. Edit the canonical documentation in docs/docs/plugins and run `pnpm docs:sync`. -->
4
4
 
5
- Render Obsidian Bases definitions from fenced `base` code blocks. Filtering,
6
- sorting, and view composition run against the content manifest at build time, so
7
- no client-side JavaScript is required.
5
+ Render a compatible, build-time subset of Obsidian Bases. `bases()` supports both
6
+ fenced `base` blocks and referenced `.base` documents; no client-side evaluator
7
+ is shipped.
8
8
 
9
9
  [日本語](./README_ja.md)
10
10
 
11
- ## Overview
11
+ ## Setup
12
12
 
13
- `bases()` recognises fenced blocks
13
+ ```ts
14
+ import { bases } from "@riebeckite/plugin-bases";
14
15
 
15
- ````md
16
- ```base
17
- filters:
18
- and:
19
- - file.hasTag("featured")
20
- properties:
21
- file.name:
22
- displayName: Title
23
- file.tags:
24
- displayName: Tags
25
- views:
26
- - type: table
27
- name: Featured
28
- order:
29
- - file.name
30
- - file.tags
31
- limit: 10
16
+ export default { plugins: [bases()] };
32
17
  ```
33
- ````
34
18
 
35
- and renders them using the content manifest (every note's frontmatter, tags,
36
- links, and permalink).
19
+ ## `.base` documents and publication
37
20
 
38
- ## Usage
21
+ A `.base` file becomes a PageType page at its extensionless path when a routable
22
+ Markdown note links to it, for example `![views/Books.base](https://github.com/Rerurate514/riebeckite/blob/main/docs/docs/views/Books.base.md)` creates
23
+ `/views/Books`. This uses the normal PageType API and does not install custom
24
+ routing.
39
25
 
40
- ```ts
41
- import { defineConfig } from "@riebeckite/core";
42
- import { bases } from "@riebeckite/plugin-bases";
43
-
44
- export default defineConfig({
45
- // ...
46
- plugins: [bases()],
47
- });
48
- ```
26
+ Document-page discovery uses Core's `publicEntries`, so a public or unlisted note
27
+ may explicitly expose a referenced Base. Base rows use `discoverableEntries`:
28
+ only public notes are listed automatically; unlisted notes remain routable only by
29
+ their direct URL. Drafts and scheduled notes are excluded from both. A Base
30
+ referenced only from non-public content is not published. Existing Markdown pages
31
+ and public redirects win route collisions; the Base page is skipped with a
32
+ `bases-invalid` warning.
49
33
 
50
- ## Block syntax
51
-
52
- The block body is an Obsidian Base YAML document.
53
-
54
- | Field | Type | Description |
55
- | ----- | ---- | ----------- |
56
- | `filters` | expression \| list \| object | Top-level filter applied to every view (below) |
57
- | `properties` | object | Property id -> display name (or `{ displayName }`) |
58
- | `views` | object[] | One or more views |
59
-
60
- ### Views
61
-
62
- | Field | Type | Description |
63
- | ----- | ---- | ----------- |
64
- | `type` | `"table"` \| `"cards"` | Output kind. Defaults to `table` |
65
- | `name` | string | Optional label rendered above the view |
66
- | `filters` | filter | Additional filter, combined with the top-level filter using AND |
67
- | `order` | string \| string[] | Columns (property ids) and their display order |
68
- | `columns` | string \| string[] | Alias for `order` |
69
- | `sort` | object \| object[] \| string | Sort keys (below) |
70
- | `limit` | number | Row cap for this view; still bounded by the `limit` option |
71
-
72
- `sort` accepts the Core shape `{ field, order }`, the Obsidian shape
73
- `{ property, direction }`, or a shorthand string (`"-file.name"` sorts
74
- descending). When a view omits `order`/`columns`, the columns are the keys of
75
- `properties` (in order), or `["file.name", "file.tags"]`.
76
-
77
- ### Filter grammar
78
-
79
- A filter is an expression string, a list of expressions (treated as AND), or an
80
- object with `and` / `or` / `not` keys. `and` and `or` take a list; `not` takes an
81
- expression or a list (the list is ANDed, then negated). A plain object whose keys
82
- are property names is treated as equality.
83
-
84
- | Expression | Description |
85
- | ---------- | ----------- |
86
- | `file.hasTag("x")` | Has the tag `x` (or a subtag `x/...`). Case-insensitive |
87
- | `file.inFolder("x")` | Slug equals `x` or starts with `x/` |
88
- | `file.hasLink("x")` | Links to `x` (by resolved slug, raw target, or file name) |
89
- | `file.name` / `file.title` | Note title |
90
- | `file.path` / `file.slug` | Slug |
91
- | `file.folder` | Parent folder of the slug |
92
- | `file.link` / `file.permalink` | Permalink |
93
- | `file.tags` | Tags |
94
- | `note.key` / `key` | A frontmatter value |
95
-
96
- Comparisons use `==`, `!=`, `>`, `<`, `>=`, `<=`, and `contains`. String
97
- comparisons are case-insensitive; `contains` tests array membership or substring
98
- containment. Bare scalar lists are ANDed.
34
+ ## Example
99
35
 
100
36
  ```yaml
101
- filters:
102
- and:
103
- - file.hasTag("featured")
104
- - or:
105
- - note.status == "published"
106
- - note.status == "review"
107
- - not:
108
- - file.hasTag("draft")
37
+ filters: note.status == "published" && !file.hasTag("hidden")
38
+ formulas:
39
+ label: 'note.author.name.upper() + " / " + note.score'
40
+ summaries:
41
+ total: values.reduce(acc + value, 0)
42
+ properties:
43
+ file.name: File
44
+ formula.label: Label
109
45
  views:
110
46
  - type: table
111
- name: Featured
112
- order: [file.name, note.status]
113
- sort:
114
- - property: file.name
115
- direction: ASC
116
- limit: 20
47
+ name: Books
48
+ order: [file.name, formula.label]
49
+ sort: [{ property: formula.label, direction: DESC }]
50
+ groupBy: { property: note.status, direction: ASC }
51
+ summaries: { formula.label: total }
52
+ - type: cards
53
+ name: Cards
54
+ order: [file.name, formula.label]
117
55
  ```
118
56
 
119
- ## Options
120
-
121
- | Option | Type | Default | Description |
122
- | ------ | ---- | ------- | ----------- |
123
- | `className` | `string` | `"rb-bases"` | Root CSS class |
124
- | `language` | `string` | `"base"` | Fence language to target |
125
- | `limit` | `number` | `100` | Global row cap applied to every view |
126
- | `showFallback` | `boolean` | `true` | Render the raw Base definition in a `<details>` fallback |
127
- | `view` | `string` | none | Render only the view with this name when a Base defines several |
128
-
129
- ## Output HTML / CSS hooks
130
-
131
- ```html
132
- <div class="rb-bases" data-bases data-bases-view="table">
133
- <section class="rb-bases__view" data-bases-view="table">
134
- <h3 class="rb-bases__view-name">Featured</h3>
135
- <table class="rb-bases__table"> ... </table>
136
- </section>
137
- <details class="rb-bases__fallback"> ... </details>
138
- </div>
139
- ```
140
-
141
- Stable classes: `rb-bases`, `rb-bases__view`, `rb-bases__view-name`,
142
- `rb-bases__table`, `rb-bases__heading`, `rb-bases__cell`, `rb-bases__row`,
143
- `rb-bases__link`, `rb-bases__tags`, `rb-bases__tag`, `rb-bases__cards`,
144
- `rb-bases__card`, `rb-bases__card-title`, `rb-bases__fields`, `rb-bases__field`,
145
- `rb-bases__field-label`, `rb-bases__field-value`, `rb-bases__empty`,
146
- `rb-bases__fallback`, `rb-bases--error`. Stable attributes: `data-bases`,
147
- `data-bases-view`.
148
-
149
- ## Diagnostics
150
-
151
- A block that is not valid YAML, or that uses an unsupported filter expression or
152
- view shape, is left as a code block and reported through `file.message(...)` with
153
- `source: "@riebeckite/plugin-bases"`.
154
-
155
- ## Limitations
156
-
157
- This is an MVP subset of Obsidian Bases:
158
-
159
- - Only the `table` and `cards` view types are rendered.
160
- - Inline boolean operators (`&&`, `||`, `!`) are not supported; use the
161
- `and` / `or` / `not` YAML structure.
162
- - `if()` / `filter()` and other Base formula functions are not supported.
163
- - Nested property paths and `file.mtime` / `file.ctime` are mapped onto `date`.
164
- - Property-to-property comparisons are not supported; the right-hand side is a
165
- literal.
166
- - Results are fixed at build time. Rebuilding a host note when a queried note
167
- changes is future work; a full build always recomputes correctly.
168
-
169
- ## Exports
170
-
171
- - `bases(options?)` — plugin factory (alias: `basesPlugin`)
172
- - `remarkBases(options?)` — remark transform usable on its own (`options.language`
173
- selects the fence language)
174
- - `parseBases(document)` — compiles a parsed YAML Base document to a spec
175
- - `matchesCondition(condition, entry)` — condition evaluator
176
- - Types: `BasesOptions`, `BasesSpec`, `BasesView`, `BasesViewType`,
177
- `BasesCondition`, `BasesValueRef`, `BasesBuiltinValue`, `BasesOperator`,
178
- `BasesLiteral`
179
-
180
- ## See also
181
-
182
- - [Plugin guide](https://github.com/Rerurate514/riebeckite/blob/main/docs/docs/reference/plugin-api.md)
57
+ The same YAML may be placed in a fenced `base` block or in a `.base` file.
58
+ Top-level and view-local `filters` are combined with AND. Table and cards are
59
+ rendered at build time; all dynamic values are escaped before HTML output.
60
+
61
+ ## Official syntax audit
62
+
63
+ This implementation follows the documented YAML shape in the [Obsidian Bases
64
+ syntax](https://help.obsidian.md/bases/syntax) and [views](https://help.obsidian.md/bases/views)
65
+ references. Compatibility is deliberately scoped to deterministic static output.
66
+
67
+ | Syntax or view capability | Status | Static behavior |
68
+ | --- | --- | --- |
69
+ | Root `filters`, `formulas`, `properties`, `summaries`, and `views` | Supported | Recursive `and`/`or`/`not` filters and `displayName` are accepted. |
70
+ | View `type`, `name`, `limit`, `filters`, `order`, `sort`, `groupBy`, `groupOrder`, and `summaries` | Supported | `groupOrder` is exclusive: an empty list hides all groups, and listed missing values create empty groups. |
71
+ | Table and cards layouts | Supported | Generated semantic HTML has no runtime evaluator. |
72
+ | List, kanban, and map layouts | Unsupported | Their interactive and spatial behavior cannot be represented by this static renderer. |
73
+ | Editing, property menus, resize, drag-and-drop, and collapse controls | Out of Scope | Bases is rendered during the site build. |
74
+
75
+ ## Expression and formula subset
76
+
77
+ Expressions are parsed into an AST and interpreted directly. They never use
78
+ `eval`, `Function`, or arbitrary JavaScript execution. Supported syntax includes
79
+ literal values and arrays, nested member/index access, `!`, unary `-`, arithmetic,
80
+ comparison, `&&`, `||`, parentheses, property-to-property comparisons, and
81
+ `formula.name` references. Formula cycles evaluate to an empty value.
82
+
83
+ Supported functions: `if`, `list`, `length`, `number`, `min`, `max`, `date`,
84
+ `duration`, `isTruthy`, `isType`, `toString`, `escapeHTML`; string `lower`,
85
+ `upper`, `title`, `contains`, `startsWith`, `endsWith`, `trim`, `split`,
86
+ `replace`, `reverse`, `repeat`, `slice`, `isEmpty`; list `contains`, `containsAll`,
87
+ `containsAny`, `join`, `unique`, `flat`, `sort`, `reverse`, `slice`, `isEmpty`,
88
+ `mean`, `sum`, `min`, `max`, `map`, `filter`, `reduce`; number `round`, `floor`,
89
+ `ceil`, `abs`, `toFixed`; object `isEmpty`, `keys`, `values`; UTC date fields,
90
+ `date`, `time`, `format`; and `file.hasTag`, `file.hasLink`, `file.inFolder`,
91
+ `file.hasProperty`.
92
+
93
+ `date()` accepts only a UTC ISO timestamp, `YYYY-MM-DD`, a finite epoch
94
+ millisecond value, or an existing Date. Date fields and formatting use UTC. This
95
+ avoids host locale and ambiguous date parsing during static builds.
96
+
97
+ Formula evaluation is bounded to 10,000 AST steps and 128 nested expressions per
98
+ evaluation. Exceeding either limit stops deterministically, reports a
99
+ `bases-invalid` diagnostic, and renders the Base error fallback. This prevents
100
+ large or deeply nested higher-order expressions from making a static build
101
+ unbounded; JavaScript callbacks are never executed.
102
+
103
+ ## File metadata
104
+
105
+ `file.size` is the source file's byte size. `file.mtime` and `file.ctime` are
106
+ UTC `Date` values sourced from the filesystem, so they can be used in properties,
107
+ filters, formulas, sorting, grouping, summaries, and higher-order expressions.
108
+ Missing or invalid source metadata evaluates to an empty value rather than being
109
+ derived from rendered Markdown or build time. Date subtraction returns
110
+ milliseconds; a Date can also be offset by a duration such as `"7 days"`.
111
+
112
+ For filesystem content, `file.ctime` uses Node's `birthtime` value, not
113
+ `stat.ctime` (which is a status-change time). Windows normally provides creation
114
+ time. Linux filesystems may not expose a creation time; Node can report a
115
+ filesystem-dependent fallback or no usable value, so portability-sensitive Bases
116
+ should handle an empty `file.ctime`. Cached timestamps retain their UTC instant.
117
+
118
+ ## Incremental builds
119
+
120
+ Bases records the properties read by filters, formulas, columns, sorting, grouping,
121
+ and summaries in the persisted Output Inventory. This applies independently to fenced
122
+ Bases and each referenced `.base` document. A change to one of those properties, to
123
+ file metadata it reads, or to the discoverable candidate set regenerates only the
124
+ Base output that reads it. This includes notes that change from not matching to
125
+ matching a filter. Body-only and unrelated frontmatter edits reuse the Base output.
126
+
127
+ Formula cycles, dynamic property access, and other dependencies that cannot be proven
128
+ statically use a conservative per-Base fallback. The fallback never treats an unknown
129
+ dependency as no dependency. Draft, scheduled, and unlisted entries remain excluded
130
+ from Base rows and are not exposed through cached output.
131
+
132
+ ## Static view accessibility
133
+
134
+ Tables retain column and row-group headers, include an off-screen result count,
135
+ and are wrapped in a keyboard-focusable horizontal scroll region for narrow
136
+ screens. Group labels include their row count; `groupOrder` entries without a
137
+ matching row render an explicit empty group. Card groups use labelled lists,
138
+ and summary values include an off-screen column label. These additions preserve
139
+ the static, no-JavaScript output model.
140
+
141
+ ## Compatibility matrix
142
+
143
+ | Obsidian Base feature | Status | Notes |
144
+ | --- | --- | --- |
145
+ | YAML root, `filters`, `properties`, `formulas`, `summaries`, `views` | Supported | Invalid YAML/specs produce a diagnostic. |
146
+ | Table and cards | Supported | Other view types are not rendered. |
147
+ | AST filters and formulas | Supported subset | See the function list above. |
148
+ | Formula sorting and multiple stable sort keys | Supported | Empty values sort last. |
149
+ | `groupBy` and `groupOrder` | Supported | Formula properties, ordered empty groups, table, and cards are supported. Interactive collapse is not. |
150
+ | Table summaries | Supported subset | Named summaries and Empty, Filled, Unique, Checked, Unchecked, numeric, and date summaries are available. |
151
+ | Card summaries | Out of Scope | Obsidian displays summaries in tables, not cards. |
152
+ | `file.name`, `file.path`, `file.ext`, `file.folder`, `file.tags`, `file.links`, `file.properties`, `file.link` | Partial | Derived from the Markdown manifest; name/path use the `.md` source convention. |
153
+ | `file.size`, `file.mtime`, `file.ctime` | Supported | Byte size, filesystem modification time, and filesystem creation-time equivalent. `ctime` can be unavailable on Linux; it is never mapped from `stat.ctime`, frontmatter, or build time. |
154
+ | Backlinks, embeds | Unsupported | These values are empty. |
155
+ | List `map`, `filter`, and `reduce` | Supported subset | Their expressions use the `value`, `index`, and `acc` scope with a bounded list size. |
156
+ | Deterministic utility, object, date, and file-property functions | Partial | UTC dates, `duration`, collection/object helpers, and `file.hasProperty` are available; functions requiring a vault API or a rendered link are not. |
157
+ | Incremental dependency tracking | Supported | Tracks filter candidates and AST-derived property dependencies; dynamic or cyclic formulas fall back per Base. |
158
+ | Regex, object literals, `file()`, link/image/icon/HTML rendering, `now`, `today`, `random`, and relative dates | Unsupported | Static rendering does not execute JavaScript, depend on build time, or emit unsafe URLs. |
159
+ | Editing, group collapse, and other interactive view controls | Out of Scope | Riebeckite renders static build output. |
160
+
161
+ ## Options and exports
162
+
163
+ `className`, `language`, `limit`, `showFallback`, and `view` retain their existing
164
+ meanings. The package exports `bases`, `basesPlugin`, `remarkBases`, `parseBases`,
165
+ `parseBasesExpression`, `analyzeBasesDependencies`, `evaluateBasesExpression`, `matchesCondition`, and the
166
+ public Bases types.
package/README_ja.md CHANGED
@@ -2,156 +2,158 @@
2
2
 
3
3
  <!-- Generated from docs/docs/plugins/bases.ja.md. Edit the canonical documentation in docs/docs/plugins and run `pnpm docs:sync`. -->
4
4
 
5
- フェンスコードブロック `base` に書いた Obsidian Bases 定義を HTML にレンダリングします。フィルタ・ソート・ビューの組み立てはビルド時にコンテンツマニフェストに対して行われるため、クライアントサイド JavaScript は不要です。
5
+ Obsidian Bases の互換サブセットをビルド時に描画します。`bases()` は fenced
6
+ `base` ブロックと、参照された `.base` ドキュメントを扱います。クライアント側の
7
+ 評価器は含みません。
6
8
 
7
9
  [English](./README.md)
8
10
 
9
- ## 概要
10
-
11
- `bases()` は次のようなフェンスブロックを認識します。
12
-
13
- ````md
14
- ```base
15
- filters:
16
- and:
17
- - file.hasTag("featured")
18
- properties:
19
- file.name:
20
- displayName: Title
21
- file.tags:
22
- displayName: Tags
23
- views:
24
- - type: table
25
- name: Featured
26
- order:
27
- - file.name
28
- - file.tags
29
- limit: 10
30
- ```
31
- ````
32
-
33
- レンダリングにはコンテンツマニフェスト(各ノートの frontmatter・タグ・リンク・パーマリンク)を使います。
34
-
35
- ## 使い方
11
+ ## 設定
36
12
 
37
13
  ```ts
38
- import { defineConfig } from "@riebeckite/core";
39
14
  import { bases } from "@riebeckite/plugin-bases";
40
15
 
41
- export default defineConfig({
42
- // ...
43
- plugins: [bases()],
44
- });
16
+ export default { plugins: [bases()] };
45
17
  ```
46
18
 
47
- ## ブロックの構文
48
-
49
- ブロック本体は Obsidian Base の YAML ドキュメントです。
50
-
51
- | フィールド | 型 | 説明 |
52
- | ---------- | -- | ---- |
53
- | `filters` | 式 \| リスト \| オブジェクト | 全ビューに適用するトップレベルフィルタ(後述) |
54
- | `properties` | オブジェクト | プロパティ ID → 表示名(または `{ displayName }`) |
55
- | `views` | オブジェクト[] | 1 つ以上のビュー |
56
-
57
- ### ビュー
58
-
59
- | フィールド | 型 | 説明 |
60
- | ---------- | -- | ---- |
61
- | `type` | `"table"` \| `"cards"` | 出力形式。既定は `table` |
62
- | `name` | string | ビュー上部に表示する任意のラベル |
63
- | `filters` | フィルタ | トップレベルフィルタに AND で合成する追加フィルタ |
64
- | `order` | string \| string[] | 列(プロパティ ID)と表示順 |
65
- | `columns` | string \| string[] | `order` の別名 |
66
- | `sort` | オブジェクト \| オブジェクト[] \| string | ソートキー(後述) |
67
- | `limit` | number | このビューの行数上限。`limit` オプション以下に制限される |
68
-
69
- `sort` は Core 形式 `{ field, order }`、Obsidian 形式 `{ property, direction }`、短縮文字列(`"-file.name"` で降順)のいずれかを受け付けます。ビューに `order` / `columns` がない場合、列は `properties` のキー(定義順)、それもなければ `["file.name", "file.tags"]` になります。
19
+ ## `.base` ドキュメントと公開範囲
70
20
 
71
- ### フィルタの文法
21
+ ルーティング可能な Markdown ノートから `.base` をリンクすると、拡張子を除いた
22
+ パスに PageType ページが作られます。たとえば `![views/Books.base](https://github.com/Rerurate514/riebeckite/blob/main/docs/docs/views/Books.base.ja.md)` は
23
+ `/views/Books` を作ります。既存の PageType API を使うため、独自のルーティングは
24
+ 追加しません。
72
25
 
73
- フィルタは式文字列、式のリスト(AND として扱う)、または `and` / `or` / `not` を持つオブジェクトです。`and` と `or` はリストを取り、`not` は式またはリスト(リストは AND でまとめてから否定)を取ります。プロパティ名をキーにした素のオブジェクトは等価比較として扱います。
26
+ ドキュメントページの検出には Core の `publicEntries` を使うため、公開または限定公開
27
+ ノートから参照した Base は明示的に公開できます。Base の行の検索には
28
+ `discoverableEntries` を使います。自動一覧には公開ノートだけが入り、限定公開ノートは
29
+ URL を直接指定した場合だけアクセスできます。下書きと公開予定ノートはいずれからも
30
+ 除外します。非公開のコンテンツからしか参照されない Base は公開しません。既存の
31
+ Markdown ページまたは公開リダイレクトと競合した場合はそちらを優先し、Base ページを
32
+ スキップして `bases-invalid` の警告を出します。
74
33
 
75
- | 式 | 説明 |
76
- | -- | ---- |
77
- | `file.hasTag("x")` | タグ `x`(またはサブタグ `x/...`)を持つ。大文字小文字は区別しない |
78
- | `file.inFolder("x")` | スラグが `x` に一致するか `x/` で始まる |
79
- | `file.hasLink("x")` | `x` へのリンクがある(解決済みスラグ・生のターゲット・ファイル名で照合) |
80
- | `file.name` / `file.title` | ノートのタイトル |
81
- | `file.path` / `file.slug` | スラグ |
82
- | `file.folder` | スラグの親フォルダ |
83
- | `file.link` / `file.permalink` | パーマリンク |
84
- | `file.tags` | タグ |
85
- | `note.key` / `key` | frontmatter の値 |
86
-
87
- 比較演算子は `==`、`!=`、`>`、`<`、`>=`、`<=`、`contains` です。文字列比較は大文字小文字を区別せず、`contains` は配列の要素または文字列の部分一致を調べます。スカラーのリストは AND として扱います。
34
+ ## 例
88
35
 
89
36
  ```yaml
90
- filters:
91
- and:
92
- - file.hasTag("featured")
93
- - or:
94
- - note.status == "published"
95
- - note.status == "review"
96
- - not:
97
- - file.hasTag("draft")
37
+ filters: note.status == "published" && !file.hasTag("hidden")
38
+ formulas:
39
+ label: 'note.author.name.upper() + " / " + note.score'
40
+ summaries:
41
+ total: values.reduce(acc + value, 0)
42
+ properties:
43
+ file.name: File
44
+ formula.label: Label
98
45
  views:
99
46
  - type: table
100
- name: Featured
101
- order: [file.name, note.status]
102
- sort:
103
- - property: file.name
104
- direction: ASC
105
- limit: 20
106
- ```
107
-
108
- ## オプション
109
-
110
- | オプション | 型 | 既定値 | 説明 |
111
- | ---------- | -- | ------ | ---- |
112
- | `className` | `string` | `"rb-bases"` | ルート CSS クラス |
113
- | `language` | `string` | `"base"` | 対象とするフェンス言語 |
114
- | `limit` | `number` | `100` | 全ビューに適用する行数上限 |
115
- | `showFallback` | `boolean` | `true` | 生の Base 定義を `<details>` のフォールバックに表示する |
116
- | `view` | `string` | なし | Base に複数ビューがあるとき、指定名のビューだけをレンダリングする |
117
-
118
- ## 出力 HTML / CSS フック
119
-
120
- ```html
121
- <div class="rb-bases" data-bases data-bases-view="table">
122
- <section class="rb-bases__view" data-bases-view="table">
123
- <h3 class="rb-bases__view-name">Featured</h3>
124
- <table class="rb-bases__table"> ... </table>
125
- </section>
126
- <details class="rb-bases__fallback"> ... </details>
127
- </div>
47
+ name: Books
48
+ order: [file.name, formula.label]
49
+ sort: [{ property: formula.label, direction: DESC }]
50
+ groupBy: { property: note.status, direction: ASC }
51
+ summaries: { formula.label: total }
52
+ - type: cards
53
+ name: Cards
54
+ order: [file.name, formula.label]
128
55
  ```
129
56
 
130
- 安定クラス: `rb-bases`、`rb-bases__view`、`rb-bases__view-name`、`rb-bases__table`、`rb-bases__heading`、`rb-bases__cell`、`rb-bases__row`、`rb-bases__link`、`rb-bases__tags`、`rb-bases__tag`、`rb-bases__cards`、`rb-bases__card`、`rb-bases__card-title`、`rb-bases__fields`、`rb-bases__field`、`rb-bases__field-label`、`rb-bases__field-value`、`rb-bases__empty`、`rb-bases__fallback`、`rb-bases--error`。安定属性: `data-bases`、`data-bases-view`。
131
-
132
- ## 診断
133
-
134
- YAML として不正なブロック、未対応のフィルタ式やビュー形状を使ったブロックはコードブロックのまま残し、`source: "@riebeckite/plugin-bases"` を付けて `file.message(...)` で報告します。
135
-
136
- ## 制限事項
137
-
138
- これは Obsidian Bases の MVP サブセットです。
139
-
140
- - レンダリングできるのは `table` と `cards` の 2 種類のビューだけです。
141
- - インラインの論理演算子(`&&`、`||`、`!`)は未対応です。`and` / `or` / `not` の YAML 構造を使ってください。
142
- - `if()` / `filter()` などの Base フォーミュラ関数は未対応です。
143
- - ネストしたプロパティパスと `file.mtime` / `file.ctime` は `date` にマップされます。
144
- - プロパティ同士の比較は未対応で、右辺はリテラルです。
145
- - 結果はビルド時に確定します。参照先ノートの変更に応じてホストノートだけを再ビルドするのは今後の課題で、フルビルドでは常に正しく再計算されます。
146
-
147
- ## エクスポート
148
-
149
- - `bases(options?)` — プラグインファクトリ(別名: `basesPlugin`)
150
- - `remarkBases(options?)` — 単体で使える remark トランスフォーム(`options.language` でフェンス言語を選択)
151
- - `parseBases(document)` — パース済み YAML Base ドキュメントをスペックにコンパイル
152
- - `matchesCondition(condition, entry)` — 条件評価関数
153
- - 型: `BasesOptions`、`BasesSpec`、`BasesView`、`BasesViewType`、`BasesCondition`、`BasesValueRef`、`BasesBuiltinValue`、`BasesOperator`、`BasesLiteral`
154
-
155
- ## 関連
156
-
157
- - [プラグインガイド](https://github.com/Rerurate514/riebeckite/blob/main/docs/docs/reference/plugin-api.ja.md)
57
+ 同じ YAML を fenced `base` ブロックまたは `.base` ファイルに書けます。トップ
58
+ レベルとビューごとの `filters` は AND で結合します。Table と cards はビルド時に
59
+ 描画し、HTML に出す動的な値はすべてエスケープします。
60
+
61
+ ## 公式構文の監査
62
+
63
+ Obsidian の [Bases 構文](https://help.obsidian.md/bases/syntax) と
64
+ [ビュー](https://help.obsidian.md/bases/views) の YAML 形式を確認し、決定的な静的出力に
65
+ 範囲を限定して対応状況を整理しています。
66
+
67
+ | 構文またはビュー機能 | 状態 | 静的出力での扱い |
68
+ | --- | --- | --- |
69
+ | ルートの `filters`、`formulas`、`properties`、`summaries`、`views` | 対応 | 再帰的な `and`/`or`/`not` filter と `displayName` を受け付けます。 |
70
+ | ビューの `type`、`name`、`limit`、`filters`、`order`、`sort`、`groupBy`、`groupOrder`、`summaries` | 対応 | `groupOrder` は排他的です。空リストはすべてのグループを隠し、存在しない値を列挙すると空グループを作ります。 |
71
+ | Table と cards のレイアウト | 対応 | 実行時の評価器を持たないセマンティック HTML を生成します。 |
72
+ | List、kanban、map のレイアウト | 未対応 | 対話的・空間的な動作はこの静的レンダラーでは表現できません。 |
73
+ | 編集、プロパティメニュー、列幅変更、ドラッグ&ドロップ、折りたたみ操作 | 対象外 | Bases はサイトのビルド時に描画します。 |
74
+
75
+ ## 式と Formula のサブセット
76
+
77
+ 式は AST に構文解析して直接評価します。`eval`、`Function`、任意の JavaScript 実行は
78
+ 使いません。リテラル、配列、ネストしたメンバー・インデックス参照、`!`、単項 `-`、
79
+ 算術、比較、`&&`、`||`、括弧、プロパティ同士の比較、`formula.name` 参照に対応します。
80
+ Formula の循環参照は空の値になります。
81
+
82
+ 対応する関数は `if`、`list`、`length`、`number`、`min`、`max`、`date`、`duration`、
83
+ `isTruthy`、`isType`、`toString`、`escapeHTML`、文字列の `lower`、`upper`、`title`、
84
+ `contains`、`startsWith`、`endsWith`、`trim`、`split`、`replace`、`reverse`、`repeat`、
85
+ `slice`、`isEmpty`、リストの `contains`、`containsAll`、`containsAny`、`join`、`unique`、
86
+ `flat`、`sort`、`reverse`、`slice`、`isEmpty`、`mean`、`sum`、`min`、`max`、`map`、
87
+ `filter`、`reduce`、数値の `round`、`floor`、`ceil`、`abs`、`toFixed`、オブジェクトの
88
+ `isEmpty`、`keys`、`values`、UTC の日付フィールド、`date`、`time`、`format`、
89
+ `file.hasTag`、`file.hasLink`、`file.inFolder`、`file.hasProperty` です。
90
+
91
+ `date()` は UTC の ISO タイムスタンプ、`YYYY-MM-DD`、有限の epoch ミリ秒値、または
92
+ 既存の Date だけを受け付けます。日付フィールドとフォーマットは UTC を使うため、静的
93
+ ビルドでホストのロケールや曖昧な日付構文に依存しません。
94
+
95
+ Formula の評価は、1回につき AST の 10,000 ステップとネストした式の 128 段階までです。
96
+ いずれかを超えると決定的に停止し、`bases-invalid` 診断を出して Base のエラー表示に
97
+ 切り替えます。大きな高階式や深い式によって静的ビルドが無制限に実行されることを防ぎ、
98
+ JavaScript のコールバックは実行しません。
99
+
100
+ ## ファイルメタデータ
101
+
102
+ `file.size` はソースファイルのバイト数です。`file.mtime` と `file.ctime` は
103
+ ファイルシステムから得る UTC の `Date` 値で、プロパティ、filter、Formula、ソート、
104
+ グループ、集計、高階式で使えます。ソースのメタデータが欠落または不正な場合は、描画後の
105
+ Markdown やビルド時刻から補わず、空の値として扱います。日付どうしの減算はミリ秒になり、
106
+ `"7 days"` のような duration による Date の加減算もできます。
107
+
108
+ ファイルシステムのコンテンツでは、`file.ctime` に Node の `birthtime` を使います。
109
+ status-change time である `stat.ctime` は使いません。Windows では通常、作成時刻を取得
110
+ できます。Linux のファイルシステムは作成時刻を持たないことがあり、Node が
111
+ ファイルシステム依存の代替値を返すか、利用できる値がない場合があります。移植性が必要な
112
+ Base では空の `file.ctime` を扱ってください。キャッシュした時刻は UTC の瞬間を保ちます。
113
+
114
+ ## 増分ビルド
115
+
116
+ Bases は、filter、formula、column、sort、group、summary が読むプロパティを永続 Output
117
+ Inventory に記録します。これは fenced Base と参照された各 `.base` ドキュメントに個別に適用されます。
118
+ これらのプロパティ、参照するファイルメタデータ、または公開候補集合が変わった場合だけ、その値を読む Base 出力を
119
+ 再生成します。filter 不一致から一致への変更も検出します。本文だけの編集と無関係な frontmatter 編集では Base 出力を
120
+ 再利用します。
121
+
122
+ formula の循環、動的なプロパティ参照など、静的に証明できない依存関係では Base 単位で保守的に再生成します。
123
+ 不明な依存関係を依存なしとして扱うことはありません。draft、scheduled、unlisted のエントリは Base の行から除外され、
124
+ キャッシュ出力からも公開されません。
125
+
126
+ ## 静的ビューのアクセシビリティ
127
+
128
+ Table は列と行グループの見出しを維持し、画面読み上げ用の件数を持ちます。狭い画面では
129
+ キーボードでフォーカスできる横スクロール領域に収めます。グループ名には行数を示し、
130
+ `groupOrder` にあるが一致する行がない値は空グループとして明示します。Card のグループは
131
+ ラベル付きリストとし、集計値には画面読み上げ用の列名を加えます。いずれも JavaScript を
132
+ 使わない静的出力のままです。
133
+
134
+ ## 互換性マトリクス
135
+
136
+ | Obsidian Base の機能 | 状態 | 備考 |
137
+ | --- | --- | --- |
138
+ | YAML ルート、`filters`、`properties`、`formulas`、`summaries`、`views` | 対応 | YAML または仕様が不正な場合は診断を出します。 |
139
+ | Table と cards | 対応 | ほかのビュー種別は描画しません。 |
140
+ | AST の filter と Formula | 一部対応 | 対応関数は上記のとおりです。 |
141
+ | Formula によるソートと複数の安定ソートキー | 対応 | 空の値は末尾に並びます。 |
142
+ | `groupBy` と `groupOrder` | 対応 | Formula プロパティ、順序付きの空グループ、Table、cards に対応します。対話的な折りたたみは対象外です。 |
143
+ | Table の集計 | 一部対応 | 名前付き集計、Empty、Filled、Unique、Checked、Unchecked、数値、日付の集計を使えます。 |
144
+ | Cards の集計 | 対象外 | Obsidian は集計を cards ではなく Table に表示します。 |
145
+ | `file.name`、`file.path`、`file.ext`、`file.folder`、`file.tags`、`file.links`、`file.properties`、`file.link` | 一部対応 | Markdown マニフェストから導出します。name/path は `.md` のソース規則を使います。 |
146
+ | `file.size`、`file.mtime`、`file.ctime` | 対応 | バイト数、ファイルシステムの更新時刻、作成時刻相当を使います。Linux では `ctime` が利用できないことがあります。`stat.ctime`、frontmatter、ビルド時刻へは置き換えません。 |
147
+ | Backlinks、embeds | 未対応 | これらの値は空になります。 |
148
+ | リストの `map`、`filter`、`reduce` | 一部対応 | `value`、`index`、`acc` スコープの式を使い、リスト長には上限があります。 |
149
+ | 決定的な utility、object、date、file-property 関数 | 一部対応 | UTC 日付、`duration`、コレクション/object ヘルパー、`file.hasProperty` を使えます。Vault API や描画済みリンクを必要とする関数は使えません。 |
150
+ | 増分依存追跡 | 対応 | filter 候補集合と AST から得たプロパティ依存を追跡し、動的・循環 formula は Base 単位でフォールバックします。 |
151
+ | 正規表現、オブジェクトリテラル、`file()`、link/image/icon/HTML の描画、`now`、`today`、`random`、相対日付 | 未対応 | JavaScript を実行せず、ビルド時刻に依存せず、安全でない URL を出力しません。 |
152
+ | 編集、グループの折りたたみなどの対話的なビュー操作 | 対象外 | Riebeckite は静的なビルド出力を描画します。 |
153
+
154
+ ## オプションとエクスポート
155
+
156
+ `className`、`language`、`limit`、`showFallback`、`view` の意味は従来どおりです。
157
+ パッケージは `bases`、`basesPlugin`、`remarkBases`、`parseBases`、
158
+ `parseBasesExpression`、`analyzeBasesDependencies`、`evaluateBasesExpression`、`matchesCondition`、公開 Bases 型を
159
+ エクスポートします。