| Crates.io | patto |
| lib.rs | patto |
| version | 0.3.0 |
| created_at | 2024-11-23 10:43:40.061666+00 |
| updated_at | 2025-12-24 23:57:19.237705+00 |
| description | 🪽 Yet another plain text format for quick note taking and task management |
| homepage | https://github.com/ompugao/patto |
| repository | https://github.com/ompugao/patto |
| max_upload_size | |
| id | 1458380 |
| size | 2,335,899 |
A simple plain-text format for quick note-taking, outlining, and task management, powered by language server.
Patto Note is a text format inspired by Cosense (formerly Scrapbox), designed for outlining, quick note-taking and task management. It works with your favorite editor, powered by the Language Server Protocol. Unlike Markdown, patto note is line-oriented; 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.
line property (please refer to the syntax section below)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'
[@table caption="sample table"]
header column1 column2 column3 column4
row1 item1 item2 item3 item4
row2 item5 item6 item7 item8
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://placehold.co/100.png "alt string"]
Code highlight with highlight.js
[@code python]
import numpy as np
print(np.sum(10))
[` inline code `]
Math with MathJax
inline math: [$ O(n log(n)) $]
[@math]
O(n^2)\\
sum_{i=0}^{10}{i} = 55
which is rendered as follows:
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.!2024-12-31*2024-12-31-2024-12-31.pn, or :new and :set syntax=patto[ and @, lsp client will complete links and snippets respectively
:LspPattoTasks command; that will gather tasks from the notes in your workspace and show them in a location window.:LspPattoTwoHopLinks command (only in neovim, currently).Please download binaries from GitHub release
If you use jdx/mise:
mise use -g github:ompugao/patto
mise use -g cargo:patto
or, use cargo:
cargo install patto
This will install the following utilities:
patto-lsp: a lsp serverpatto-preview: a preview server for your patto notespatto-markdown-renderer: export patto notes to markdown (Standard, Obsidian, GitHub flavors)patto-html-renderer: a format converter from patto note to htmlcall plug#begin()
Plug 'prabirshrestha/asyncomplete.vim'
Plug 'prabirshrestha/asyncomplete-lsp.vim'
Plug 'prabirshrestha/vim-lsp'
Plug 'ompugao/patto', {'for': 'patto'}
call plug#end()
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')
vim.lsp.config('patto_lsp', {}) -- for note management
vim.lsp.config('patto_preview', {}) -- for preview server
vim.lsp.enable({'patto_lsp', 'patto_preview'})
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.
g:patto_enable_open_browser: Set to 1 to enable automatic browser opening for the preview server (default: disabled)patto-lsp can suggest entries from your Zotero library while completing [ links when it is built with the zotero cargo feature (e.g. cargo install patto --features zotero).
$XDG_CONFIG_HOME/patto/patto-lsp.toml (defaults to ~/.config/patto/patto-lsp.toml).[zotero]
user_id = "1234567"
api_key = "zotero_api_key"
endpoint = "http://127.0.0.1:23119/api" # optional: talk to local Zotero desktop
(Uppercase keys such as ZOTERO_USER_ID/ZOTERO_API_KEY/ZOTERO_ENDPOINT are also accepted.)
When configured, patto-lsp will log the Zotero connection status on startup and include matching papers as completion candidates in the form paper title zotero://select/library/items/<ITEM_ID>. Use the endpoint setting to target the Zotero desktop application's local API (default remains the public https://api.zotero.org).
To keep completions fast even when the Zotero API is slow, patto-lsp periodically refreshes and stores the full paper list at $XDG_CACHE_HOME/patto/paper-catalog.json (or the platform-specific equivalent) and serves completion items from that cache.
For enhanced task viewing with deadline sorting and categorization:
Plug 'folke/trouble.nvim'
After installing trouble.nvim, you can use:
:Trouble patto_tasks
This will display tasks organized by deadline categories (Overdue, Today, This Week, etc.) with automatic sorting.
Released from v0.2.2. You can install from HERE, supporting content preview and task management.
| column separators> blockquote syntax[@table] block element for structured dataplease refer to todo
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 (ref Code Block Indentation):
print('hello')
Please use your favorite template/snippet engine of your editor. I personally use LuaSnip in neovim.
Other candidate vim plugins:
Export your patto notes to markdown with the patto-markdown-renderer command:
# Standard markdown (CommonMark-compatible)
patto-markdown-renderer -f note.pn -o note.md
# Obsidian-native format
patto-markdown-renderer -f note.pn -o note.md --flavor obsidian
# GitHub-flavored markdown
patto-markdown-renderer -f note.pn -o note.md --flavor github
# Pipe from stdin to stdout
echo "Hello [* world]" | patto-markdown-renderer
# Output: Hello **world**
# Read from stdin, write to file
cat note.pn | patto-markdown-renderer -o note.md
| Feature | Standard | Obsidian | GitHub |
|---|---|---|---|
| WikiLinks | [note](note.md) |
[[note]] |
[note](note.md) |
| Tasks | - [ ] task (due: date) |
- [ ] task 📅 date |
- [ ] task (due: date) |
| Anchors | <a id="name"></a> |
^name |
<!-- anchor: name --> |
| Frontmatter | No | Yes | No |
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