* Fix extended task state widget click behavior in widgets
* Add mouse click handler on extended task state span to prevent
CodeMirror from moving selection to widget source on normal click
* Let `Alt+Click` pass to parent div for the "cursor to source" behavior
matching simple checkbox `Alt+Click` behavior
* Skip state cycling on `Alt+Click`
Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>
* Prevent task state corruption from concurrent cycling on mobile
On mobile, rapid taps on an enhanced task state (e.g. `[PLANNED]`) could
fire multiple events before the first `taskCycleAtPos` completed. Add
a reentrancy guard to `taskCycleAtPos` so concurrent calls are dropped.
Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>
---------
Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>
* Fix extended task rendering in widgets
This patch addresses several issues.
1. Extended tasks like `[PLANNED]` or `[TODO]` were not rendering
correctly when generated via widgets. The HTML renderer was producing
plain text without brackets or proper styling, while simple `[x]`
tasks worked fine. The fix produces the same DOM structure as
CodeMirror producing coherent styling everywhere.
2. Widget checkboxes are not interactive now. Since widget tasks have no
backing state handler clicking them only caused a misleading visual
toggle with no effect. The `disabled` attribute prevents this
confusion and the dimmed appearanceit signals to the user that the
checkbox is read-only in this context which is the truth.
To see it in action try the following Markdown snippet in SilverBullet:
```
- [x] #foo [att: i]
- [PLANNED] bar #bar [att: i]
${'- [x] #foo [att: i]\n- [PLANNED] bar #bar [att: i]'}
```
Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>
* Revert and just prevent widget checkboxes from toggling visually
Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>
* Support custom task states in widgets and indexer
Custom task states like `[PLANNED]` or `[IN PROGRESS]` now render
correctly in *widgets*, matching the same DOM structure as CodeMirror
uses in the editor. Widget-rendered tasks that reference a real task
(via `page@pos`) are fully interactive — clicking an extended state
cycles it through the configured states and updates the source task.
Tasks without a reference are disabled to prevent misleading visual
feedback.
The task indexer now respects the `done` flag on custom states defined
via `taskState.define`, so queries like `where not t.done` correctly
exclude tasks in states marked as done. Previously only the built-in
simple tasks (`- [x]` or `- [X]`) states were treated as completed. The
`Task: Remove Completed` command already handled custom done states and
continues to work unchanged.
State cycling now preserves the definition order from `taskState.define`
calls instead of sorting alphabetically. A new `order` field allows
explicit control over the cycle sequence. Without it, states cycle in
definition order. With it, states are sorted by the `order` field value.
This gives users full control over the progression, for example:
PLANNED --> IN PROGRESS --> FINISHED
The `taskState.define` API now validates its input against a schema:
`name` (string, required), `done` (boolean, optional), and `order`
(number, optional).
The `expandMarkdown` no longer injects "fake" `page@pos` references into
tasks rendered via `widget.markdownBlock` or `widget.new` which was
causing broken links and unwanted interactivity on static task content.
The `task:stateChange` event is dispatched when toggling tasks from
widgets, ensuring Lua listeners (such as some custom completed timestamp
management) fire correctly regardless of where the toggle originates.
Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>
---------
Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>
Based on https://www.markdownlang.com/extended/footnotes.html
* Both "official" [^1] and [^1]: def
* And inline ^[My foot note]
Features:
* Properly parsed in markdown parser
* Syntax highlighting
* Live Preview to ... when on-hover preview of content, on-click moves
cursor to definition
* Reference completion
* Invalid references are marked
The table style is determined by the header row. After normalizing the
header (filling empty cells between consecutive delimiters), extract
two properties: the column count and whether the header starts with
a delimiter.
For each data row, normalization proceeds in three steps. First, fill in
empty cells between consecutive delimiters (this handles empty cells in
the middle of a row). Second, if the header has no leading delimiter but
the row does, insert an empty cell after the row's leading delimiter (this
corrects the one-position shift caused by the row having a leading pipe
that the header lacks. Third, if the row has fewer cells than the header
column count, pad with empty cells at the end (this handles rows that
are shorter than the header because trailing pipes or cells were
omitted).
The same normalization is applied both in the renderer and the indexer.
Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>
The Markdown parser omits `TableCell` nodes for empty cells, so
`collectNodesOfType` returns fewer cells than columns.
The indexer mapped cells to headers by array index, causing all cells
after an empty one to shift left.
The HTML renderer already solved this: its `TableRow` case walks the
children and injects empty `TableCell` nodes between consecutive
`TableDelimiter` nodes with no cell in between.
This patch extracts that same normalization logic into a reusable
`normalizeTableRow` helper and applies it to each row before collecting
cells.
The original index-based cell-to-header mapping then works correctly
without any positional arithmetic. I feel like this is more elegant
solution to the issue.
Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>
For example, with the following table:
```markdown
| a | b | c |
| --- | --- | --- |
| 1 | | 3 |
| 1 | 2 | 3 |
| a | b | c |
| a | b | |
| | b | c |
| x | | |
| | | z |
```
the following query results in dataset with shifted columns
when cells are empty:
```lua
from
index.tag 'table'
where
page == 'test'
order by
pos asc
select {
a, b, c
}
```
This is now fixed and gives correct results:
|0 |1 |2 |
|--|--|--|
|1 | |3 |
|1 |2 |3 |
|a |b |c |
|a |b | |
| |b |c |
|x | | |
| | |z |
Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>
* Trim user input from prompts where appropriate
* Run formatter
* Use "page title" language instead of "page name" in notifications.
Existing language in prompt asks for a "page title".
* Use const for prefix inputs as they are never trimmed
- Introduced a new `validate` callback for `tag.define`
- Added `index.validateObjects` API to validate and transform objects before indexing.
- Updated relevant documentation and examples to reflect these changes.
* Modified renamePage function in refactor.ts to ensure navigation to the new page occurs after the index queue is processed, so that linked mentions reflect updated data once arriving there