Note Taking Manual
Table of Contents
1 TODO Clean up and Replace previous Method
2 TODO Clear off Workload of attempts
3 Introduction
The important features are:
- Writing Material
- Finding Material
- Reading Material
- Mobile
- Desktop
- Sharing Material
3.1 Org-Mode and Markdown
While org-mode is full featured and powerful, there are a
few reasons I don't like it for the backbone of a note taking system:
3.1.1 Problems with org-mode
- Emacs with
org-modeis just far too unstable, I've spent hours, well no weeks, literally 9-5 weeks trying to get it stable, you blink and it fails to export, or inline create math or whatever, whereas markdown just works, lacking in features, but, it just works. - Emacs takes an enormous amount of configuration
- my
~/.emacs.d/init.elis already at like 500 lines and I'm using a starter kit (Spacemacs)- With Emacs 28, this is now in
~/.config/emacs/init.elwhere it should be but I don't really look forward to moving it.
- With Emacs 28, this is now in
- my
- Emacs can get really slow
- This is probably on my end, but again, a pain in the ass
- No mobile editors (see 2.1 below)
- I don't like beorg, it sucks for long notes, doesn't support
inline math and it doesn't work well with
git, using Dropbox is nothing but a headache when it comes to syncing.- I've heard good things about it's support for the
agenda but I don't use
org-modelike that, I use thetodofeatures to track a specific project in an index but I use ToDoist because it's just simpler to use.
- I've heard good things about it's support for the
agenda but I don't use
- I don't like beorg, it sucks for long notes, doesn't support
inline math and it doesn't work well with
- It only works with emacs
- The Vim Rendition is half-way there
- markdown works in both and
emacsdoesn't scroll with the mouse which is a shame on the laptop. - You'll miss fzf,
helm-locateandhelm-agdon't even come close.
- No live preview for math sucks
- Math inline preview will break if there is a bug above
- this is a dealbreaker honestly, it's ridiculous
- Exported Math depends on previous math, whereas markdown is compartmentalised
yasnippetsdoesn't hold a candle to using UltiSnips to write LaTeX in vim. andcompany-modeisn't much better than Deoplete, but i'll admit YCM is a buggy mess that fails when you blink- bugs in
init.elcan break HTML export
3.1.2 Strengths to org-mode
Although it does have some features that justify using it:
- inline LaTeX preview is really great
- if youre willing to compile ghostscript v50 from
source if you're not on Arch-Linux
- oh and you can tollerate opening your
init.elto inclrease the font size as opposed to usingC-x C-+ C--
- oh and you can tollerate opening your
- if youre willing to compile ghostscript v50 from
source if you're not on Arch-Linux
- It really is more readable as raw text than Markdown
- This means if you use WorkingCopy on iOS you
can practically edit and work with your
orgset-up- If you're using
org-wikiyou can even follow the HTML File through all the links which is great, because I think the tags and agenda suck for navigating notes/notebooks.1 - Alternatively you could use
python3 -m http.server 8351 --bind 192.168.0.134to look on the ipad, but this is annoying because you have to grap your ipv4 before doing that if you're out of the house unlike iamcco's preview which does it automatically.
- If you're using
- This means if you use WorkingCopy on iOS you
can practically edit and work with your
- Foldable Code Boxes out of the box
- with MD you have to use
set foldmethod=manualand a text-object plugin.
- with MD you have to use
- Once it is set up creating links with
SPC a o lfeels amazing - Inline code is amazing with outshine mode
- I cannot get outshine to play with R though so I don't know
- Literate Programming with it is amazing, so many of my
bashscripts start asorg-modeusingorg-edit-specialand then I just pull the bash out [fn:9] and use =SPC m e e t uto give myself a manual/help dialog for it, it feels like magic!! - Managing long documents with emacs is a lot easier, because the folding feels very natural and the syntax highlighting is brilliant.
citeproc-orgmakes your HTML documents look just like they would with BibTeXorg-modesupports the minted package out of the box (minted looks better than listing and actually supports most languages likevimscriptandelisporg-modeinterprets LaTeX properly and then passes it to mathjax, markdown is so confusing because you wrap everything in$even if you wouldn't in LaTeX and I think that's ridiculous.- you never need to leave
emacs- I map
C-ce=/=vto vim emacs so it shouldn't matter.
- I map
3.1.3 Use Case
Basically the choice of format will depend on the note type,
- A long document like a manual will go into
org-mode- because the interlinking is brilliant and the inbuild HTML export
- A short note will go into
mdbecause- fzf works in vim works with
md - more apps support it (MWeb/iaWriter)
- More programs have support for smaller document notes:
- live preview of math is excellent
- Two features, missing by
org-mode2 but available forMDwhich are crucial to filtering through small notes (and available in Evernote) are:- Something I call fuzzy-search-with-live-preview which is
provided only by Notable
- although
fzf --previewcomes pretty close- This is implemented in vim with
notational-fzf, which is amazing
- This is implemented in vim with
- although
- Recursively Filtering through tags
- Something I call fuzzy-search-with-live-preview which is
provided only by Notable
- fzf works in vim works with
3.1.4 Using pandoc
Thankfully pandoc means you shouldn't really too much
about this stuff though, you can literally paste org-mode
out of the clipboard into Markdown and vice-versa if you
map a bash script to a keybinding 3
input=$(xclip -o -selection clipboard) alias xclip='xclip -selection clipboard' # To Org xclip -o | pandoc -s -f markdown -t org | xclip # Back to Markdown xclip -o | pandoc -s -t markdown -f org | xclip
Actually with pipes you can do all sort of cool things, like this is an example of how to pull a website into markdown:
curl https://orgmode.org/manual/Markdown-Export.html#Markdown-Export | pandoc -f HTML -t gfm | xclip -selection clipboard
and reference it using beautifulsoup:
arglink=$(xclip -o -selection clipboard) title=$(wget -qO- $arglink | perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title/si' | recode html..) outputlink="[$title]($arglink)" echo $outputlink | xclip -selection clipboard
- Problems with links
Links may become a pain in the ass to maintain, so what i do is copy the file name to the clipboard and use fzf with this bash script to make a relative link to a file:
#!/bin/bash # Don't forget to adjust the permissions with: #chmod +x ~/somecrazyfolder/script1 ## Program ### Description # This will use fzf to find filenames that might correspond to a path from a broken link in the clipboard. # so let's say that ~[](~/broken/path/to/rsico.png)~ is a broken link, I can use ~yi(~ to copy that to the clipboard in vim and run the following bash scipt to return the correct link: # Requires: # * gnu coreutils (specifically realpath) # * fzf # * xclip ### Code brokenPath=$(xclip -o -selection clipboard) #find ~/Dropbox/ -name $(echo $(basename $brokenPath)) | fzf | xclip -selection clipboard NewFile=$(find ~/Dropbox/ -name $(echo $(basename $brokenPath)) | fzf) echo $NewFile | xclip -selection clipboard echo " Put the path of the source file in the clipboard and Press any Key to Continue " # this will just continue after a key stroke read -d'' -s -n1 echo " Using: " sourceFile=$(xclip -o -selection clipboard) echo " SOURCE_FILE.......$sourceFile NEW_ATTACHMENT....$NewFile " sourcePath=$(dirname $sourceFile) relativePath=$(realpath --relative-to=$sourcePath $NewFile) relPathWithDot="./"$relativePath echo $relPathWithDot | xclip -selection clipboard echo " Success! Relative path is in clipboard " exit 0 ## vim:fdm=expr:fdl=0 ## vim:fde=getline(v\:lnum)=~'^##'?'>'.(matchend(getline(v\:lnum),'##*')-2)\:'='
4 Sharing Material
4.1 Markdown
- HackMD is an option
- MkDocs and GitHub
4.2 Org-Mode
- put the HTML on Github
4.3 HTML and iOS
- Shortcuts
- iCloud is quicker
- Dropbox allows mathjax
- WorkingCopy (best)
- phenomenal, uses mathml for math in
MD - uses MathJax to view Math in HTML
- phenomenal, uses mathml for math in
5 Writing Material
5.1 Diagrams
5.1.1 Apple Pencil
5.1.2 TiKz
Tikz is awesome but this is actually a bit of work to implement:
See Previous work on
- write in LaTeX
- export using a luascript
- grab the svg
- be aware that getting an svg in LaTeX is a real pain, so you can go from TeX to HTML with the lua script but not really back, its madness.
- Or you could go from
svgtopngbut then you lose scaling so the whole thing sucks - You could also use LaTeX and just export to HTML with Mathjax
This is probably the way to go tbh.
- You can open the HTML from notable :shrug:
5.1.3 InkScape
6 Finding Material
6.1 Tags
Tags revolve around:
- Entering the same tag
- Browsing through tags
6.1.1 Yaml Tags
These are basically Notebooks, they make more sense than folders
because you can change them using vim and sed which scales
better over many files and is easier to maintain than manually maintaining
symlinks across directories.
These are supported by:
NotableVsCode
And they work really well for there rigid strucutre
- Inserting
YAMLTags ATTACH
In order to insert a
YAMLtag into a note withvimyou can useFZFto read a text file and make suggestions from a text file with those entries:imap <expr> <C-c><C-y> fzf#vim#complete('cat ~/Notes/MD/notes/00tags.csv')In order to get that text file you can use an R that leverages
RMarkdownto pull theyamlout:noteFiles <- c(dir(pattern="*.Rmd"), dir(pattern="*.md"), dir(pattern="*.txt"), dir(pattern="*.markdown")) tagVector <- c() # Run the following code over the entire folder for (i in noteFiles){ yamlExtract <- yaml_front_matter(input = i ) MDTags <- (yamlExtract$tags) tagVector <- c(MDTags, tagVector) # Generate Symlinks for (tagDirPath in MDTags) { actDirPath <- paste0("./aaaamytest/", tagDirPath) dir.create(path = actDirPath, recursive = TRUE) linkPath=paste0( actDirPath, "/", i) print(i) print(linkPath) createLink(link = linkPath, target = i) } }
Then you can just regenerate the tags as needed with
$ Rscript makeTags.Rand insert them withC-c C-y.This can be seen in this gif:
- Browsing Yaml Tags
In order to browse
YAMLtags just search for the verbatim structure withripgrep, in this contextYAMLtags are only used to set up notebook directories, so they will always be nested with/characters, hence the number of false positives will be small enough to justify this simplicity:cat 00tags.csv | rg '[a-zA-Z0-9]+/[a-zA-Z0-9/]+' | fzf | xargs rg -l > /tmp/kdkdjaksd; cat /tmp/kdkdjaksd # I couldn't get a pipe to work so I had to save to /tmp
- Folder Structure
You can Also browse through the YAML tags like a folder structure, the above RScript at 6.1.1.1 uses a nested
forloop to create a directory structure with symlinks for the corresponding notes.
- Folder Structure
6.1.2 #Tags
So the advantage to inline tags is that they are:
- Really simple to implement and use
- for example using
YAMLbasically requires a parser because:- if you're working with something rigid like
YAMLyou need to support it properly or the system will fall apart, butYAMLcan use:python-style lists- mappings
- New line sequences
- Even if
YAMLused just one syntax, it would not be easy to implement in regex because look around features don't like to work with wild cards, moreover doing something like\-\-\-\n[\w\W]*tags:\scannot be efficient.
- if you're working with something rigid like
- for example using
- Can appear anywhere in your document
- If you use iamcco's preview, the scroll can be locked to once you jump to the tag it will be in the preview as well.
- Because they are easy to implement they can be concurrently filtered
I've elected to use #tags rather than @4 becuase
it's more common and is implemented by iaWriter, meaning
I can use smart folders on the iPad, :tag: was another
option I rejected 5.
In order to reduce false positives it's important to have a really clear definition of a tag, I've chosen to do \s#TAGNAME\s, this should work well, I just need to be mindful to include spaces around the tags.
- Listing already Created tags
This is where
#tagsreally shine, because they are easy to parse and becauseripgrepandfzfare both lightning fast all the notes can be searched and all the tags listed on the fly like so:imap <expr> <C-c><C-t> fzf#vim#complete('rg --pcre2 "\s#[a-zA-Z-@]+\s" -o --no-filename $HOME/Notes/MD/notes -t md \| sort -u')Then simply presing
C-c C-tinvimwill allow you to enter the matching tag. - Filtering by the desired tag
This is where
#tagsare amazing, because they are so simple, they can be recursively filtered for, first create a temporary file to store any notes that have tags in them6, then useripgrepwithlook-aroundto extract the tag name:First find all the tags and offer the user
# Make a temp file to store results if necessary if test -f 00TagMatchList; then echo "subsequent search"; else # List in order of modification Date, top newest ls -t *.md > 00TagMatchList; fi tagval=$(cat 00TagMatchList | xargs -d '\n' rg --pcre2 --no-pcre2-unicode --no-filename '(?<=[\n\s]#)[a-zA-z]+(?=[\s\n$])' -o | sort -u | fzf)
After the tags have been identified and passed to the user, save the
tagvalas a temp file and search through all the notes listed in the file for any matches:if [[ ! -z $tagval ]]; then echo ' wait for fzf to finish otherwise ripgrep has nothing with which to filter ' exit 1 else cat 00TagMatchList | xargs rg ":$tagval:|\s#$tagval\s" -l > 00TagMatchList; fi bat 00TagMatchList
Now you can re run those last two commands (which I've written into a
bashscript astagFilter.shhere, over and over again until the number of listed tags is down to a reasonable number7 .Once you're satisfied that the results are sufficiently filtered you can dump them as symlinks into a direcory like so:
mkdir 00TagMatch rm 00TagMatch/* ln -s $(realpath $(cat 00TagMatchList)) ./00TagMatch; rm 00TagMatchList
Then you can go through that directory using
fzfand--previewwith 8:rg --files-with-matches --no-messages "$1" | fzf --preview "highlight -O ansi -l {} 2> /dev/null | rg --colors 'match:bg:yellow' --ignore-case --pretty --context 10 '$1' || rg --ignore-case --pretty --context 10 '$1' {}"
Or you you could preview the files in ranger using
glowby appending the following to your scope.sh:9... md|markdown) glow -s dark "${FILE_PATH}" && { dump | trim; exit 5; } ;; ...
- Integrating with TMSU
Alternatively you can leverage TMSU to make all the symlinks, both is probably the way to go because that way you're not tied to TMSU (plus the mounting is a little buggy) but you can still leverage it
# Piping is still better than a loop because ripgrep acts on everything # Unfoutunately you cannot pipe directley into tmsu cd ~/Notes/MD/notes rg --pcre2 '(?<=\s#)[a-zA-Z]+(?=\s)' *.md -o \ | sed s+:+\ + | sed s/^/tmsu\ tag\ / | bash
TMSU wouldn't work so well with nested
yamlTAGS because TMSU doesn't have any notion of nested tags, instead it would be easier to create symlinks directly from R usingR.utils::createLink() - Browsing through the Symlinks
Then you can mount the TMSU Virtual File System wherever you like and there is an easy to browse through tags.
What works really well though is to open nvim in the directory with:
# any other way causes a crash # also confusingly =|= is to vim as =;= is to bash nvim -c 'set noautochdir | cd 00tmsutags/ | pwd'#+end_src
and then search through the files using
:Filesfrom FZF (mapped toC-p/SPC f f) and/or NerdTree, and use iamcco's preview in Firefox with Tree Style Tab to stay organised. If you'd rather work frombashyou can usefzfwith the--previewoption from before.Or you could use vim with and a preview app like iamcco's.
Or you could preview all the markdown in a rendered state by using MarkText / or Typora, or Zettlr, Abricotine, Typora, MarkdownViewer Chrome Plugin10 , MkDocs or Docsify, are other options that work in some way.
Another good option for navigating the 'tags are now folders' structure is to use VSCode and/or atom, both are well suited to navigating through a dense structure.
Dillinger is also really cool, but, I don't know what I'd use it for, could I get it on the ipad by hosting my own server maybe?
- Renaming Tags
Just use a careful application of
sedif this is necessary:sed -i s+#OldTag+#NewTag+g
- Renaming Files
Somewhat integral to the Tag Filtering operation above is reasonable file names, if it's necessary to fix the file name just use
chdir "%p"; ! mv "%" newname.md.This will break links, but if a note is already linked from elsewhere you'd make a new note and/or delete the old one.
- Searching Tag Under Cursor
In order to search for the word under the cursor you could just
:RgbyFZF,:NVbynotational-fzf-vimoffers a seamless preview as well so I'll just use that.Add the following to
.vimrcand you'll be able to search for a tag under the cursor withSPC f gand if you forget keyboard shortcutsSPC Tabwill list them."let mapleader="\<Space>" map <Space> <Leader> :set iskeyword+=# nmap <Space>fg :NV <C-r><C-w> <CR> nmap <leader><tab> <plug>(fzf-maps-n)
7 Viewing Material
7.1 Vim-Plugin
7.2 Firefox
while Previewing MD in the browser, in order to keep your sanity, you're going to want to use this Tree add on to keep yourself organised.
7.3 Chrome Browser Extension
Firefox will not allow local MD files to be rendered with
an add on as a security policy, instead you can
Firefox doesn't allow markdown files to be rendered inside
the browser if they are local ( nor does it make it easy if
you do it with a simple python3 -m http.server 8089 --bind 192.168.0.137 )
you'd be better off just doing it in chrome with This extension
7.4 WYSIWYG Editor
7.5 Notable
8 Appendix
8.1 Emacs Speaks Statistics
Emacs is amazing for literate programming, but it's a nightmare to work with,
it has it's place but Nvim-R is definitely best in class for literate
programming using R-Markdown, but there are cases where using R in
org-mode is really handy, for example, to make a bar chart of all the words in
this manual:
## Load Tidy Verse library(tidyverse) ## Scan Through the Manual words <- tolower(scan("./manual.org", what = "", na.strings = c("|",":")) ) ## Use Grep to pull out org #+ Blocks words <- words[-grep(pattern = "#.*", x = words)] ## Sort the words by frequency and cut the results topwords <- sort(table(words[nchar(words) > 3]), decreasing = TRUE)[1:9] topwords <- as_tibble(topwords, .name_repair = "universal") names(topwords) <- c("Word", "Frequency") print(topwords)
| Word | Frequency |
|---|---|
| with | 54 |
| this | 44 |
| using | 29 |
| tags | 24 |
| because | 21 |
| just | 21 |
| like | 21 |
| will | 21 |
| that | 20 |
## Make Plot WordFreqPlot <- ggplot(topwords, aes(y = Frequency, x = Word, fill = -Frequency)) + geom_col() + theme_minimal() # Export the Plot into the working directory plotname <- "WordCount" png(filename=paste0(plotname, ".png")) print(WordFreqPlot) dev.off() # Print the =org-mode= link syntax print(paste0( "\n", "Output:", "\n", "[[./", plotname, ".png", "]]"))
| x |
|---|
| Output: |
![]() |
8.1.1 Using ESS with org-babel
- Output types
- Results Type
Notice that this block when executed with
C-cwill give the STDOUTrnorm(9)
[1] 0.6382742 0.8345823 1.7164897 -1.6547841 0.3749552 -0.3740537 -0.1397769 [8] 1.7248219 -0.6240926
Where as this block will give the expected results:
rnorm(9)
-0.291413700921148 -0.842118271320166 0.607393290039903 -1.45235488571945 0.76756412055268 -0.781050222761955 -0.00871441944811291 2.55762250149617 0.035717298920082 - Format Type
You can also change the output to better integrate with org by using
:format rawor:format org:rnorm(9)
-0.77482993685678 0.0965881713078849 -0.14713783099907 0.872082762958436 0.430324516204023 1.09693115216299 -1.08671165152439 0.0577277935967486 1.99238195515524
- Results Type
- Working with Graphics
Switching back to
:results valueso we don't get crap from the graphic export:library(tidyverse) rnorm(9) %>% hist()
We can see that this gives us a popup, which we don't really want, instead, let's deal with an inline image, previously I was able to acheive this by using
:results output graphics, that's since stopped working, it would probably better to just bypass the brokenorg-babelbullshit and deal with it all from R, it's not as nice but theres not much I can do about that.library("ggplot2") # Using SVG is also an option, but LaTeX sucks. svg(filename="pipe.svg") # Give the filename of the plot and a Description plotname="chocolatemouselamp" description= "Just a test to get =org-babel= plots" # Export the Plot into the working directory png(filename=paste0(plotname, ".png")) print(qplot(mpg, wt, data = mtcars)) dev.off() # Print the =org-mode= link syntax print(paste0( "\n", "Output:", "\n", "[[./", plotname, ".png", "]]"))
Output: 
Footnotes:
Yes I've been patient, no it doesn't work for me.
Atleast easily in a fashion I could make work
This is used by Notes.vim
A variable would be quicker than a file because it's stored in memory, I did a file when I was playing in the terminal using for loops rather than pipes and it just made it's way into the script I'm using, there is a TODO next to it but the whole script needs to be rewritten anyway.
This is why using descriptive file names is important, with all notes in one directory it will be necessary to have unique file names, but using a sample of 1000 words and never repeating a word and not using the same 3 words in two files there will be \(\binom{1000}{3} > 10^6\) different combinations, so there is no need to use a UUID.
I got this idea from the Github Wiki
ranger crashes all the time though, there's some bug with the way the
directories are mounted and vim, for example vim can only change into that
directory after being loaded, so vim -c 'cd 00tmsutags' is fine but
vim 00tmsutags is not fine.
You might want to start a python server for this with python3 -m https.server 8392
