Giter Club home page Giter Club logo

obsidian-linter's Introduction

Obsidian Linter

Build Downloads

This Obsidian plugin formats and styles your notes with a focus on configurability and extensibility. Rules can be toggled and configured in the settings. The main documentation on rules and other things are located on the wiki. Below is a quick run down of some reference links to the rules that exist and how to install the Linter.

Demo

Rules

Documentation for all rules can be found on the wiki. The docs are updated before the plugin is released, so they may not be completely accurate.

Each rule is its own set of logic and is designed to be run independently. This means that enabling certain rules together could cause undesired results. One such case would be using "Paragraph blank lines" with "Two Spaces Between Lines with Content". These two rules have some overlap in what they target to change which results in undesired or unexpected results since together they work differently than if they were run by themselves.

YAML rules

Heading rules

Footnote rules

Content rules

Spacing rules

Paste rules

Installing

As of version 0.9.7 of Obsidian, this plugin is available to be installed directly from within the app. The plugin can be found in the Community Plugins directory which can be accessed from the Settings pane under Third Party Plugins. The plugin is called Linter.

Manual installation

  1. Download the latest release
  2. Extract the obsidian-linter folder from the zip to your vault's plugins folder: <vault>/.obsidian/plugins/
    Note: On some machines the .obsidian folder may be hidden. On MacOS you should be able to press Command+Shift+Dot to show the folder in Finder.
  3. Reload Obsidian
  4. If prompted about Safe Mode, you can disable safe mode and enable the plugin.

How You Can Help

Contributions are welcome and appreciated. You can help in any of the following ways:

No repo setup required:

Varying repo and development setup required:

obsidian-linter's People

Contributors

alitekdemir avatar chrisgrieser avatar dependabot[bot] avatar ekil1100 avatar gavinmn avatar haloislet avatar hananoshikayomaru avatar hardwaylinka avatar iucario avatar jeppeklitgaard avatar lguenth avatar lifeek23 avatar lucible avatar magicwenli avatar mahtaran avatar marcelhas avatar michabrugger avatar mnaoumov avatar mokkacicc avatar muya avatar northword avatar ooopz avatar pjkaufman avatar platers avatar qazxcdswe123 avatar rea1shane avatar sewerynkras avatar tfthacker avatar victorflexcompute avatar windily-cloud avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

obsidian-linter's Issues

[BUG] multi line footnotes catastrophe linter moves only first line !!!

if i do text

lora ipsala [^note] dolores.

[^note]: This is not right

    - because the footnote takes more than one paragraph.
    - and linter does only move the first line.

    but not the rest of it

    it will mess up every multiline note instantly

this is not cool

it will destroy all all footnotes

Feature Request: Custom Date Updated Field Name

Thanks for the great plugin. I have a small FR, that we can customize the field name of date updated, for example, change it to modified.

By the way I have a small question: what is the syntax of yaml-timestamp format=? I wrote

yaml-timestamp format=YYYY-MM-DD HH:MM

and it told me invalid argument format. Seems like the space between YYYY-MM-DD and HH:MM is invalid.

Rule Suggestion: Convert between Tabs and spaces

First of all, thanks for the plugin! It's one of those little things saving a bit of time every day.

A rule that I would find very useful is the conversion between tabs and spaces. For me personally, this would be incredibly useful because all the notes I imported from earlier apps use spaces, but the various relationship line css snippets need tabs to work.

Rule line-break-at-document-end not recognized

I get a popup message "Rule line-break-at-document-end not recognized".
My rules:

trailing-spaces
space-after-list-markers
header-increment
re-index-footnotes
move-footnotes-to-the-bottom
line-break-at-document-end

Obisidian v0.12.15
Linter v1.1.5

[bug] Settings are gone

Since last plugin update i cant find the linter settings tab.

may because linter does lint every thing now?
except if i add YAML exclussion rules, i think this is a semi bad idea, people should be able to define the rules they want in settings, apply extra rules in YAML od deactivate rules in YAML, but people should not need to place YAML exclussions to all files because the want to exclude only one rule in general.

