obsidian-linter icon indicating copy to clipboard operation
obsidian-linter copied to clipboard

FR: Adjust rules for documents containing no H1, but only H2s (Obsidian 0.16)

Open chrisgrieser opened this issue 3 years ago • 3 comments
trafficstars

Is Your Feature Request Related to a Problem? Please Describe.

With Obsidian 0.16, we get inline titles and tab headers which make H1 redundant, resulting in some people like me to remove all their H1; my notes now only contain H2.

However, this makes some rules like "Header Increment" unusable, since without an H1, all H2s become H1, and All H3s H2 and so on. However, as described very well in this forum post, having multiple H1 in one document is also considered bad practice.

Describe the Solution You'd Like

Adjust rules like "header-increment" so that they also work for notes that do not contain H1s; maybe as an additional option?

In this regard, a rule like "there should be no H1 in your note" could also be worth considering.

Describe Alternatives You've Considered

Simply disabling all the affected rules. However, this would diminish the usefulness of the linter.

chrisgrieser avatar Sep 16 '22 13:09 chrisgrieser

Thanks for the feedback!

Is this something that only affects this one rule or are there more? I ask because I want to fully understand the scope of this.

Note that I will not have access to Obsidian 0.16.0 to test against until it is publicly released.

pjkaufman avatar Sep 16 '22 14:09 pjkaufman

I think it's mainly that one rule, maybe also "insert filename as H1", but it's debatable whether one should even enable it if one wants not to use any H1 anymore.

chrisgrieser avatar Sep 16 '22 14:09 chrisgrieser

Yeah. H2 is not a replacement for the title of a note, so I would not think that rule would need changing.

pjkaufman avatar Sep 16 '22 15:09 pjkaufman

bump This makes the Header Increment rule useless to me.

Calorion avatar Nov 28 '22 05:11 Calorion

I took a look at this and it seems it is easier said than done. Header increment does not increase the level of headers. It can only decrement them as it stands. Is my understanding correct that there is no need to increment existing headers or is this something where it is being asked that the rule be rewritten to also be able to account for incrementing headers?

I am asking to make sure I understand exactly what needs to be done for this since the latter would take more time to determine a functional change for.

Note that I am open to PRs in the meantime that would add this as I have been tied up with a couple of other rules and bug fixes.

pjkaufman avatar Nov 28 '22 13:11 pjkaufman

I did take a stab at this which is where the above question is coming from. It looks like header increment is designed solely for decrement values to make sure they are incrementing rather than setting a starting value. It is not impossible to change, but it may not be a simple change either. So it could be done for the next release if all goes well and there is a clear expectation of how it should work when H1's are present in the file.

pjkaufman avatar Nov 28 '22 13:11 pjkaufman

It totally increases the heading levels. If I have some h2s and h3s, and lint with no h1 in the body of the file, I will suddenly have h1s and h2s instead. All I want is an option to never increment to h1 and start at h2.

Of course if there are already h1s in the file, it should do exactly what it currently does.

Calorion avatar Nov 28 '22 16:11 Calorion

To clarify, the header values can increment. However it does this by decrementing any jumps in the number of headers. So it currently has no mechanism for converting an H1 to an H2. I can set the minimum header level, but it may not work as expected when an H1 is present as they would likely be converted to H2s while H2s would remain the same. Does that make sense?

pjkaufman avatar Nov 28 '22 16:11 pjkaufman

Here is an example of what I am thinking would happen before:

# H1 becomes H2
### H3 stays the same
####### H7
###### H6
## H2
###### H6
 _Note that incrementing starts at heading level 2, so H3s that come after an H1 or H2 will remain the same after the rule runes when the starting level is set to H2_

after:

## H1 becomes H2
### H3 stays the same
#### H7
### H6
## H2
### H6
_Note that incrementing starts at heading level 2, so H3s that come after an H1 or H2 will remain the same after the rule runes when the starting level is set to H2_

Does that make sense or is there something that should be changed about this behavior? I have it working with the above behavior, but I want to get feedback on it before I go ahead and merge it.

