#task-management #text-format #note #plain-text #quick #language #line

bin+lib patto

🐙 Yet another plain text format for quick note taking and task management

5 releases

new 0.1.8 Feb 8, 2025
0.1.7 Feb 3, 2025
0.1.5 Jan 12, 2025
0.1.2 Nov 24, 2024

#472 in Parser implementations

Download history 356/week @ 2024-11-23 20/week @ 2024-11-30 20/week @ 2024-12-07 9/week @ 2024-12-14 131/week @ 2025-01-11 7/week @ 2025-01-18 96/week @ 2025-02-01

234 downloads per month

MIT license

170KB
3.5K SLoC

Rust 3K SLoC // 0.1% comments Shell 185 SLoC // 0.0% comments Vim Script 179 SLoC // 0.1% comments Lua 148 SLoC // 0.1% comments TypeScript 107 SLoC // 0.2% comments Pest 81 SLoC // 0.1% comments JavaScript 35 SLoC // 0.1% comments

🐙 Patto Note

A simple, language server-powered plain-text format for quick note-taking, outlining, and task management.

Description

Patto Note is a text format inspired by Cosense (formerly Scrapbox), designed for quick note-taking, task management, and outlining. It works with your favorite editor, powered by the Language Server Protocol. Unlike Markdown, every newline (\n) creates a new line, and a leading hard tab (\t) itemizes the line. This simple, line-oriented structure makes it easy to outline ideas, organize tasks, and brainstorm effectively.

Demo

demo.gif

Features

  • Primary Zettelkasten support
  • Task management with line property (please refer to the syntax section below)
  • Integrated vim plugin
  • Primary Language Server Protocol support
    • asynchronous workspace scanning
    • diagnostics
    • jumping between notes by go-to definition
    • backlinks by find-references
    • note/anchor completion

Syntax

Hello world.
	itemize lines with a leading hard tab `\t'
		that can be nested
	the second element  #sampleanchor
	the third element
	[@quote]
		quoted text must be indented with `\t'

Task Management
	a task {@task status=todo}
	another task with deadline {@task status=todo due=2030-12-31T23:59:00}
		abbreviated version of task !2030-12-31
	a completed task {@task status=done}

Decoration:
	[* bold text]
	[/ italic text]
	[*/ bold italic text]

Links:
	[other note]
		link to other note in a workspace
	[other note#anchor]
		direct link to an anchored line
	[#sampleanchor]
		self note link to the anchored line (i.e., this line) #sampleanchor
	url link:
		[https://google.com url title]
	title and url can be flipped:
		[url title https://google.com]
	link to an image
		[@img https://via.placeholder.com/50]

Code highlight with highlight.js
	[@code python]
		import numpy as np
		print(np.sum(10))
	[` inline code `]

Math with katex
	[@math]
		O(n^2)\\
		sum_{i=0}^{10}{i} = 55
	inline math: [$ O(n log(n)) $]

Line property

A text in the form of {@XXX YYY=ZZZ} is named as line property and adds an property to the line (not the whole text). Currently, anchor and task properties are implemented:

  • {@anchor name}: adds an anchor to the line. abbrev: #name
  • {@task status=todo due=2024-12-31}: marks the line as a todo.
    The due date only supports the ISO 8601 UTC formats (YYYY-MM-DD or YYYY-MM-DDThh:mm).
    abbrev (symbols might be changed some time):
    • todo: !2024-12-31
    • doing: *2024-12-31
    • done: -2024-12-31

Usage with (neo)vim

  • First, open a file in a workspace with suffix .pn, or :new and :set syntax=patto
  • Then, write your memos.
  • Once you type [ and @, lsp client will complete links and snippets respectively
    • snippets will only be completed with lsp-oriented snippet plugins such as vim-vsnip.
  • You will have :LspPattoTasks command; that will gather tasks from the notes in your workspace and show them in a location window.

task aggregation demo

Installation

Install lsp server

Please download binaries from GitHub release

or, use cargo:

cargo install patto

This will install the following utilities:

  • patto-lsp: a lsp server
  • patto-markdown-renderer: a format converter from patto note to markdown
  • patto-html-renderer: a format converter from patto note to html

Setup vim with vim-lsp (using vim-plug)

call plug#begin()
Plug 'prabirshrestha/asyncomplete.vim'
Plug 'prabirshrestha/asyncomplete-lsp.vim'
Plug 'prabirshrestha/vim-lsp'
Plug 'ompugao/patto', {'for': 'patto'}
call plug#end()

Setup neovim with nvim-lspconfig (using vim-plug)

call plug#begin()
Plug 'neovim/nvim-lspconfig'
Plug 'hrsh7th/cmp-nvim-lsp'
Plug 'hrsh7th/nvim-cmp'
Plug 'ompugao/patto'
call plug#end()

lua << EOF
  require('patto')
  require('lspconfig.configs').patto_lsp.setup({})
EOF

Note: we recommend neovim@nightly for non-ascii notes since PositionEncoding UTF-16 support has a bug in the current neovim stable v0.10.3. see https://github.com/neovim/neovim/issues/32105.

Setup vscode extension

To be released.

Upcoming features:

parser

  • link to local files

lsp

  • document backlinks using find references
    • file renaming keeping note connections
    • anchor renaming
  • 2-hop links
  • semantic tokens

renderer

  • markdown export
  • math expression rendering
  • replace highlight.js with syntect

other todos

please refer to todo

FAQ

Why not Markdown?

The differences in behavior between Markdown parsers led me to create the Patto format. For example, in GitHub Markdown, code fences can be contained within a list item, whereas in Obsidian, they cannot:

  • item
  • print('hello')
    
  • item3

Custom template?

Please use your favorite template/snippet engine of your editor. I personally use LuaSnip in neovim.
Other candidate vim plugins:

Misc

unix command utilities

sort tasks with grep and sort

rg --vimgrep '.*@task.*todo' . | awk '{match($0, /due=([0-9:\-T]+)/, m); if (RLENGTH>0) print m[1], $0; else print "9999-99-99", $0}' |sort |cut -d' ' -f2-
# or, in vim
cgetexpr system('rg --vimgrep ".*@task.*todo" . | awk "{match(\$0, /due=([0-9T:\-]+)/, m); if (RLENGTH>0) print m[1], \$0; else print \"9999-99-99\", \$0}" |sort|cut -d" " -f2-')|copen

Dependencies

~17–30MB
~445K SLoC