Browse Source

update

master
Gregory Leeman 2 years ago
parent
commit
a685fe3efa
  1. 21
      README.html
  2. 327
      autoload/notecrate.vim
  3. 34
      ftplugin/notecrate.vim
  4. 3
      plugin/notecrate.vim
  5. 26
      scripts/convert.sh
  6. 6
      scripts/header.html
  7. 13
      scripts/marp.sh
  8. 48
      syntax/notecrate.vim

21
README.html

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>notecrate.vim</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
</style>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<h1 id="notecrate.vim">notecrate.vim</h1>
</body>
</html>

327
autoload/notecrate.vim

@ -26,7 +26,7 @@ function! notecrate#get_link_at_cursor() " {{{
if (l:match[1] == -1) if (l:match[1] == -1)
return '' return ''
elseif l:match[1] <= l:cursor && l:cursor < l:match[2] elseif l:match[1] <= l:cursor && l:cursor < l:match[2]
break break
endif endif
let l:match = matchstrpos(l:line, l:regex, l:match[2] + 1) let l:match = matchstrpos(l:line, l:regex, l:match[2] + 1)
endwhile endwhile
@ -61,7 +61,7 @@ function! notecrate#grep(pattern) " {{{
echom b:notecrate_dir echom b:notecrate_dir
let l:files = [] let l:files = []
try try
silent execute 'vimgrep /' . a:pattern . '/j ' . b:notecrate_dir . '/*.md' silent execute 'vimgrep /' . a:pattern . '/j ' . b:notecrate_dir . '/*.md'
catch /^Vim\%((\a\+)\)\=:E480/ " No Match catch /^Vim\%((\a\+)\)\=:E480/ " No Match
endtry endtry
for d in getqflist() for d in getqflist()
@ -137,15 +137,15 @@ function! notecrate#nested_markdown_folds(lnum) " {{{
let l:nextIndent = notecrate#indent_level(a:lnum + 1) let l:nextIndent = notecrate#indent_level(a:lnum + 1)
let l:nextDepth = notecrate#heading_depth(a:lnum + 1) let l:nextDepth = notecrate#heading_depth(a:lnum + 1)
if l:thisLine =~ '^\s*<' && l:prevLine =~ '^\s*$' if l:thisLine =~ '^\s*<' && l:prevLine =~ '^\s*$'
return 1 return 1
endif endif
if l:thisLine =~ '^\s*$' && l:prevLine =~ '^\s*<' if l:thisLine =~ '^\s*$' && l:prevLine =~ '^\s*<'
return 0 return 0
endif endif
if l:nextLine =~ '^---$' || l:thisLine =~ '^---$' if l:nextLine =~ '^---$' || l:thisLine =~ '^---$'
return 0 return 0
endif endif
@ -187,102 +187,7 @@ endfunction
" }}} " }}}
" }}} " }}}
" git {{{
function! notecrate#push() " {{{
execute "normal! :!cd " . b:notecrate_dir . "; git add -A; git commit -m \"autocommit\"; git push;\<CR>"
endfunction
" }}}
function! notecrate#pull() " {{{
execute "normal! :!cd " . b:notecrate_dir . "; git pull;\<CR>"
endfunction
" }}}
" }}}
" pandoc {{{
function! notecrate#convert() " {{{
execute "normal! :w!\<CR>:!pushd " . b:notecrate_dir . "; bash convert.sh;\<CR>"
endfunction
" }}}
" }}}
" navigation {{{
function! notecrate#follow_link() " {{{
let l:link = notecrate#get_link_at_cursor()"
if type(l:link) == 4
if l:link['dest'] =~ '^.*\.md$'
call notecrate#open_note(l:link['dest'])
else
silent execute "!open " . l:link['dest']
endif
endif
endfunction
" }}}
function! notecrate#open_note(filename) " {{{
let l:filename = expand('%:t')
let l:notecrate_dir = b:notecrate_dir
let l:notecrate_history = b:notecrate_history
let l:path = b:notecrate_dir . "/" . a:filename
let l:reg = getreg('')
if !filereadable(expand(l:path))
echo "Note does't exist!"
return
endif
call add(b:notecrate_history, l:filename)
silent execute "e " . l:path
let b:notecrate_dir = l:notecrate_dir
let b:notecrate_history = l:notecrate_history
call notecrate#update_backlinks()
silent execute "normal! /^#\<CR>"
call setreg('', l:reg)
endfunction
" }}}
function! notecrate#open_index() " {{{
while !isdirectory(expand(b:notecrate_dir))
let choice = confirm('', b:notecrate_dir . " does not exist. Create? &Yes\n&No\n")
if choice == 1
silent execute "!mkdir " . b:notecrate_dir
else
return 0
endif
endwhile
let l:filename = "index.md"
let l:path = b:notecrate_dir . "/" . l:filename
if !filereadable(expand(l:path))
echo "Note does't exist!"
return
endif
silent execute "e " . l:path
call notecrate#update_backlinks()
silent execute "normal! /^#\<CR>"
endfunction
" }}}
function! notecrate#open_previous() " {{{
if len(b:notecrate_history) == 0
return
endif
let l:filename = remove(b:notecrate_history, -1)
call notecrate#open_note(l:filename)
call remove(b:notecrate_history, -1)
endfunction
" }}}
function! notecrate#search_open() " {{{
call notecrate#fzf_sink('notecrate#open_from_fzf')
endfunction
function! notecrate#open_from_fzf(line)
let filename = substitute(a:line, ":[0-9]\*:[0-9]\*:.\*$", "", "")
call notecrate#open_note(filename)
endfunction
" }}}
" }}}
" notes {{{ " notes {{{
function! notecrate#update_backlinks() " {{{ function! notecrate#update_backlinks() " {{{
let l:filename = expand('%:t') let l:filename = expand('%:t')
@ -292,7 +197,7 @@ function! notecrate#update_backlinks() " {{{
let l:pattern = '\[[^\]]*\](' . l:filename . ')\(\(.*\n\)*---\)\@=' let l:pattern = '\[[^\]]*\](' . l:filename . ')\(\(.*\n\)*---\)\@='
let l:links = notecrate#grep_links(l:pattern) let l:links = notecrate#grep_links(l:pattern)
let l:backlinks = "---\n\n" let l:backlinks = "---\n\n"
if len(l:links) == 0 if len(l:links) == 0
let l:backlinks = l:backlinks . "* [Index](index.md)" let l:backlinks = l:backlinks . "* [Index](index.md)"
else else
let l:backlinks = l:backlinks . join(uniq(l:links), "\n") . "\n* [Index](index.md)" let l:backlinks = l:backlinks . join(uniq(l:links), "\n") . "\n* [Index](index.md)"
@ -344,7 +249,7 @@ endfunction
function! notecrate#new_note_from_selection() " {{{ function! notecrate#new_note_from_selection() " {{{
let l:title = notecrate#get_visual_selection() let l:title = notecrate#get_visual_selection()
let l:filename = notecrate#generate_filename() let l:filename = notecrate#generate_filename()
silent execute "normal! :'<,'>s/\\%V.*\\%V/[" . l:title . "](" . l:filename . ")/e\<CR>" silent execute "normal! :'<,'>s/\\%V.*\\%V/[" . l:title . "](" . l:filename . ")/e\<CR>"
call notecrate#new_note(l:title, l:filename) call notecrate#new_note(l:title, l:filename)
endfunction endfunction
@ -396,7 +301,7 @@ endfunction
function! notecrate#insert_link_from_fzf_selection(line) function! notecrate#insert_link_from_fzf_selection(line)
let l:filename = substitute(a:line, ":[0-9]\*:[0-9]\*:.\*$", "", "") let l:filename = substitute(a:line, ":[0-9]\*:[0-9]\*:.\*$", "", "")
let l:title = notecrate#get_visual_selection() let l:title = notecrate#get_visual_selection()
silent execute "normal! :'<,'>s/\\%V.*\\%V/[" . l:title . "](" . l:filename . ")/e\<CR>" silent execute "normal! :'<,'>s/\\%V.*\\%V/[" . l:title . "](" . l:filename . ")/e\<CR>"
endfunction endfunction
" }}} " }}}
@ -412,3 +317,219 @@ endfunction
" }}} " }}}
" }}} " }}}
" navigation {{{
function! notecrate#follow_link() " {{{
let l:link = notecrate#get_link_at_cursor()"
if type(l:link) == 4
if l:link['dest'] =~ '^.*\.md$'
call notecrate#open_note(l:link['dest'])
else
silent execute "!open " . l:link['dest']
endif
endif
endfunction
" }}}
function! notecrate#open_note(filename) " {{{
let l:filename = expand('%:t')
let l:notecrate_dir = b:notecrate_dir
let l:notecrate_history = b:notecrate_history
let l:path = b:notecrate_dir . "/" . a:filename
let l:reg = getreg('')
if !filereadable(expand(l:path))
echo "Note does't exist!"
return
endif
call add(b:notecrate_history, l:filename)
silent execute "e " . l:path
let b:notecrate_dir = l:notecrate_dir
let b:notecrate_history = l:notecrate_history
" call notecrate#update_backlinks()
silent execute "normal! /^#\<CR>"
call setreg('', l:reg)
endfunction
" }}}
function! notecrate#open_index() " {{{
while !isdirectory(expand(b:notecrate_dir))
let choice = confirm('', b:notecrate_dir . " does not exist. Create? &Yes\n&No\n")
if choice == 1
silent execute "!mkdir " . b:notecrate_dir
else
return 0
endif
endwhile
let l:filename = "index.md"
let l:path = b:notecrate_dir . "/" . l:filename
if !filereadable(expand(l:path))
echo "Note does't exist!"
return
endif
silent execute "e " . l:path
call notecrate#update_backlinks()
silent execute "normal! /^#\<CR>"
endfunction
" }}}
function! notecrate#open_previous() " {{{
if len(b:notecrate_history) == 0
return
endif
let l:filename = remove(b:notecrate_history, -1)
call notecrate#open_note(l:filename)
call remove(b:notecrate_history, -1)
endfunction
" }}}
function! notecrate#search_open() " {{{
call notecrate#fzf_sink('notecrate#open_from_fzf')
endfunction
function! notecrate#open_from_fzf(line)
let filename = substitute(a:line, ":[0-9]\*:[0-9]\*:.\*$", "", "")
call notecrate#open_note(filename)
endfunction
" }}}
" }}}
" git {{{
function! notecrate#push() " {{{
execute "normal! :!cd " . b:notecrate_dir . "; git add -A; git commit -m \"autocommit\"; git push;\<CR>"
endfunction
" }}}
function! notecrate#pull() " {{{
execute "normal! :!cd " . b:notecrate_dir . "; git pull;\<CR>"
endfunction
" }}}
" }}}
function! notecrate#update_mappings() " {{{
execute 'command! -nargs=1 Rename call notecrate#rename_note(<f-args>)'
execute 'nnoremap <buffer> <leader>r :Rename<CR>'
execute 'command! -buffer -nargs=0 Delete call notecrate#delete_note()'
execute 'nnoremap <buffer> <leader>d :Delete<CR>'
execute 'command! -buffer -nargs=0 Convert :call notecrate#script("convert")'
execute 'nnoremap <buffer> <leader>c :Convert<CR>'
execute 'command! -buffer -nargs=0 Presentation :call notecrate#script("marp")'
execute 'nnoremap <buffer> <leader>p :Presentation<CR>'
execute 'command! -buffer -nargs=0 SearchOpen :call notecrate#search_open()'
execute 'nnoremap <buffer> <leader>o :SearchOpen<CR>'
execute 'command! -buffer -nargs=0 InsertLink :call notecrate#search_insert_link()'
execute 'nnoremap <buffer> <leader>i :InsertLink<CR>'
execute 'command! -buffer -nargs=0 Backlinks :call notecrate#update_backlinks()'
execute 'nnoremap <buffer> <leader>b :Backlinks<CR>'
execute 'command! -buffer -nargs=0 New :call notecrate#new_note_from_prompt()'
execute 'nnoremap <buffer> <leader>n :New<CR>'
execute 'command! -buffer -nargs=0 Push :call notecrate#push()'
execute 'nnoremap <buffer> <leader>s :Push<CR>'
execute 'command! -buffer -nargs=0 Pull :call notecrate#pull()'
execute 'nnoremap <buffer> <leader>u :Pull<CR>'
execute 'command! -buffer -nargs=0 Follow :call notecrate#follow_link()'
execute 'nnoremap <buffer> <CR> :Follow<CR>'
execute 'nnoremap <buffer> <backspace> :call notecrate#open_previous()<CR>'
execute 'nnoremap <buffer> <S-j> /\[[^\]]*\]([^)]*)<CR>:noh<CR>'
execute 'nnoremap <buffer> <S-l> /\[[^\]]*\]([^)]*)<CR>:noh<CR>'
execute 'nnoremap <buffer> <Tab> /\[[^\]]*\]([^)]*)<CR>:noh<CR>'
execute 'nnoremap <buffer> <S-Tab> /\[[^\]]*\]([^)]*)<CR>NN:noh<CR>'
execute 'nnoremap <buffer> <S-h> /\[[^\]]*\]([^)]*)<CR>NN:noh<CR>'
execute 'nnoremap <buffer> <S-k> /\[[^\]]*\]([^)]*)<CR>NN:noh<CR>'
execute 'command! -buffer -nargs=0 Insert :call notecrate#search_insert_link_selection()'
execute 'vnoremap <buffer> <leader>i :Insert<CR>'
execute 'vnoremap <buffer> <CR> :call notecrate#new_note_from_selection()<CR>'
execute 'inoremap <buffer> <Tab> <C-t>'
execute 'inoremap <buffer> <S-Tab> <C-d>'
endfunction
" }}}
function! notecrate#update_syntax() " {{{
execute 'setlocal textwidth=79'
execute 'setlocal autowriteall'
execute 'setlocal comments+=b:*'
execute 'setlocal foldlevel=3'
execute 'setlocal foldmethod=expr'
execute 'setlocal foldexpr=notecrate#nested_markdown_folds(v:lnum)'
execute 'setlocal foldtext=notecrate#fold_text()'
execute 'setlocal conceallevel=2'
execute 'setlocal concealcursor='
execute 'setlocal wrap'
execute 'syn match NotecrateLinkInternal /\(\](\)\@<=[^()]*\()\)\@=/'
execute 'hi def link NotecrateLinkInternal orangeu'
execute 'syn match NotecrateBoldConceal /\*\*/ conceal containedin=ALL'
execute 'syn match NotecrateLinkConceal /!*\[\+\([^\]]*](\)\@=/ conceal'
execute 'syn match NotecrateLinkConceal /\]\+\((\)\@=/ conceal'
execute 'syn match NotecrateLinkConceal /\(\[[^\]]*\]\)\@<=([^)]*)/ conceal contains=NotecrateLinkInternal'
execute 'hi def link NotecrateLinkConceal blue'
execute 'syn match NotecrateLink /\(\[\)\@<=[^\[\]]*\(\](\)\@=/'
execute 'hi def link NotecrateLink blueu'
execute 'syn match NotecrateLinkImage /!\[\]/ containedin=ALL'
execute 'hi def link NotecrateLinkImage redu'
execute 'syn match NotecrateHeader1 /\(^# \)\@<=.*/'
execute 'hi def link NotecrateHeader1 base3u'
execute 'syn match NotecrateHeader2 /\(^##\+ \)\@<=.*/'
execute 'hi def link NotecrateHeader2 base1u'
execute 'syn match NotecrateRule /^---\+/'
execute 'hi def link NotecrateRule base01'
execute 'syn region NotecrateFrontCustomMatter start=/\%^---/ end=/^---/'
execute 'hi def link NotecrateFrontCustomMatter base01'
execute 'syn region NotecrateCode start=/^```/ end=/^```/'
execute 'hi def link NotecrateCode red'
execute 'syn region NotecrateBold start=/\*\*/ end=/\*\*/ contains=NotecrateBoldConceal keepend'
execute 'hi def link NotecrateBold base2'
execute 'syn match NotecrateQuote /^>.*$/'
execute 'hi def link NotecrateQuote cyan'
execute 'syn match NotecrateTag /#[^# ]\S*/'
execute 'hi def link NotecrateTag cyanu'
execute 'syn match NotecrateDone /#DONE/ containedin=NotecrateTag'
execute 'hi def link NotecrateDone greenbg'
execute 'syn match NotecrateTodo /#TODO/ containedin=NotecrateTag'
execute 'hi def link NotecrateTodo redbg'
endfunction
" }}}
function! notecrate#script(name) " {{{
let l:script = g:todo_plugin_dir . "/scripts/" . a:name . ".sh"
let l:dir = getcwd()
let l:file = expand('%:t')
execute "cd " . b:notecrate_dir
execute "!bash " . l:script . " " . l:file
execute "cd " . l:dir
endfunction
" }}}