Edit: an added note is that an H1 followed by an H2 will not increment the H2 to an H3 as it has the same level as the previous header since saying H2 are the starting level means that they are the level that is left alone instead of the H1s.

pjkaufman avatar Nov 30 '22 00:11 pjkaufman

I am still trying to workout an algorithm that can accommodate both setups. But the above scenario is the output of the one I have come up with so far that just goes ahead and sets the minimum header level.

pjkaufman avatar Nov 30 '22 12:11 pjkaufman

Interesting. This is a tricky situation. I hadn't thought about what to do if there are existing H1s in the file.

Okay, let's try this:

We need one new Rule, and one new option for an existing Rule. The new Rule is the exact inverse of "File Name Heading"; let's call it "Remove File Name Heading." This will check to see if there is an H1 that matches the file name above any other headers. If so, it removes it.

The new option is what has been suggested in this Issue: an option for "Header Increment" called "Don't create H1s" (or whatever you want to call it).

This option would not remove any existing H1s, so the example you present above wouldn't be implemented. Instead, it would work like this:

"Don't create H1s" option

Option off

Current behavior

Option on

With existing H1

Example 1
Before
# H1
### H3
# H1
#### H4
###### H6

H1 at beginning of file: same as existing behavior
After
# H1
## H3
# H1
## H4
### H6

H1 at beginning of file: same as existing behavior
Example 2
Before
### H3
#### H4
# H1
#### H4
###### H6

No H1 at beginning of file: No header promoted beyond H2; H1s left alone
After
## H3
### H4
# H1
## H4
### H6

No H1 at beginning of file: No header promoted beyond H2; H1s left alone

So the Rule, with this option on, does not touch existing H1s, but will not promote headings above H2. Why? Because the new way isn't "don't use H1s"; it's "treat the file as having the file name as an H1 at the top, because that's what Obsidian's new 'Show inline title' option does."

Without existing H1

Before
### H3
#### H4
## H2
#### H4
###### H6

Nothing gets promoted above H2
After
## H3
### H4
## H2
### H4
#### H6

Nothing gets promoted above H2 

Calorion avatar Nov 30 '22 17:11 Calorion

Interesting. This is a tricky situation. I hadn't thought about what to do if there are existing H1s in the file.

Okay, let's try this:

We need one new Rule, and one new option for an existing Rule. The new Rule is the exact inverse of "File Name Heading"; let's call it "Remove File Name Heading." This will check to see if there is an H1 that matches the file name above any other headers. If so, it removes it.

The new option is what has been suggested in this Issue: an option for "Header Increment" for "Don't create H1s" (or whatever you want to call it).

This option would not remove any existing H1s, so the example you present above wouldn't be implemented. Instead, it would work like this:

"Don't create H1s" option

Option off

Current behavior

Option on

With existing H1

Example 1
Before
# H1
### H3
# H1
#### H4
###### H6

H1 at beginning of file: same as existing behavior
After
# H1
## H3
# H1
## H4
### H6

H1 at beginning of file: same as existing behavior
Example 2
Before
### H3
#### H4
# H1
#### H4
###### H6

No H1 at beginning of file: No header promoted beyond H2; H1s left alone
After
## H3
### H4
# H1
## H4
### H6

No H1 at beginning of file: No header promoted beyond H2; H1s left alone

So the Rule, with this option on, does not touch existing H1s, but will not promote headings above H2. Why? Because the new way isn't "don't use H1s"; it's "treat the file as having the file name as an H1 at the top, because that's what Obsidian's new 'Show inline title' option does."

Without existing H1

Before
### H3
#### H4
## H2
#### H4
###### H6

Nothing gets promoted above H2
After
## H3
### H4
## H2
### H4
#### H6

Nothing gets promoted above H2 

I can take a look at doing this. The main problem I see is the decrement logic will not play well with this since it is calculated by the difference between the current and last header encountered. It can be mitigated, but this is not generally a simple change to make it work this way.

