Plugin: Rich Markdown

That makes sense to me, I think it's possible to get the Joplin setting so this feature can be toggled on and off from the markdown menu as usual.

I'll look into it.

1 Like

This plugin is great! :smiley_cat: thanks for making it :partying_face:

1 Like

Sorry I missed this before. To clarify, you're customizing the hr in your css like so?

.cm-hr {
  border-top: 1px solid #777;
  display: block;
  line-height: 0px;
}

If that's the case I've added some new css that you'll need to use instead. It will be available in v0.4.0.

1 Like

Thanks for clearing that point, I wasn't sure how far I could go with the css requests.

Yeah, that's what I meant. I updated my css, just have to wait for the update now.

I had some fun with the CSS to get the Markdown styling even nicer to read.
I was tired of the multi-colors and in general was just looking to simplify the look. Really happy with how easy it was with the extra CSS classes!

Here's the code:


span.cm-rm-checkbox.cm-property + span.cm-rm-checkbox + span.cm-rm-checkbox {
	/*adds a strike through on completed checkmarks*/
	text-decoration: line-through;
	opacity: 0.7;
}

  .CodeMirror-sizer {
  	/*keeps the text width manageable*/
  margin-right: auto !important;
  margin-left: auto !important;
  max-width: 80ch !important;
  line-height: 2.3ch !important;
}

.cm-hr {
	/*makes `---` solid*/
  border-top: 1px solid #cccccc;
  display: block;
  line-height: 0px;
}

.cm-s-default *{
	/*makes all text black*/
	color: black !important;
}
.cm-header.cm-rm-header-token{
	/*makes the markdown #, ##, ###, etc less noticable*/
	color: #cccccc !important;
    font-size: 90%; 
    margin-left: -50px;
    max-width: 50px;
    width: 50px;
    overflow: hidden;
    display: inline-block;
    text-align: right;
}

Not all of this is my invention, found lots of inspiration from previous posts, thanks!

(NOTE: requires turning on "Add additional CSS classes for enhanced customization" in the Settings).

9 Likes

Thanks for sharing @uxamanda, it looks great! I've been thinking that it would be nice to have some cohesive themes added to the repo. Would you mind if I added this to the repo? (With credit of course).

1 Like

That's brilliant, the editor looks very good like this. It's like we're getting close to Typora but without hiding any markup. Perhaps we could set this CSS as default on the main app?

8 Likes

Sure, see below for probably a better default.

I still have on my list to do a deep dive into easy theming. My dream is to build (collaborate? :stuck_out_tongue: ) on a plugin that allows a user to quickly choose colors like you can in Slack. It would also allow for basic changes like Condensed/Regular (less line height), Max Width of editor, Header size difference (make each header x times larger than the next, and let the user slide to change X) with some preset themes for what you generally work on "journaling", "code notes / math", "night mode" etc.

I still haven't looked into how the new color variables work in the app. I see references to things like "var(--joplin-font-family)", but I can't see where they are set. It seems like they are JS values not CSS values, so I don't think they can easily be changed by the user and would be better handled by a plugin. Is that the case or am I missing something?

To answer your question of default theme, I cleaned up my CSS above to make it less extreme (added some colors back). This might be a better default.

:root {
    --color-dark: #3e3e3e;
    --color-medium: #ccc;
    --color-light: #f1f1f1;
    --color-base: #fff;
    --color-actionable: dodgerblue; 
}

span.cm-rm-checkbox.cm-property + span.cm-rm-checkbox + span.cm-rm-checkbox {
	/*adds a strike through on completed checkmarks*/
	text-decoration: line-through;
	opacity: 0.7;
}

  .CodeMirror-sizer {
  	/*keeps the text width manageable*/
  margin-right: auto !important;
  margin-left: auto !important;
  max-width: 80ch !important;
  line-height: 1.6em !important;
}

.cm-s-default .cm-hr {
	/*makes `---` like a musical staff, cause... Joplin :-) */
    border-top: 1px solid var(--color-medium);
    color: var(--color-medium) !important;
    display: block;
    line-height: 1px;
    width: 100%;
}


.cm-overlay, .cm-variable-2.cm-overlay, .cm-variable-3.cm-overlay, .cm-variable-4.cm-overlay, .cm-variable-5.cm-overlay, .cm-variable-6.cm-overlay{
	/*makes markdown-specific things fade back, i.e. _ and ** in bold and italic*/
		color: var(--color-medium) !important;
}


.cm-s-default .cm-header{
	/*changes header color*/
	color: var(--color-dark) !important;
}

 .cm-variable-2,.cm-variable-3,  .cm-variable-4, .cm-variable-5,.cm-variable-6{
	/*changes list color*/
	color: var(--color-dark) !important;
}
.cm-header.cm-rm-header-token{
	/*makes the markdown #, ##, ###, etc less noticable*/
	color: var(--color-medium) !important;
    font-size: 70%; 
    margin-left: -50px;
    max-width: 50px;
    width: 50px;
    overflow: hidden;
    display: inline-block;
    text-align: right;
    direction: rtl; 
}
.cm-header.cm-rm-header-token:before {
	/*this plus the `    direction: rtl;` in the header token are a hack to add space between the markdown ## and the header*/
	content: '--'  !important;
	color: transparent;
}