34
ftplugin/notecrate.vim

@ -1,33 +1 @@
setlocal textwidth=79 call notecrate#update_mappings()
setlocal autowriteall
setlocal comments+=b:*
setlocal foldlevel=3
" setlocal formatoptions=cro
command! -nargs=1 Rename call notecrate#rename_note(<f-args>)
nnoremap <buffer> <leader>c :call notecrate#convert()<CR>
nnoremap <buffer> <leader>o :call notecrate#search_open()<CR>
nnoremap <buffer> <leader>i :call notecrate#search_insert_link()<CR>
nnoremap <buffer> <leader>b :call notecrate#update_backlinks()<CR>
nnoremap <buffer> <leader>n :call notecrate#new_note_from_prompt()<CR>
nnoremap <buffer> <leader>d :call notecrate#delete_note()<CR>
nnoremap <buffer> <leader>s :call notecrate#push()<CR>
nnoremap <buffer> <leader>u :call notecrate#pull()<CR>
nnoremap <buffer> <CR> :call notecrate#follow_link()<CR>
nnoremap <buffer> <backspace> :call notecrate#open_previous()<CR>
nnoremap <buffer> <S-j> /\[[^\]]*\]([^)]*)<CR>:noh<CR>
nnoremap <buffer> <S-l> /\[[^\]]*\]([^)]*)<CR>:noh<CR>
nnoremap <buffer> <Tab> /\[[^\]]*\]([^)]*)<CR>:noh<CR>
nnoremap <buffer> <S-Tab> /\[[^\]]*\]([^)]*)<CR>NN:noh<CR>
nnoremap <buffer> <S-h> /\[[^\]]*\]([^)]*)<CR>NN:noh<CR>
nnoremap <buffer> <S-k> /\[[^\]]*\]([^)]*)<CR>NN:noh<CR>
vnoremap <buffer> <leader>i :call notecrate#search_insert_link_selection()<CR>
vnoremap <buffer> <CR> :call notecrate#new_note_from_selection()<CR>
inoremap <buffer> <Tab> <C-t>
inoremap <buffer> <S-Tab> <C-d>