pjkaufman avatar Nov 30 '22 17:11 pjkaufman

The requested change should now be available on master and should go out in the next release. It should treat H1s as a reset point for the increment level when the setting for starting at heading level 1 is active. This means the following:

# H1
## H2
### H3
#### H4
# H1
##### H5

becomes

# H1
## H2
### H3
#### H4
# H1
## H5

pjkaufman avatar Dec 08 '22 02:12 pjkaufman

sorry, I am a bit confused – the issue is about documents with no H1, but your example contains multiple H1?

chrisgrieser avatar Dec 08 '22 11:12 chrisgrieser

sorry, I am a bit confused – the issue is about documents with no H1, but your example contains multiple H1?

Yes. The example provided is to show what happens if an H1 already exists (they will not be affected, but they will be treated as reset points for what the next level should be).

So if you have no H1 in the file to start with, you will end with no H1 in the file:

### H3
#### H4
#### H4
##### H5
## H2

becomes

## H3
### H4
### H4
#### H5
## H2

Does that clear things up?

pjkaufman avatar Dec 08 '22 15:12 pjkaufman

If this is a request to increment headers that are H1s, that may cause the rule to be inefficient. I have tried to think up a good way of knowing how to properly shift values up 1, but so far I have come up blank on that.

pjkaufman avatar Dec 08 '22 15:12 pjkaufman

In other words, H1 will not be a value that can be affected by this rule. It will be ignored and it will treat H2s like the new H1.

pjkaufman avatar Dec 08 '22 15:12 pjkaufman

so essentially what the rule now does is to ensure no heading level is skipped?

chrisgrieser avatar Dec 08 '22 16:12 chrisgrieser

so essentially what the rule now does is to ensure no heading level is skipped?

It is hard for me to explain clearly. It makes sure that headings are incremented from the minimum level up. Anything below the minimum level is ignored and the next header after an ignored header will become the minimum level.

The default behavior is the minimum level is 1 and everything is incremented from there with the appropriate decrements applied.

With the option to start at heading level 2, the minimum level is 2, so when decrementing/setting heading levels the lowest it will go is 2. It does not touch heading level 1 headers since I have not come up with a good approach for this yet that may not mess up heading nesting. I have an idea I want to try for it later today, but I am not sure if it will work.

pjkaufman avatar Dec 08 '22 18:12 pjkaufman

I see, I think I got it now. Could be worth coming up with a good description, so that users won't be confused what the rule actually does 🤔

chrisgrieser avatar Dec 08 '22 18:12 chrisgrieser

You may wish to consult my example and explanation above: https://github.com/platers/obsidian-linter/issues/412#issuecomment-1332492585

Calorion avatar Dec 08 '22 21:12 Calorion

The irony is that I think I just found a simple solution to what I initially wanted to do. I will see if all tests pass. But essentially what I wanted to do to make this work was to go ahead and add 1 to the header level prior to checking the header level info. This allows it to automatically shift H1s to H2s and H2s to H3s and so on and so forth. This way the decrement feature can still work and make sure that everything is properly offset. It should be much clearer what this means than the ignoring of H1s. Fingers crossed that it works.

pjkaufman avatar Dec 08 '22 22:12 pjkaufman

It seems to have passed. Here is what it will look like with the change (all headers are incremented by 1 level and then the header increment can run with the absolute minimum level being 2 for the headings):

When an H1 exists

before:

# H1
## H2
### H3
#### H4
# H1
##### H5

after:

## H1
### H2
#### H3
##### H4
## H1
### H5

When no H1 exists

before:

### H3
#### H4
#### H4
##### H5
## H2

after:

## H3
### H4
### H4
#### H5
## H2

Summary

The key difference here is that instead of ignoring H1s, it will go ahead and make H1s conform with the header increment rule by promoting them to the H2 level. This should get rid of all H1s present.

pjkaufman avatar Dec 08 '22 22:12 pjkaufman

The change should be much more straight forward and much less Jerry rigged to make it work.

pjkaufman avatar Dec 08 '22 22:12 pjkaufman