Obsidian-Code-Styler
Obsidian-Code-Styler copied to clipboard
Make compatible with Obsidian Publish
I have been having difficulty writing CSS to add line numbers to an Obsidian Publish site (so in the publish.css file). I would like to use the Code Styler for this, but plug-ins are not allowed on Obsidian Publish.
I realize this is a weird request, but is there any chance you can help me extract out the relevant lines of code from your styles.css file so I can transfer them to my publish.css file?
For the record, this is the best I have gotten using copilot and google, but the line numbers are incrementing incorrectly (at each code style change rather than each line) and are colliding. Also, the code I am testing is an R block, and the css below is specific to R rather than a general case like your plug-in.
.is-loaded.language-r {
counter-set: line 0;
display: block;
white-space: pre-wrap;
position: relative;
padding-left: 3em;
}
.language-r code > span::before {
content: counter(line);
counter-increment: line;
position: absolute;
left: 0;
width: 2em;
text-align: right;
color: #f00;
border-right: 1px solid #ddd;
padding-right: 0.5em;
Thanks so much for any help.
So I"m doing a big refactor atm, partially because of how rubbish and challenging to understand the old CSS was. I actually wouldn't be able to help you there as I don't understand what I've written there at the moment in its entirety, only when translating it. Having said that, there's a couple of key classes to look for, particularly the class that includes line-number.
Despite this, I'm not sure what the goal is since the CSS with Code Styler would only apply to the DOM/HTML structure that code styler provides. If you apply it to pure Obsidian rendered html in publish it won't work because it won't find the added elements code styler adds.
Before I worked on this plugin, I had a go at doing this by pure CSS and I'll share my attempt for line numbers below. (If you want to see more of the attempts like headers, titles and buttons etc, just lmk). But I don't think this worked in the end in most edge cases, only working in ideal scenarios (and tbh it's been so long I'm not sure it ever did). Anyways, this is the code:
body:not(.no-codeblock-line-numbers) .HyperMD-codeblock-begin {
counter-reset: codeblock-line-numbers;
}
body:not(.no-codeblock-line-numbers) .HyperMD-codeblock:not( .HyperMD-codeblock-begin, .HyperMD-codeblock-end)::before {
counter-increment: codeblock-line-numbers;
content: counter(codeblock-line-numbers);
font-size: var(--code-size);
line-height: 2;
text-align: right;
width: 1.7em;
color: var(--text-muted);
background-color: rgba(0,0,0,0);
position: relative;
left: 0px;
top: 0px;
padding-right: 15px;
}
And an example of it working in Live Preview. Not sure this helps at all since Publish will be more similar to reading view than live preview.
Happy to try and help though! You say the counter changes on each code style? Is that each type of token? i.e. punctuation, constants, functions etc.? In Reading mode, the issue is there are no clear lines in DOM structure, only inner HTML so you can't do this for each line. One attempt would be to find some invisible character you put at the start of each line that can be easily identified by its class (or added class? I can't recall if you can do this) and use that to increment the numbers. Otherwise if you could identify the line breaks somehow with CSS and select those, that should work too but I don't think it's possible with CSS. Either way keep me updated!
If anyone has further information on how plugins can be added to publish via none pure css, that would be helpful, a cursory search doesn't give much info.
Thanks so much for the help - I clearly know very little css!
With a simple line like below, there are 4 styles because it colors the letters and parentheses differently.
library(tidyverse)
In obsidian, with the css I pasted above when creating the issue, the web inspector html for this area looks like this:
<div class="el-pre">
<pre class="language-r" tabindex="0">
<code data-line="0" class="language-r is-loaded">
library
<span class="token punctuation">
(
</span>
tidyverse
<span class="token punctuation">
)
</span>
</code>
</pre>
</div>
So, it does look like there is some token for punctuation that is messing with the line count. Another suggestion that copilot had is pasted below... and it does like what you said... only adds line numbers where there is "token punctuation", looking like this in Obsidian:
.el-pre {
position: relative;
}
.is-loaded.language-r {
counter-reset: line;
display: block;
white-space: pre-wrap;
position: relative;
padding-left: 3em;
}
.language-r {
display: block;
}
.language-r code > span {
display: block;
position: relative;
padding-left: 3em;
}
.language-r code > span::before {
counter-increment: line;
content: counter(line);
position: absolute;
left: 0;
width: 2em;
text-align: right;
color: #f00;
border-right: 1px solid #ddd;
padding-right: 0.5em;
}
So perhaps it just needs to ignore the tokens somehow? But then again, it is only adding line numbers for those tokens... so I'm not sure.
The issue is that any line of code will start with a different class (called tokens) is its punctuation, a function, a constant etc. and unless you write VERY VERY specific code, you won't know what the starting token is. Thats why I suggested adding a character where you know the token to the starting of each line (and somehow select specifically that element if other elements with that class exist, or choose a rare token that never? (read very rarely) comes up in code).
Not really sure how I would do that but the way to go is try different characters (search for invisible charcters) see what class they get and see if nothing else gets that class. If they all get no class which is pretty likely then oh no. Honestly it's very very hard and that's why this plugin has to use JavaScript!