generated from obsidianmd/obsidian-sample-plugin
-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(view:codeblock:markmap): Markmap codeblocks alpha
- Loading branch information
1 parent
60f682c
commit 328441b
Showing
4 changed files
with
174 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<script lang="ts"> | ||
import type BreadcrumbsPlugin from "src/main"; | ||
import { wrap_in_codeblock } from "src/utils/strings"; | ||
import RenderMarkdown from "../obsidian/RenderMarkdown.svelte"; | ||
/** The markmap string, **not** wrapped in a codeblock */ | ||
export let markmap: string; | ||
export let plugin: BreadcrumbsPlugin; | ||
export let source_path: string | undefined = undefined; | ||
</script> | ||
|
||
<RenderMarkdown | ||
bind:plugin | ||
{source_path} | ||
markdown={wrap_in_codeblock(markmap, "markmap")} | ||
/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
<script lang="ts"> | ||
import type { ICodeblock } from "src/codeblocks/schema"; | ||
import { Traverse, type EdgeTree } from "src/graph/traverse"; | ||
import { | ||
get_edge_sorter, | ||
has_edge_attrs, | ||
type EdgeAttrFilters, | ||
} from "src/graph/utils"; | ||
import type { BreadcrumbsError } from "src/interfaces/graph"; | ||
import type BreadcrumbsPlugin from "src/main"; | ||
import { active_file_store } from "src/stores/active_file"; | ||
import { Markmap } from "src/utils/markmap"; | ||
import { onMount } from "svelte"; | ||
import MarkmapDiagram from "../Markmap/MarkmapDiagram.svelte"; | ||
import CopyToClipboardButton from "../button/CopyToClipboardButton.svelte"; | ||
import CodeblockErrors from "./CodeblockErrors.svelte"; | ||
export let plugin: BreadcrumbsPlugin; | ||
export let options: ICodeblock["Options"]; | ||
export let errors: BreadcrumbsError[]; | ||
export let file_path: string; | ||
const sort = get_edge_sorter( | ||
// @ts-expect-error: ts(2345) | ||
options.sort, | ||
plugin.graph, | ||
); | ||
const { show_node_options } = plugin.settings.views.codeblocks; | ||
let tree: EdgeTree[] = []; | ||
// if the file_path is an empty string, so the code block is not rendered inside note, we fall back to the active file store | ||
$: source_path = file_path | ||
? file_path | ||
: $active_file_store | ||
? $active_file_store.path | ||
: ""; | ||
// this is an exposed function that we can call from the outside to update the codeblock | ||
export const update = () => { | ||
tree = Traverse.sort_edge_tree(get_tree(), sort); | ||
}; | ||
const base_traversal = (attr: EdgeAttrFilters) => | ||
Traverse.build_tree( | ||
plugin.graph, | ||
source_path, | ||
{ max_depth: options.depth[1] }, | ||
(e) => | ||
has_edge_attrs(e, { | ||
...attr, | ||
$or_target_ids: options["dataview-from-paths"], | ||
}), | ||
); | ||
const edge_field_labels = | ||
options.fields ?? plugin.settings.edge_fields.map((f) => f.label); | ||
const get_tree = () => { | ||
if (source_path && plugin.graph.hasNode(source_path)) { | ||
const traversal = options["merge-fields"] | ||
? base_traversal({ $or_fields: options.fields }) | ||
: edge_field_labels.flatMap((field) => | ||
base_traversal({ field }), | ||
); | ||
// NOTE: The flattening is done here so that: | ||
// - We can use NestedEdgeList for both modes | ||
// - ListIndex builds from an EdgeTree[] as well | ||
return options.flat | ||
? Traverse.flatten_tree(traversal).map((item) => ({ | ||
depth: 0, | ||
children: [], | ||
edge: item.edge, | ||
})) | ||
: traversal; | ||
} else { | ||
return []; | ||
} | ||
}; | ||
$: markmap = Markmap.from_tree(tree, { | ||
show_node_options, | ||
show_attributes: options?.["show-attributes"], | ||
}); | ||
onMount(update); | ||
</script> | ||
|
||
<div class="BC-codeblock-markmap"> | ||
<CodeblockErrors {plugin} {errors} /> | ||
|
||
{#if options.title} | ||
<h3 class="BC-codeblock-markmap-title"> | ||
{options.title} | ||
</h3> | ||
{/if} | ||
|
||
{#if tree.length} | ||
<div class="relative"> | ||
<div class="absolute left-2 top-2 flex"> | ||
<CopyToClipboardButton | ||
text={markmap} | ||
cls="clickable-icon nav-action-button" | ||
/> | ||
</div> | ||
|
||
<MarkmapDiagram {plugin} {markmap} {source_path} /> | ||
</div> | ||
{:else} | ||
<!-- TODO(HELP-MSG) --> | ||
<p class="search-empty-state">No paths found.</p> | ||
{/if} | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import type { EdgeAttribute } from "src/graph/MyMultiGraph"; | ||
import type { EdgeTree } from "src/graph/traverse"; | ||
import type { ShowNodeOptions } from "src/interfaces/settings"; | ||
import { Links } from "./links"; | ||
import { untyped_pick } from "./objects"; | ||
import { Paths } from "./paths"; | ||
import { url_search_params } from "./url"; | ||
|
||
type Options = { | ||
show_attributes?: EdgeAttribute[]; | ||
show_node_options?: ShowNodeOptions; | ||
}; | ||
|
||
const from_tree = (tree: EdgeTree[], options?: Options) => { | ||
let markmap = ""; | ||
|
||
tree.forEach((item) => { | ||
const hashes = "#".repeat(item.depth); | ||
|
||
const link = Links.ify( | ||
item.edge.target_id, | ||
Paths.show(item.edge.target_id, options?.show_node_options), | ||
{ link_kind: "markdown" }, | ||
); | ||
|
||
const attr = options?.show_attributes | ||
? ` (${url_search_params(untyped_pick(item.edge.attr, options.show_attributes), { trim_lone_param: true })})` | ||
: ""; | ||
|
||
markmap += `${hashes} ${link}${attr}\n`; | ||
|
||
if (item.children.length) { | ||
markmap += from_tree(item.children, options); | ||
} | ||
}); | ||
|
||
return markmap; | ||
}; | ||
|
||
export const Markmap = { | ||
from_tree, | ||
}; |