.cm-s-default .cm-comment {
	/*affects the code background*/
    background: var(--color-light);
}

.cm-jn-monospace {
	/*affects the code block background*/
    background: var(--color-light);
    letter-spacing: 0.1em;
}

.cm-rm-checkbox {
	/*changes the checkbox*/
    background: transparent;
    color: dodgerblue !important;
}


span.cm-rm-link, .cm-variable-2.cm-rm-link, .cm-variable-3.cm-rm-link, .cm-variable-4.cm-rm-link, .cm-variable-5.cm-rm-link, .cm-variable-6.cm-rm-link {
	/*changes links*/
    color: var(--color-actionable) !important;
}

5 Likes

These variables are readonly so indeed the plugin you mentioned wouldn't be currently possible. In any case, these variables are derived from the theme file so perhaps the way to go is to allow creating a custom theme from a plugin, which shouldn't be too hard to implement.

Once that's done, it should be possible to dynamically set the values from a config screen (although restarting the app might be necessary, I'm not sure).

Oh nice, that looks straightforward, I don't think restarting the app is a deal killer. I am going to put mention it as a plugin feature request and see if anyone is interested in collaborating.

@uxamanda @laurent
Just out of coincedence I found this online editor which is meant to be demoing a specific font, but it uses a codemirror instance for text input. It seems to use the same trick that you used @uxamanda but the hash tags pop over before the space is input, which feels more natural. I think this website has some good examples for what can be done with Joplin. But it also demonstrates what we should avoid (try entering a code block for example, or try ---).

Yea, I would prefer that! Mine pops over as soon as the class is detected.

(I will say that I hope it doesn't break the inline tags plugin though... I worry that immediately assuming a # is a header might break that.)

Also, having used my new CSS all day, I realized my hacky RTL trick to add a space between the header ###s and the text really makes things confusing with the cursor when you try to edit a title. Do you think you could move the space ###_ inside the .cm-header.cm-rm-header-token class? (You might have to test out my latest to get a feel for the problem I was trying to solve)

1 Like

Anyone else having issues when editing a note with code block and the plugine nabled?

For me, whenever I edit a note with a code block, Joplin would just stop responding every minute or so: the characters I type are not appearing, I can't click anywhere, etc. This goes on for a few seconds, then goes back to normal for a bit and repeats. It happens even when I edit outside of code block, it's just enough to have it somewhere within the note.
Disabling Rich Markdown seems to fix the issue.

My version is

Joplin 1.7.11 (prod, linux)

Client ID: 934e50ae74a941f587912680f6d54c43
Sync Version: 2
Profile Version: 34
Keychain Supported: No

Revision: f560563 (master)

I'll try checking further, just wanted to see if it's a known issue maybe?

UPD
Restarted again with the plugin enabled and the issue is gone. Might something specific to my system then. I also get visual artifacts occasionally when Joplin stays open for long time, so most likely these problems are of the same origin.

Looks good Amanda!

I have one problem though.
When installing gutters (CodeMirror builtin addon) things get mixed.
Screenshot from 2021-04-02 15-23-04

It happens for "Folding in Code Mirror Editor" plugin that uses those gutters.
Here is quick work around for those who have both Folding and Rich markdown plugin.

.CodeMirror-line {
padding-left: 10px !important;
}

.CodeMirror-gutters {

     left: 0px !important;
   
}

It will result in:
Screenshot from 2021-04-02 15-53-05

1 Like

Ah, somehow I missed that plugin. That CSS works to get the functionality back, but causes issues with list alignment. Makes me wonder if my hack for moving the "###" could actually be moved to the real code mirror gutter system. Will need to play. Thanks for sharing the fix!

2 Likes

Also, is it not possible to write the CSS without using !important, for example by playing on the CSS Specificity? Because each "important" rule means that if a different plugin tries to change it to something else it won't be possible.

1 Like

This is just so wonderful, thank you, @CalebJohn @uxamanda and @laurent for continuing to make Joplin awesome beyond my wildest dreams :heart::two_hearts::smiling_face_with_three_hearts:

2 Likes

I've battled this a lot and agree with you that it would be better. I don't normally use !important in CSS at all. It seems that the way to fix this would be to make sure that the user's CSS is always loaded last. It seems like for example, Code Mirror CSS is loaded after overriding my choices. I can do some hacking by nesting all my classes, but it gets hard to read.

Another idea might be to put a class on the body if the user has custom CSS loaded. Then I would just include that in every declaration, for example: .has-user-css .cm-variable-2 (I just tested this and it does allow me to remove all !important). This is still a little messier than I'd like, but it means I can ignore other dev's CSS specificity in the code and it is consistent.

Hi Amanda

Thanks for sharing this, looks great.

One minor issue I've found: horizontal rules created with *** or * * * or ---/- - - show symbols on top of the rule itself:

Not sure if this can be fixed via CSS at all.

Hey, yes, I left them so that it was easier to see what was happening, but you can hide them by changing this part of the block

.cm-s-default .cm-hr{
...
color: transparent !important!
...
}
1 Like