libdenote added (not used yet)
This commit is contained in:
195
autoload/libdenote.vim
Normal file
195
autoload/libdenote.vim
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
" libdenote plugin for vim
|
||||||
|
" This plugin describes basic denote functions. Each one of these functions
|
||||||
|
" deals wither with the file-naming scheme (prefixed with scheme_), or with the
|
||||||
|
" front matter (prefixed with fm_). All functions are pure, i.e., have no side
|
||||||
|
" affects.
|
||||||
|
"
|
||||||
|
" FILE-NAMING SCHEME {{{1
|
||||||
|
"
|
||||||
|
" Script-local functions {{{2
|
||||||
|
"
|
||||||
|
" This function removes illegal characters in parts of the filename.
|
||||||
|
function s:santizefnpart(part)
|
||||||
|
return a:part->tolower()
|
||||||
|
\ ->substitute('[^[:alnum:]]', '-', 'g')
|
||||||
|
\ ->substitute('-\+', '-', 'g')
|
||||||
|
\ ->substitute('_\+', '_', 'g')
|
||||||
|
\ ->substitute('=\+', '=', 'g')
|
||||||
|
\ ->substitute('@\+', '@', 'g')
|
||||||
|
\ ->trim('-_@=')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" API {{{2
|
||||||
|
|
||||||
|
" Identifier creation
|
||||||
|
" This unction generates a fresh denote identifier
|
||||||
|
function libdenote#scheme_idgen()
|
||||||
|
return exists('*strftime')
|
||||||
|
\ ? strftime('%Y%m%dT%H%M%S')
|
||||||
|
\ : rand()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Generate file name
|
||||||
|
" This function returns the Filename given all components in the file-naming
|
||||||
|
" scheme
|
||||||
|
"
|
||||||
|
" @argument a:ext string: File extension
|
||||||
|
" @argument a:id string: Identifier of denote entry
|
||||||
|
" @argument a:title string: Title of denote entry
|
||||||
|
" @argument a:tags list[string]: List of strings that specify the tags
|
||||||
|
" @argument a:sig string: Signature string of denote entry
|
||||||
|
function libdenote#scheme_filename(ext, identifier, title='', tags=[], sig='')
|
||||||
|
let l:f = s:santizefnpart(a:identifier)
|
||||||
|
let l:f ..= len(a:sig) > 0 ? ('==' .. s:santizefnpart(a:sig)) : ''
|
||||||
|
let l:f ..= len(a:title) > 0 ? ('--' .. s:santizefnpart(a:title)) : ''
|
||||||
|
let l:f ..= len(a:tags) > 0 ? ('__' .. map(copy(a:tags), {_, v -> s:santizefnpart(v)})->join('_')) : ''
|
||||||
|
return l:f .. '.' .. a:ext
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Retrieve metadata from file name
|
||||||
|
" This function returns a dict with the entries 'id', 'title', 'tags', and
|
||||||
|
" 'sig.' The value type of 'tags' is a list, the other entries hold strings.
|
||||||
|
"
|
||||||
|
" @argument a:filename string: Filename or path to file
|
||||||
|
function libdenote#scheme_metadata(filename)
|
||||||
|
return {
|
||||||
|
\ 'id': a:filename->fnamemodify(':t')->matchstr('@@\zs.\{-\}\ze\(==\|--\|__\|\..\)')
|
||||||
|
\ ?? a:filename->fnamemodify(':t')->matchstr('^.\{-\}\ze\(==\|--\|__\|\..\)'),
|
||||||
|
\ 'title': a:filename->fnamemodify(':t')->matchstr('--\zs.\{-\}\ze\(==\|@@\|__\|\..\)')
|
||||||
|
\ ->substitute('-', ' ', 'g'),
|
||||||
|
\ 'tags': a:filename->fnamemodify(':t')->matchstr('__\zs.\{-\}\ze\(==\|@@\|--\|\..\)')
|
||||||
|
\ ->split('_'),
|
||||||
|
\ 'sig': a:filename->fnamemodify(':t')->matchstr('==\zs.\{-\}\ze\(==\|@@\|__\|\..\)')
|
||||||
|
\}
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
" Get path to file from denote identifier
|
||||||
|
" This function returns the path to the file the note corresponds to, if it
|
||||||
|
" exists, and v:false otherwise.
|
||||||
|
"
|
||||||
|
" @argument a:dir string: Path to denote directory
|
||||||
|
" @argument a:id string: Identifier of denote entry
|
||||||
|
function libdenote#scheme_find(dir, id)
|
||||||
|
" According to the file-naming scheme, the note id is prefixed with '@@'. If
|
||||||
|
" the note id appears at the beginning of the file name, then this prefix is
|
||||||
|
" optional. There may exist another field (such as the signature, title, or
|
||||||
|
" keywords field) after the note id. These are prefixed with '==', '--', or
|
||||||
|
" '__'. If the note id is the last field, then the id is followed by the file
|
||||||
|
" extension, e.g., '.md'.
|
||||||
|
" (A) First, we get all files that contain the note id as substring.
|
||||||
|
" (B) Then we ensure that the note id is followed by another field or by the
|
||||||
|
" file extension.
|
||||||
|
let l:files = glob(a:dir .. '/*' .. a:id .. '*', 0, v:true)
|
||||||
|
\ ->filter('v:val->split("/")[-1] =~ "' .. a:id .. '\\(==\\|--\\|__\\|\\.\\)"')
|
||||||
|
\ ->filter('v:val->split("/")[-1] =~ "^' .. a:id .. '\\|@@' .. a:id .. '"')
|
||||||
|
return empty(l:files) ? v:false : l:files[0]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
" FRONT-MATTER HANDLING {{{1
|
||||||
|
"
|
||||||
|
" Script-local functions {{{2
|
||||||
|
"
|
||||||
|
" Put string in double quotes, and remove inside double quotes.
|
||||||
|
function s:escapeDQ(s)
|
||||||
|
return '"' .. substitute(a:s, '"', '', 'g') .. '"'
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Create front matter (yaml)
|
||||||
|
function s:md_new_yaml(id, title, tags)
|
||||||
|
return [
|
||||||
|
\ '---',
|
||||||
|
\ 'title: ' .. s:escapeDQ(a:title),
|
||||||
|
\ 'date: ' .. strftime('%FT%T%z'),
|
||||||
|
\ 'tags: [' .. map(copy(a:tags), {_, t -> s:escapeDQ(t) })->join(', ') .. ']',
|
||||||
|
\ 'identifier: ' .. s:escapeDQ(a:id),
|
||||||
|
\ '---'
|
||||||
|
\ ]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Create front matter (toml)
|
||||||
|
function s:md_new_toml(id, title, tags)
|
||||||
|
return [
|
||||||
|
\ '+++',
|
||||||
|
\ 'title ' .. s:escapeDQ(a:title),
|
||||||
|
\ 'date ' .. strftime('%FT%T%z'),
|
||||||
|
\ 'tags [' .. map(copy(a:tags), {_, t -> s:escapeDQ(t) })->join(', ') .. ']',
|
||||||
|
\ 'identifier ' .. s:escapeDQ(a:id),
|
||||||
|
\ '+++'
|
||||||
|
\ ]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Create front matter (plain)
|
||||||
|
function s:plain_new(id, title, tags)
|
||||||
|
return [
|
||||||
|
\ 'title: ' .. a:title,
|
||||||
|
\ 'date: ' .. strftime('%F'),
|
||||||
|
\ 'tags: ' .. a:tags->join(' '),
|
||||||
|
\ 'identifier: ' .. a:id,
|
||||||
|
\ '---------------------------',
|
||||||
|
\ ]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Create front matter (org)
|
||||||
|
function s:org_new(id, title, tags)
|
||||||
|
return [
|
||||||
|
\ '#+title: ' .. a:title,
|
||||||
|
\ '#+date: [' .. strftime('%F %a %R') .. ']',
|
||||||
|
\ '#+filetags: :' .. map(copy(a:tags), {_, t -> substitute(t, ':', '', 'g') })->join(':') .. ':',
|
||||||
|
\ '#+identifier: ' .. a:id,
|
||||||
|
\ ]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" API {{{2
|
||||||
|
|
||||||
|
" Create front matter
|
||||||
|
" This function generates a front matter. It may use the global variable
|
||||||
|
" g:denote_fm_md_type.
|
||||||
|
"
|
||||||
|
" @argument a:ext string: Generate front matter for a file of this
|
||||||
|
" extension
|
||||||
|
" @argument a:id string: Identifier of the denote note
|
||||||
|
" @argument a:title string: Title of the denote note
|
||||||
|
" @argument a:tags list[string]: List of strings that specify the tags
|
||||||
|
" @argument a:md_type string: Any of 'yaml' (default) or 'toml', for
|
||||||
|
" markdown front matter
|
||||||
|
" @return: List of strings with a line-per item that describes the front matter
|
||||||
|
function libdenote#fm_gen(ext, id, title, tags=[], md_type='yaml')
|
||||||
|
return a:ext == 'org' ? s:org_new(a:id, a:title, a:tags)
|
||||||
|
\ : a:ext == 'txt' ? s:plain_new(a:id, a:title, a:tags)
|
||||||
|
\ : a:md_type == 'toml' ? s:md_new_toml(a:id, a:title, a:tags)
|
||||||
|
\ : s:md_new_yaml(a:id, a:title, a:tags)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Alter front matter
|
||||||
|
" This function returns the (modified) a:fm front matter. For any of the
|
||||||
|
" arguments a:id, a:title, and a:tags, if the argument is specified (for the
|
||||||
|
" tag, it may also be an empty list), then the value of the argument is used as
|
||||||
|
" a replacement in the input front matter a:fm.
|
||||||
|
"
|
||||||
|
" @argument a:fm list[string] List of strings describes a frontmatter
|
||||||
|
" @argument a:ext string: Generate front matter for a file of this
|
||||||
|
" extension
|
||||||
|
" @argument a:id string: Identifier of the denote note
|
||||||
|
" @argument a:title string: Title of the denote note
|
||||||
|
" @argument a:tags list[string] or v:false:
|
||||||
|
" List of strings that specify the tags
|
||||||
|
" @return: List of strings with a line-per item that describes the front matter
|
||||||
|
function libdenote#fm_alter(fm, ext, id='', title='', tags=v:false)
|
||||||
|
let l:new = copy(a:fm)
|
||||||
|
let l:repl = libdenote#fm(a:ext, a:id ?? '', a:title ?? '', a:tags ?? [])
|
||||||
|
if a:id
|
||||||
|
let l:ididx = indexof(l:repl, 'v:val =~ "^\\(#+\\)\\?identifier"')
|
||||||
|
call map(l:new, {_, v -> v =~ "^\\(#+\\)\\?identifier" ? l:repl[l:ididx] : v})
|
||||||
|
endif
|
||||||
|
if a:title
|
||||||
|
let l:titleidx = indexof(l:repl, 'v:val =~ "^\\(#+\\)\\?title"')
|
||||||
|
call map(l:new, {_, v -> v =~ "^\\(#+\\)\\?title" ? l:repl[l:titleidx] : v})
|
||||||
|
endif
|
||||||
|
if type(a:tags) == v:t_list
|
||||||
|
let l:tagsidx = indexof(l:repl, 'v:val =~ "^\\(#+file\\)\\?tags"')
|
||||||
|
call map(l:new, {_, v -> v =~ "^\\(#+file\\)\\?tags" ? l:repl[l:tagsidx] : v})
|
||||||
|
endif
|
||||||
|
return l:new
|
||||||
|
endfunction
|
||||||
@@ -15,6 +15,12 @@ CONTENTS *vim-denote* *denote*
|
|||||||
3. Settings |denote-settings|
|
3. Settings |denote-settings|
|
||||||
4. Keys |denote-keys|
|
4. Keys |denote-keys|
|
||||||
|
|
||||||
|
Appendices
|
||||||
|
A. The libdenote plugin |libdenote|
|
||||||
|
A.1 File-naming functions |libdentoe-filenaming|
|
||||||
|
A.2 Front-matter functions |libdenote-frontmatter|
|
||||||
|
B. Package API |denote-api|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
INTRODUCTION *denote-intro*
|
INTRODUCTION *denote-intro*
|
||||||
|
|
||||||
@@ -245,4 +251,64 @@ dd Delete the selected entry.
|
|||||||
{Visual}d Delete the visually selected entries.
|
{Visual}d Delete the visually selected entries.
|
||||||
|
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
APPENDIX A - THE LIBDENOTE PLUGIN *libdenote*
|
||||||
|
|
||||||
|
The present package has as constituent the libdenote plugin for basic
|
||||||
|
denote-centered operations. That plugin is given by the file
|
||||||
|
autoload/libdenote.vim. Each function in this plugin is pure, i.e., produces
|
||||||
|
no side effects. There are two classes of functions: functions concerning the
|
||||||
|
file-naming scheme (prefixed with scheme_, see |libdenote-filenaming|) and
|
||||||
|
functions concerning the front matter (prefixed with fmt_, see
|
||||||
|
|libdenote-frontmatter|).
|
||||||
|
|
||||||
|
*libdenote-filenaming*
|
||||||
|
File-naming functions~
|
||||||
|
*libdenote#scheme_idgen()*
|
||||||
|
libdenote#scheme_idgen()
|
||||||
|
This function generates a new identifier. If the function |strftime()|
|
||||||
|
is available, than strftime(%Y%m%dT%H%M%S) is used, otherwise a random
|
||||||
|
identifier is generated using |rand()|.
|
||||||
|
|
||||||
|
*libdenote#scheme_filename()*
|
||||||
|
libdenote#scheme_filename({ext}, {id}, {title}, {tags}, {sig})
|
||||||
|
With this, the file name of the denote entry with the given metadata
|
||||||
|
is returned. The parameter {ext} describes the extension of the file
|
||||||
|
is is one of 'md', 'txt', or 'org'. The parameter {id} is the denote
|
||||||
|
identifier, possibly generated via |libdenote#scheme_idgen()|. The
|
||||||
|
{title} parameter is optional and describes the title of the note. By
|
||||||
|
default, it is set to the empty string ''. The {tags} parameter is
|
||||||
|
optional as well, is a list of tags associated to the note. The
|
||||||
|
default value is the empty list []. Also, the {sig} parameter is
|
||||||
|
optional, and used to describe the signature of the entry.
|
||||||
|
|
||||||
|
*libdenote#scheme_metadata()*
|
||||||
|
libdenote#scheme_metadata({filename})
|
||||||
|
This function returns the metadata of the file given by {filename}.
|
||||||
|
This parameter may describe the path to the file, or the tail only.
|
||||||
|
The returned |dict| has the keys 'id' for the identifier, 'title' for
|
||||||
|
the title, 'tags' for the list of tags, and 'sig' for the signature.
|
||||||
|
|
||||||
|
*libdenote-frontmatter*
|
||||||
|
Front-matter functions~
|
||||||
|
*libdenote#fm_gen()*
|
||||||
|
libdenote#fm_gen({ext}, {id}, {title}, {tags}, {md_type})
|
||||||
|
This function returns the list of lines for the front matter that
|
||||||
|
stores the given metadata. The paramter {ext} is the extension of the
|
||||||
|
file, the parameter {id} the identifier, the parameter {title}, the
|
||||||
|
title of the note, and {tags} the optional parameter as a list of tags
|
||||||
|
associated to the note. Per default {tags} is set to the empty list
|
||||||
|
[]. Finally, {md_type} descries the format to be used in markdown. For
|
||||||
|
markdown files (extension 'md'), two formats are possible: 'yaml' and
|
||||||
|
'toml'. The former format is used per default.
|
||||||
|
|
||||||
|
*libdenote#fm_alter()*
|
||||||
|
libdenote#fm_alter({fm}, {ext}, {id}, {title}, {tags}, {md_type})
|
||||||
|
Similar to |libdenote#fm_gen()|, this function returns a list
|
||||||
|
containing the lines of a front matter. In contrast to the above
|
||||||
|
function, this functions takes a front matter {fm} as base (again,
|
||||||
|
given as list of lines), and alters the title or tags associated with
|
||||||
|
the note. The arguments {title} and {tags} are optional. When set,
|
||||||
|
then {fm} is returned with the corresponding replaced lines.
|
||||||
|
|
||||||
vim:tw=78:sw=4:ts=8:noet:ft=help:norl:
|
vim:tw=78:sw=4:ts=8:noet:ft=help:norl:
|
||||||
|
|||||||
Reference in New Issue
Block a user