Linter
The linter enforces rules on your notes to ensure their syntax is consistent and makes easy to find them later. It’s particularly interesting as your collection of notes grows over time.
Configuration
The linter reads its configuration from the YAML file .nt/lint
. No file exists by default. Ex:
rules:- name: min-lines-between-notes args: [2]- name: no-dangling-media- name: no-dead-wikilink
Rules are declared under the attribute rules
. Some rules accept arguments using the attribute args
(array of primitive values) and you may restrict a rule to a subset of your notes using the attribute includes
(array of glob path expressions).
Rules
Rule | Description | Arguments |
---|---|---|
no-duplicate-note-title | Enforce no duplicate between note titles inside the same file | - |
no-duplicate-slug | Enforce no duplicate slugs between notes across files | - |
min-lines-between-notes | Enforce a minimum number of lines between notes |
|
max-lines-between-notes | Enforce a maximum number of lines between notes |
|
note-title-match | Enforce a consistent naming for notes |
|
no-dangling-media | Path to media files must exist | - |
no-dead-wikilink | Links between notes must exist | - |
no-extension-wikilink | No extension in wikilinks | - |
no-ambiguous-wikilink | No ambiguity in wikilinks | - |
require-tag | At least one tag on quotes (must match the optional pattern) |
|
check-attribute | Attributes must satisfy their schema if defined (see below) | - |
no-duplicate-note-title
Configuration:
rules:- name: no-duplicate-note-title
Example (with violations highlighted):
# Example
## Note: The same title is allowed on different types
This is a note.
### Flashcard: The same title is allowed on different types
This is a flashcard.
## Note: Long title must be unique inside a file
This is a note.
## Note: Long title must be unique inside a file
This is a note with the same title.
no-duplicate-slug
Configuration:
rules:- name: no-duplicate-slug
Example (with violations highlighted):
# Example
## Note: The slug attribute is supported
`@slug: note1`
This is a note.
### Note: The same slug cannot be reused
`@slug: note1`
This is a note.
## Note: Slugs must be compatible with URLs
`@slug: not a valid slug`
This is a note.
min-lines-between-notes
Configuration:
rules:- name: min-lines-between-notes args: - 2
Example (with violations highlighted):
# Example
## Note: One
This is the first note.
## Note: Two
This is the second note.
## Note: Three
This is the third note.## Note: FourThis is the fourth note.
max-lines-between-notes
Configuration:
rules:- name: max-lines-between-notes
Example (with violations highlighted):
# Example
## Note: One
This is the first note.
## Note: Two
This is the second note.
## Note: Three
This is the third note.
## Note: FourThis is the fourth note.
note-title-match
Configuration:
rules:- name: note-title-match args: - "^(Note|Reference):\s\S.*$"
Example (with violations highlighted):
# Example
## Note: Example
A title matching the regular expression `(Note|...):\s\S.*`.
## neference: Example
The type is in lowercase (allowed but enforced by the linter).
no-dangling-media
Configuration:
rules:- name: no-dangling-media
Example (with violations highlighted):
# Example

no-dead-wikilink
Configuration:
rules:- name: no-dead-wikilink
Example (with violations highlighted):
# Example
## Note: A
[[#B]][[#Note: B]][[unknown.md]]
## Note: B
[[no-dead-wikilink.md#Note: A]][[no-dead-wikilink#Note: A]]
no-extension-wikilink
Configuration:
rules:- name: no-extension-wikilink
Example (with violations highlighted):
# Example
## Note: Link 1
[[no-extension-wikilink#Note: Link 2]]
## Note: Link 2
[[no-extension-wikilink.md#Note: Link 1]]
## Note: Link 3
[[no-extension-wikilink]]
## Note: Link 4
[[no-extension-wikilink.md]]
no-ambiguous-wikilink
Configuration:
rules:- name: no-ambiguous-wikilink
Example (with violations highlighted):
# Example
[[books.md]][[notes/books.md]][[reviews/books.md]]
require-tag
Configuration:
rules:- name: require-tag args: - "^(life|favorite)$"
Example (with violations highlighted):
# Example
## Quote: No Tag
`@name: Anonymous`
This is the first quote.
## Quote: Tag
`@name: Anonymous``#useless`
This is the second quote.
check-attribute
Configuration:
rules:- name: check-attribute
schemas:
- name: Quotes type: quote path: references attributes: - name: name aliases: [author, illustrator] type: string required: true
Example (with violations highlighted):
# Example
## Note: Marcus Aurelius On Others
> What’s bad for the hive is bad for the bee.
## Quote: Summum Bonum
Just that you do the right thing.
## Quote: Memento Mori
`@author: Marcus Aurelius`
You could leave life right now. Let that determine what you do and say and think.
Schemas
Schemas are used to defined attributes and must follow this structure:
schemas:
- name: Quotes # A name used when reporting violations type: quote # Restriction on the note types path: references # Restriction on the note path (glob pattern) attributes: # Define a list of attributes - name: name # The attribute name aliases: [author] # Optional aliases for the attribute name type: string # One of: string[], string (default), bool, number, object required: true # Mandatory? (default: false) inherit: true # Attribute is inheritable by sub-notes? (default: true)
Default schemas (important for the inner working of the application) are predefined:
schemas:
- name: Hooks attributes: - name: hook type: string[] inherit: false
- name: Tags attributes: - name: tags type: string[]
- name: Relations attributes: - name: source inherit: false - name: references type: string[] - name: inspirations type: string[]
Declaring attributes as array
is convenient as value will automatically be appended to existing values:
---tags: life # Same as tags: [life]---
# A Note
`@tags: life-changing` `#favorite`
This note will have the tags `#life`, `#life-changing`, and `#favorite`.