mirror of
https://github.com/foambubble/foam.git
synced 2026-01-09 14:08:13 -05:00
Proposal and basic feature to include notes into a note (#741)
* Add the functionality to include notes in a note * Add proposal of embedding * Add tests for including notes * Add documentation for inclusion feature
This commit is contained in:
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@@ -12,6 +12,7 @@
|
||||
},
|
||||
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
|
||||
"typescript.tsc.autoDetect": "off",
|
||||
"foam.edit.linkReferenceDefinitions": "withExtensions",
|
||||
"foam.files.ignore": [
|
||||
"**/.vscode/**/*",
|
||||
"**/_layouts/**/*",
|
||||
|
||||
@@ -13,3 +13,19 @@ For example, to load a stylesheet called `Style.css`, we can update `settings.js
|
||||
"markdown.styles": ["Style.css"]
|
||||
}
|
||||
```
|
||||
|
||||
## Foam elements
|
||||
|
||||
### Foam note & placeholder links
|
||||
|
||||
It is possible to custom style the links to a note or placeholder. The links are an `<a>` tag. For notes use the class `foam-note-link`, for placeholders use `foam-placeholder-link`.
|
||||
|
||||
### Cyclic inclusion warnings
|
||||
|
||||
Foams offers the functionality to include other notes in your note. This will be displayed in the preview tab. Foam recognises a cyclic inclusion of notes and will display a warning when detected. The following html is used and can be custom styled using the class `foam-cyclic-link-warning`.
|
||||
|
||||
```html
|
||||
<div class="foam-cyclic-link-warning">
|
||||
Cyclic link detected for wikilink: ${wikilink}
|
||||
</div>
|
||||
```
|
||||
20
docs/features/including-notes.md
Normal file
20
docs/features/including-notes.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Including notes in a note
|
||||
|
||||
In some situations it might be useful to include the content of another note in your current note. Foam supports this displaying within the vscode environment. Note, this does not work out-of-the-box for your publishing solutions.
|
||||
|
||||
## Including a note
|
||||
|
||||
Including a note can be done by adding an `!` before a wikilink defintion. For example `![[wikilink]]`.
|
||||
|
||||
## Custom styling
|
||||
|
||||
Displaying the inclusion of notes allows for some custom styling, see [[custom-markdown-preview-styles]]
|
||||
|
||||
## Future possibilities
|
||||
|
||||
Work on this feature is evolving and progressing. See the [[inclusion-of-notes]] proposal for the current discussion.
|
||||
|
||||
[//begin]: # "Autogenerated link references for markdown compatibility"
|
||||
[custom-markdown-preview-styles]: custom-markdown-preview-styles.md "Custom Markdown Preview Styles"
|
||||
[inclusion-of-notes]: ../proposals/inclusion-of-notes.md "Inclusion of notes Proposal "
|
||||
[//end]: # "Autogenerated link references"
|
||||
48
docs/proposals/inclusion-of-notes.md
Normal file
48
docs/proposals/inclusion-of-notes.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Inclusion of notes Proposal <!-- omit in TOC -->
|
||||
|
||||
Currently it is not possible within Foam to include other notes into a note. Next to including a full note it could be interesting to add functionalities that allow for greater flexibility. This proposal discusses some functionalities around inclusion of notes.
|
||||
|
||||
**IMPORTANT: This design is merely a proposal of a design that could be implemented. It DOES NOT represent a commitment by `Foam` developers to implement the features outlined in this document. This document is merely a mechanism to facilitate discussion of a possible future direction for `Foam`.**
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [New features](#new-features)
|
||||
- [Including a note](#including-a-note)
|
||||
- [Include a section of a note](#include-a-section-of-a-note)
|
||||
- [Include an attribute of a file (note property or frontmatter)](#include-an-attribute-of-a-file-note-property-or-frontmatter)
|
||||
|
||||
## Introduction
|
||||
|
||||
Initial work and thought on including a note was ignited by issue [#652](https://github.com/foambubble/foam/issues/652). Requested by a user was a likewise functionality as offered in Obsidian. This was simply the ability to include a note.
|
||||
|
||||
Whilst researching digital gardening for my own setup, I came across an in-depth overview by [Maggie Appleton](https://maggieappleton.com/roam-garden). Showing examples of her personal Roam Research I see valuable possibilites to connect more information, if we would add additional functionalities to the possibility of including a note. This proposal displays these possible functionalities and markup.
|
||||
|
||||
## New features
|
||||
|
||||
### Including a note
|
||||
|
||||
The minimal functionality is the ability to fully include a note. Markup used in Obsidian for this is `![[wikilink]]`. For Foam I would suggest to follow this syntax. Benefits being:
|
||||
|
||||
- Adds minimal amount of knowledge required as syntax is based on the syntax of creating a wikilink.
|
||||
- Makes the auto-complete work ouf-of-the-box, without any additional code and listeners required.
|
||||
|
||||
**Important**. A risk exists that a loop of including the same notes arises. E.g. Note A includes note B which includes note A. This needs to be prevented by the implementation and made visible to the user.
|
||||
|
||||
### Include a section of a note
|
||||
|
||||
It could be interesting to only include a section of a note instead of the entire note. In order to do so thse user should be able to use the following syntax:
|
||||
|
||||
`![[wikilink#section-b]]`
|
||||
|
||||
As a result it will include the section title + section content until the next section *or* end of file.
|
||||
|
||||
### Include an attribute of a file (note property or frontmatter)
|
||||
|
||||
As a user I could be interested in collecting the value of any given proeprty for a note. For example, I might want to include the tags as defined in the frontmatter of note A. This should be possible via the syntax:
|
||||
|
||||
`![[wikilink:<property>]]`
|
||||
|
||||
The property value should be lookedup by foam defined properties, e.g. title, **or** any property defined in the frontmatter of a note.
|
||||
|
||||
So, the example of including the tags of a note should be:
|
||||
|
||||
`![[wikilink:tags]]`
|
||||
@@ -56,6 +56,7 @@ A #recipe is a guide, tip or strategy for getting the most out of your Foam work
|
||||
- _More..._
|
||||
- VS Code Advanced Features [[todo]] [[good-first-task]]
|
||||
- Focus with Zen Mode
|
||||
- Display content of other notes in the preview tab by [[including-notes]]
|
||||
|
||||
## Version control
|
||||
|
||||
@@ -125,6 +126,7 @@ _See [[contribution-guide]] and [[how-to-write-recipes]]._
|
||||
[add-images-to-notes]: add-images-to-notes.md "Add images to your notes"
|
||||
[shows-image-preview-on-hover]: shows-image-preview-on-hover.md "Shows Image Preview on Hover"
|
||||
[good-first-task]: ../dev/good-first-task.md "Good First Task"
|
||||
[including-notes]: ../features/including-notes.md "Including notes in a note"
|
||||
[git-integration]: ../features/git-integration.md "Git Integration"
|
||||
[write-your-notes-in-github-gist]: write-your-notes-in-github-gist.md "Write your notes in GitHub Gist"
|
||||
[publish-to-github-pages]: ../publishing/publish-to-github-pages.md "GitHub Pages"
|
||||
|
||||
@@ -4,6 +4,7 @@ import { createTestNote } from '../test/test-utils';
|
||||
import {
|
||||
markdownItWithFoamLinks,
|
||||
markdownItWithFoamTags,
|
||||
markdownItWithNoteInclusion,
|
||||
} from './preview-navigation';
|
||||
|
||||
describe('Link generation in preview', () => {
|
||||
@@ -50,3 +51,55 @@ describe('Stylable tag generation in preview', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Displaying included notes in preview', () => {
|
||||
const noteA = createTestNote({
|
||||
uri: 'note-a.md',
|
||||
text: 'This is the text of note A',
|
||||
});
|
||||
const noteC = createTestNote({
|
||||
uri: 'note-c.md',
|
||||
text: 'This is the text of note C which includes ![[note-d]]',
|
||||
});
|
||||
const noteD = createTestNote({
|
||||
uri: 'note-d.md',
|
||||
text: 'This is the text of note D which includes ![[note-c]]',
|
||||
});
|
||||
const ws = new FoamWorkspace()
|
||||
.set(noteA)
|
||||
.set(noteC)
|
||||
.set(noteD);
|
||||
const md = markdownItWithNoteInclusion(MarkdownIt(), ws);
|
||||
|
||||
it('renders an included note', () => {
|
||||
expect(
|
||||
md.render(`This is the root node.
|
||||
|
||||
![[note-a]]`)
|
||||
).toMatch(
|
||||
`<p>This is the root node.</p>
|
||||
<p><p>This is the text of note A</p>
|
||||
</p>`
|
||||
);
|
||||
});
|
||||
|
||||
it('displays the syntax when a note is not found', () => {
|
||||
expect(
|
||||
md.render(`This is the root node.
|
||||
![[note-b]]`)
|
||||
).toMatch(
|
||||
`<p>This is the root node.
|
||||
![[note-b]]</p>
|
||||
`
|
||||
);
|
||||
});
|
||||
|
||||
it('displays a warning in case of cyclical inclusions', () => {
|
||||
expect(md.render(noteD.source.text)).toMatch(
|
||||
`<p>This is the text of note D which includes <p>This is the text of note C which includes <p>This is the text of note D which includes <div class="foam-cyclic-link-warning">Cyclic link detected for wikilink: note-c</div></p>
|
||||
</p>
|
||||
</p>
|
||||
`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,6 +5,7 @@ import { FoamFeature } from '../types';
|
||||
import { isNone } from '../utils';
|
||||
|
||||
const ALIAS_DIVIDER_CHAR = '|';
|
||||
const refsStack: string[] = [];
|
||||
|
||||
const feature: FoamFeature = {
|
||||
activate: async (
|
||||
@@ -17,6 +18,7 @@ const feature: FoamFeature = {
|
||||
extendMarkdownIt: (md: markdownit) => {
|
||||
return [
|
||||
markdownItWithFoamTags,
|
||||
markdownItWithNoteInclusion,
|
||||
markdownItWithFoamLinks,
|
||||
markdownItWithRemoveLinkReferences,
|
||||
].reduce((acc, extension) => extension(acc, foam.workspace), md);
|
||||
@@ -25,6 +27,47 @@ const feature: FoamFeature = {
|
||||
},
|
||||
};
|
||||
|
||||
export const markdownItWithNoteInclusion = (
|
||||
md: markdownit,
|
||||
workspace: FoamWorkspace
|
||||
) => {
|
||||
return md.use(markdownItRegex, {
|
||||
name: 'include-notes',
|
||||
regex: /!\[\[([^[\]]+?)\]\]/,
|
||||
replace: (wikilink: string) => {
|
||||
try {
|
||||
const includedNote = workspace.find(wikilink);
|
||||
|
||||
if (!includedNote) {
|
||||
return `![[${wikilink}]]`;
|
||||
}
|
||||
|
||||
const cyclicLinkDetected = refsStack.includes(wikilink);
|
||||
|
||||
if (!cyclicLinkDetected) {
|
||||
refsStack.push(wikilink.toLowerCase());
|
||||
}
|
||||
|
||||
const html = cyclicLinkDetected
|
||||
? `<div class="foam-cyclic-link-warning">Cyclic link detected for wikilink: ${wikilink}</div>`
|
||||
: md.render(includedNote.source.text);
|
||||
|
||||
if (!cyclicLinkDetected) {
|
||||
refsStack.pop();
|
||||
}
|
||||
|
||||
return html;
|
||||
} catch (e) {
|
||||
Logger.error(
|
||||
`Error while including [[${wikilink}]] into the current document of the Preview panel`,
|
||||
e
|
||||
);
|
||||
return '';
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const markdownItWithFoamLinks = (
|
||||
md: markdownit,
|
||||
workspace: FoamWorkspace
|
||||
|
||||
@@ -6,9 +6,13 @@
|
||||
.foam-note-link,
|
||||
.foam-attachment-link {
|
||||
color: var(--vscode-textLink-foreground);
|
||||
|
||||
}
|
||||
|
||||
.foam-tag {
|
||||
color: var(--vscode-editorLineNumber-foreground)
|
||||
}
|
||||
color: var(--vscode-editorLineNumber-foreground);
|
||||
}
|
||||
|
||||
.foam-cyclic-link-warning {
|
||||
background-color: var(--vscode-editorError-background);
|
||||
color: var(--vscode-editorError-foreground);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user