Docker Compose (recommended)
First, create a folder notegraf
.
Then, within that folder, create a docker-compose.yml
file.
notegraf
└── notegraf_config.yml
# docker-compose.yml
version: '3'
services:
db:
image: postgres:14
restart: always
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_DB: notegraf
LANG: C.UTF-8
volumes:
- dbdata:/var/lib/postgresql/data
notegraf:
image: ghcr.io/caizixian/notegraf:master
restart: always
depends_on:
- "db"
ports:
- "8000:8000"
environment:
NOTEGRAF_HOST: "0.0.0.0"
NOTEGRAF_PORT: 8000
NOTEGRAF_NOTESTORETYPE: "PostgreSQL"
NOTEGRAF_DATABASE_HOST: "db"
NOTEGRAF_DATABASE_PORT: 5432
NOTEGRAF_DATABASE_USERNAME: postgres
NOTEGRAF_DATABASE_PASSWORD: password
NOTEGRAF_DATABASE_NAME: notegraf
NOTEGRAF_DEBUG: false
volumes:
dbdata:
Within the folder, run docker-compose up -d
.
Your Notegraf instance should be up and running.
Open http://localhost:8000 in your browser and see for yourself.
To update Notegraf, run docker pull ghcr.io/caizixian/notegraf:master
and run docker-compose up -d
again.
Inline math
`${a^2 + b^2 = c^2}$`
Display mode math:
```math
a^2 + b^2 = c^2
```
Developer Guide
Prerequisite
- Rust toolchain installed via https://rustup.rs/. Tested with 1.62.0.
- Node.js. Tested with 16.x LTS and 18.x.
- PostgreSQL. Tested with 14. On macOS with Homebrew installed, simply
brew install postgresql
, and follow the instructions in the installation caveats.
Build from Source
git clone https://github.com/caizixian/notegraf.git
cd notegraf/notegraf-web
npm install
cargo build
Setup Development Server
First, you need to create a database, e.g., via createdb notegraf
.
Then, under notegraf/notegraf-web
, create the following two files.
notegraf
├── ...
└── notegraf-web
├── ...
├── .proxyrc.js
└── configuration.yml
// .proxyrc.js
const {createProxyMiddleware} = require("http-proxy-middleware");
module.exports = function (app) {
app.use(
createProxyMiddleware({
// localhost on macOS can also resolve to ::1
// python3 -c 'import socket; print(socket.getaddrinfo("localhost", 8000))'
// https://stackoverflow.com/questions/15227154/inexplicable-node-js-http-throwing-connect-econnrefused-ipv6
target: "http://localhost:8000/",
pathFilter: ["/**", "!/", "!**/*.html", "!**/*.js", "!*.css", "!**/*.css", "!**/*.map", "!**/*.ttf", "!**/*.woff", "!**/*.woff2", "!**/*.svg", "!**/*.png"],
})
);
};
# configuration.yml
port: 8000
notestoretype: "PostgreSQL"
debug: true
database:
host: localhost
port: 5432
name: notegraf
Finally, open two terminal windows.
In the first window, run cargo run
under notegraf/notegraf-web
, and in the other window, run npm start
.
Your browser should automatically navigate to http://localhost:1234.
Project Structure
The repo is set up as a cargo workspace with two crates.
notegraf
├── ...
├── notegraf <- Notegraf core data types and persistence logics
└── notegraf-web <- Notegraf HTTP frontend and web UI
Pre-commit
cargo check && cargo test && cargo clippy && cargo fmt
.
Search Syntax
A search query contains zero or more search terms, separated by spaces.
If any positive lexeme term is specified, results are ordered by relevance for the PostgreSQL backend. If no positive lexeme term is specified, results are ordered by their creation time (newer notes come first) regardless the backend. In any other case, the order is unspecified.
If no positive lexeme term is specified, results are limited to 10 notes by default, unless a !limit=<integer>
modifier is used.
Lexeme Terms
- Positive lexeme term: a plain word, such as
token
, will be searched against the title and the note body. - Negative lexeme term: prefix a word with
-
to exclude the word, such as-exclude
.
Tag Terms
- Positive tag term: a hashtag, such as
#token
. - Negative tag term: prefix a hashtag with
-
to exclude the tag, such as-#exclude
.
Modifier Terms
!notag
: match notes with no tags.!orphan
: match notes that have no previous note, no parent note (i.e., not a branch of another note), and not referenced by other notes.!limit=<integer>
: control the number of notes returned in the result to be<integer>
.!nolimit
: return all notes that match. This takes precedence over!limit=<integer>
.
Changelog
Unreleased
Added
- [Web UI] Better typographic punctuations.
Changed
- [Web UI] Set the page height to be the viewport height to allow two panes in the note search result/revision view to be scrolled independently.
Deprecated
Removed
Fixed
- [Web UI] Replace all occurrences of
<URL origin>/note/
in the note body (see v0.1.1 release) instead of just the first one. - [Core] Fix that deleting a note in a sequence might result in inconsistent parent/children or previous/next relationship.
Security
v0.1.1 (2022-09-12)
Changed
- [Web UI] "Hyperlinks" in the note title and the backlinks/branches are now real hyperlinks, rather than clickable texts. (#206)
- [Web UI] Any occurrence of
<URL origin>/note/
in the note body will be treated as cross-links, and therefore be replaced bynotegraf:/note/
. (#206)
Fixed
- [Web UI] When showing note titles for branches or backlinks, the (transitive) suffix (indicating that the title shown is actually the title of the closest ancestor) will be placed on the same line as the title. (#206)
- [Web UI] When a new editing session (editing an existing note, creating a new note, etc.) is created without user interaction, the current page is replaced by, instead of being navigated away from, the editor UI. This is so that when a user navigate back to the previous page, it expectedly shows the original page where the user clicked a button. (#206)
- [Web UI] When creating a task with a link (such as
- [x] [link](https://example.com)
) in Markdown lists, the checkbox is now aligned properly with the link. (#227)
v0.1.0 (2022-08-30)
Initial release.