3
plugin/notecrate.vim

@ -3,6 +3,9 @@ if !exists("g:notecrate_dirs")
\ "notes": { "prefix": "n", "dir": "~/notecrate"} \ "notes": { "prefix": "n", "dir": "~/notecrate"}
\ } \ }
endif endif
let g:todo_plugin_dir = expand("<sfile>:p:h:h")
for [key, value] in items(g:notecrate_dirs) for [key, value] in items(g:notecrate_dirs)
silent execute "autocmd BufRead,BufNewFile " . value["dir"] . "/*.md set filetype=notecrate syntax=notecrate" silent execute "autocmd BufRead,BufNewFile " . value["dir"] . "/*.md set filetype=notecrate syntax=notecrate"
silent execute "normal! :nnoremap <leader>w" . value["prefix"] . " :e " . value["dir"] . "/index.md<CR>:let b:notecrate_dir = \"" . value["dir"] . "\"<CR>:let b:notecrate_history = []<CR>\<CR>" silent execute "normal! :nnoremap <leader>w" . value["prefix"] . " :e " . value["dir"] . "/index.md<CR>:let b:notecrate_dir = \"" . value["dir"] . "\"<CR>:let b:notecrate_history = []<CR>\<CR>"

26
scripts/convert.sh

@ -0,0 +1,26 @@
HEADER="$(dirname ${0})/header.html";
for MARKDOWN in ./*.md; do
CONVERT=0;
TITLE=$(grep '^# \S' ${MARKDOWN} | sed 's/# //g');
HTML="${MARKDOWN%.*}.html";
if [ ! -f ${HTML} ]; then
CONVERT=1;
elif [[ $(date -r ${MARKDOWN} +%s) > $(date -r ${HTML} +%s) ]]; then
CONVERT=1;
fi;
if [[ $CONVERT -eq 1 ]]; then
echo "Converting ${TITLE}";
`which pandoc` -s ${MARKDOWN} -H ${HEADER} -f markdown-task_lists --metadata pagetitle="${TITLE}" -o ${HTML};
fi;
done;
for HTML in ./*.html; do
HTML="${HTML/_p./}";
MARKDOWN="${HTML%.*}.md";
if [ ! -f ${MARKDOWN} ]; then
echo "Removing ${HTML}";
rm "${HTML}";
fi;
done;
sed -i ./*html -e 's/\.md/.html/g';

6
scripts/header.html

@ -0,0 +1,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Courgette&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">

13
scripts/marp.sh

@ -0,0 +1,13 @@
SOURCE=${1};
TARGET="${SOURCE%.*}_p.html";
# sed -n '/---/q;p' ${SOURCE} > temp.md;
docker run \
--rm \
-v ${PWD}:/home/marp/app/ \
-e LANG=${LANG} \
-e MARP_USER="$(id -u):$(id -g)" \
marpteam/marp-cli \
-o ${TARGET} \
temp.md;

48
syntax/notecrate.vim

@ -1,47 +1 @@
setlocal foldmethod=expr call notecrate#update_syntax()
setlocal foldexpr=notecrate#nested_markdown_folds(v:lnum)
setlocal foldtext=notecrate#fold_text()
setlocal conceallevel=2
setlocal wrap
syn match NotecrateLinkInternal /\(\](\)\@<=[^()]*\()\)\@=/
hi def link NotecrateLinkInternal orangeu
" syn match NotecrateBoldConceal /\*\*/ containedin=ALL
syn match NotecrateBoldConceal /\*\*/ conceal containedin=ALL
syn match NotecrateLinkConceal /!*\[\+\([^\]]*](\)\@=/ conceal
syn match NotecrateLinkConceal /\]\+\((\)\@=/ conceal
syn match NotecrateLinkConceal /\(\[[^\]]*\]\)\@<=([^)]*)/ conceal contains=NotecrateLinkInternal
hi def link NotecrateLinkConceal blue
syn match NotecrateLink /\(\[\)\@<=[^\[\]]*\(\](\)\@=/
hi def link NotecrateLink blueu
syn match NotecrateLinkImage /!\[\]/ containedin=ALL
hi def link NotecrateLinkImage redu
syn match NotecrateHeader1 /\(^# \)\@<=.*/
hi def link NotecrateHeader1 base3u
syn match NotecrateHeader2 /\(^##\+ \)\@<=.*/
hi def link NotecrateHeader2 base1u
syn match NotecrateRule /^---\+/
hi def link NotecrateRule base01
syn region NotecrateFrontCustomMatter start=/\%^---/ end=/^---/
hi def link NotecrateFrontCustomMatter base01
syn region NotecrateCode start=/^```/ end=/^```/
hi def link NotecrateCode red
syn region NotecrateBold start=/\*\*/ end=/\*\*/ contains=NotecrateBoldConceal keepend
hi def link NotecrateBold base2
syn match NotecrateQuote /^>.*$/
hi def link NotecrateQuote cyan
syn match NotecrateTag /#[^# ]\S*/
hi def link NotecrateTag cyanu