how ever ... thanks for your effort

Window Shifts After Linting

This plugin is so useful that I bound it to the hotkey Ctrl + S together with the save command. However, a tiny problem is that, after executing the lint command, the window will automatically shift up a fixed distance.

Large linting errors when the file has an additional YAML frontmatter section

I haven't been able to test this out further but just had to restore a few files from my version history because large duplications of content and messed up formatting occurred when there was a second instance of frontmatter.

Example:

---
frontmatter: at the top of the file
---

Contents of the file
Contents of the file

---
code block: with frontmatter
---
code
code

Using rules:

heading-blank-lines bottom="false"
consecutive-blank-lines
space-after-list-markers
yaml-timestamp format="YYYY-MM-DD" dateCreated="false"
compact-yaml
capitalize-headings
file-name-heading

Bug: "#" comments in code blocks are not headers

I found that Obsidian-Linter incorrectly treats C/Python/sh comments (#) in code blocks as "headers." In the example below, I didn't except any formatting changes, but this probably can't be easily fixed.

(Note: I this bug also applies to comments like #### H4 which would have been autocorrected to ## H2)

# Title

- Indented Code Block

    ```sh
    # Comment
    echo "Hello"

    echo "World!"
    ```

```python
# normal CODE
```

Becomes:

# Title

- Indented Code Block

    ```sh

# Comment

    echo "Hello"

    echo "World!"
    ```

```python

# Normal Code

```

With rules:

heading-blank-lines
header-increment
capitalize-headings titleCase=true

Check-Only vs. Autofix

I just started using Obsidian! I really like the mdlint package for VSCode that highlights errors in markdown without making changes. Would it be possible for a new feature that only checks on save rather than auto-fixes?

I haven't looked at the Plugin API, so I'm not sure how difficult it would be to display lint results (i.e. underline or highlight lines with errors then provide some sort of error message on hover). If too difficult, then that wouldn't be worth the effort

Handle abnormal capitalization in titleCase

Terms such as acronyms are not handled properly. It seems hard to support every edge case.
The rule could only apply to lowercase words, and ignore other words. I think this should be an option.

gitignore syntax in settings

Should be able to:

  1. *: enable all rules with default options, in default order
  2. ! to disable a rule
  3. Adding a rule overrides it in * with the given options

Compatibility issues with Excalidraw files

Hello,

At present, when all documents of the whole vault are processed in batches, the Excalidraw documents in vault will be broken.

It might be a good choice to provide a filter option to skip the specific folders.

Thank you.

FR: caltialize headers rule

Nice plug-in!

How difficult is it to add new rules? One that will reformat headers to Capitalized would be great!

Blank line created between 1st & 2nd level list items

Hi @platers,
Thanks for the useful plugin!

I've noticed an issue for a while and wanted to bring it up. I've tried to rule out any other plugins that might affect it

  • Test Vault with only the Linter Plugin enabled
  • Blank line created between 1st & 2nd level list items (List item, To-do Item, etc.)
  • All rules applied. I've disabled a few that looked like they might apply, but no luck

Here is a screen recording to display the issue

2021-09-24_14-08-59.mp4

Let me know if I can be of any further assistance

Option to respect fold state of headers / list items

I'm not sure if / how this would be possible but it would be great if the linter would respect the folded state of headers and list items. Currently if you lint a file with collapsed headers or list items, they are all expanded.

It also looks like linting the file bumps you out of any zoom level you are currently in with the Zoom plugin https://github.com/vslinko/obsidian-zoom. Not sure if this could be avoided as well.

Disabled Rules Not Working

In the setting I toggled on header-increment rule. In a Kanban file where I only use H2 headings without a H1 heading, I wrote disabled rules: [ header-increment ]. But linting still turn H2 headings into H1s.

Order of Rule Execution

Is there a specific order in which the rules are executed? Relevant for this point.

From your comment, I assume that it's the order in which they are listed by the user in the Linter settings, is that correct? Especially with increasing rule numbers, I think it might be worthy of consideration whether the order of rule execution is left to the user who might not factor in potential unintended effects or certain rule orders.

My suggestion would be to stipulate to execute rules in a specific order. This avoids undesired effects like for example running move-footnotes-to-the-bottom after the consecutive-blank-lines by an unsuspecting user.

Setting for Documents never to lint

Especially when using the "lint on save" setting, it is easily to accidentally lint a document that is not meant to be linted (e.g. templates or templater scripts, which annoyingly are still saved as .md ...).

May be setting to never lint certain files might make sense? This would prevent accidental linting. The Filename Header Sync Plugin has pretty much implemented this for files where headings should not be synced with the filename, I assume a bigger part of that code can be re-used.

Look into a markdown parser

Regex's are showing limitations in dealing with all the edge cases of markdown syntax such as #75. A parser like https://github.com/remarkjs/ will be necessary to handle edge cases. remark also has a linter built in, so many rules can be replaced with remarks implementations.

Rule Suggestion: Remove Hashtags (`#`) from YAML

  • Problem: tags in the YAML Header aren't autocompleted.
  • Solution: use hashtags
  • Subsequent Problem: Hashtags in YAML Header are invalid and need to be removed

I am currently using this templater script for that, but I think that this would be a wonderfully useful rule to have until we get autocomplete in the YAML header.

<%*
//get file content
var noteContent = tp.file.content;

//remove hashtags from YAML
noteContent = noteContent.replace (/^tags: ((?:#\w+(?: |$))+)$/im, function (tagsYAML){
	return tagsYAML.replaceAll("#","").replaceAll(" ", ", ").replace("tags:,","tags:");
});

//select all in note, return regexed content, move cursor to the top
let cmEditorAct = this.app.workspace.activeLeaf.view.editor;
cmEditorAct.setSelection({ line: 0, ch: 0 }, { line: 9999, ch: 9999 });
tR = tp.file.cursor(0) + noteContent;
%>

Rule Suggestion: Remove duplicate YAML Header

One thing that can happen due to merging of notes is that you have duplicate YAML headers.

However, I am not totally certain how to deal with that – in some cases, it makes case just to keep the YAML at the very top, in other cases, one would want to "merge" the YAMLs maybe? Maybe set this with an option?

Both cases could be a little bit tricky to implement, considering that you have to distinguish two hr with text between them from a wrong-placed YAML.

Format Tags in YAML doesn't work as expected

The rule "Format Tags in YAML" doesn't handle tags in the front matter formatted like

Tags:

  • #foo
  • #Bar

Applying the linter does nothing. The expected results were

Tags:

  • foo
  • Bar

My use case for this is that I find this style of lists in YAML to be more legible and easier to edit or remove a tag. I suspect the reason I start with the # is similar to others, we want auto-complete help when assigning tags.

Links go nowhere

The links in the plugin description try to open a browser I think? doesn't work on win 10/11:
image

`header-increment` and `file-name-heading` linting order

Problem. When the both rules are active and the current file has no H1, then after linting the document each header increments correctly but file-name-heading rule does not trigger at all.

Possible solution. Change the execution order for the two rules so that an H1 is added first by file-name-heading, and then other headers are incremented by header-increment.

Steps to reproduce

  1. Create a note:
    ## Header 2.1
    
    ## Header 2.2
    
    ### Header 3.1
    
  2. Apply header-increment and file-name-heading linting rules
  3. Expected result:
    # Header 1
    
    ## Header 2.1
    
    ## Header 2.2
    
    ### Header 3.1
    
  4. Actual result:
    # Header 2.1
    
    # Header 2.2
    
    ## Header 3.1
    

Use markdownlint

markdownlint is an existing semi-popular tool for markdown linting.
Using it provides you with more rules than this plugin. Rules that you can enforce outside of Obsidian, which makes people less dependent on the plugin and the rules more portable. It has a command line tool and a VSCode plugin among other things.

Without using markdownlint or consulting with existing plugin devs (Markdown prettifier, prettier) this is just another formatter with its own proprietary set of rules.

Improve Instructions for Contributions

I think with the last few commits, the contribution threshold increased quite a bit. It took me a while, for example, to figure out how to set a non-boolean option, since there was no "IntegerOption" or something equivalent I could copy. Also the new ignore-codeblock-fuction thing also took me a moment to figure out.

And locally disabling eslint-rules (see #36) is another problem potential contributors might struggle with, especially since examples often need wrong formatting, since you need to figure out eslint rules to make contributions (and also figure out, that it is eslint rules that you have to look for).

A brief expansion of the contribution guide where these things are addressed might help?

linter does not load


main.ts:66
Uncaught (in promise) TypeError: Cannot read property 'Format Tags in YAML' of undefined at LinterPlugin.eval (eval at <anonymous> (app.js:1), <anonymous>:11934:217) at Generator.next (<anonymous>) at fulfilled (eval at <anonymous> (app.js:1), <anonymous>:28:58)
  eval @ main.ts:66
  fulfilled @ tslib.es6.js:73
  Promise.then (async)    
  step @ tslib.es6.js:75
  eval @ tslib.es6.js:76
  __awaiter @ tslib.es6.js:72
  onload @ main.ts:12
  e.load @ app.js:1
  (anonymous) @ app.js:1
  (anonymous) @ app.js:1
  (anonymous) @ app.js:1
  s @ app.js:1
  Promise.then (async)    
  l @ app.js:1
  (anonymous) @ app.js:1
  o @ app.js:1
  t.loadPlugin @ app.js:1
  (anonymous) @ app.js:1
  (anonymous) @ app.js:1
  (anonymous) @ app.js:1
  (anonymous) @ app.js:1
  o @ app.js:1
  t.enablePlugin @ app.js:1
  (anonymous) @ app.js:1
  (anonymous) @ app.js:1
  (anonymous) @ app.js:1
  (anonymous) @ app.js:1
  o @ app.js:1
  t.enablePluginAndSave @ app.js:1
  (anonymous) @ app.js:1
  (anonymous) @ app.js:1
  (anonymous) @ app.js:1
  (anonymous) @ app.js:1
  o @ app.js:1
  (anonymous) @ app.js:1
  t.setValue @ app.js:1
  t.onClick @ app.js:1

Possible rule suggestion: Reformat & Re-Index Footnotes

Not sure whether this is something that fits with this plugin, but I think some reformatting of footnotes could also make sense. One example would to move all footnotes to the bottom after merging two or more notes, see also here. Another case could be the re-indexing of footnotes, which unfortunately, is not fully covered by the Tidy Footnotes Plugin.

For both cases, you could argue that they belong to some footnote plugin, or maybe to the longform plugin, but I think you could also make the case for those issues belonging to the linter. When you think they fit with the Linter, I could do a PR for it?

`convert-spaces-to-tabs` does not work

Testing exactly the rule from rules.ts at sites like regex101 or via a simple templater script, it does work as intended. When running tests with rules.ts, it also works.

But it does not seem to work in the linter. I assume it should therefore be sth related to the linter? :(

FR: Ignore Pattern

When editing Kanban files in markdown, the Linter changes break the Kanban format because they are converted from H2

Is it possible to add a regex like *Kanban* to skip certain files from lint on save? (manual linting should probably override this ignore rule)

Incorrect `file-name-heading` behaviour

Problem: linting inserts a file title incorrectly.

Steps to reproduce:

  1. Create a note with the following content

    Text 1
    
    ---
    
    Text 2
    
    
  2. Apply file-name-heading linting rule

  3. Expected result

    # Title
    
    Text 1
    
    ---
    
    Text 2
    
    
  4. Actual (incorrect) result

    
    Text 1
    
    ---
    # Title
    
    Text 2
    
    

I believe this case should be added as an exception for documents with no YAML variables.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.