Plugin: Rich Markdown

@whitewall
Looks good! To be honest this is a bit of a grey area for me, and I haven't completely made up my mind about it. I actually slipped some css to do this into the TIPs, but didn't advertise it :slight_smile:.

I've been thinking this as well. To start with I was just planning on having a toggle for a fully themed version. But it makes sense to have a few smaller, more granular controls like this. I'll probably have a few options in the settings menu (maybe a dropdown?) for themes. As well as a couple of commands to toggle the active line token highlighting and focus mode. This only really just became possible with the latest pre-release of Joplin, so it won't be immediately available, but it is next on my todo list for the plugin.

Thanks for the suggestions and thanks for sharing your css!

And for everyone else, please check out my CSS TIPS for a better markdown experience!

1 Like

Great!

I have found one hitch, though, and I had seen it earlier but was ignoring it.

It seems that every single asterisk gets the cm-rm-em-token class added to it. This is the case for just an ordinary asterisk like this:

image

(it is gray because I wanted to de-emphasize the tokens)
And here is what the code looks like:

image

Because of this, my css above to remove the tokens for em also removes the asterisks that are used for bulleted lists.

Is this because I should really be using .cm-em.cm-rm-em-token and not just cm-rm-em-token?

Yes. It was easier to implement this way and in the off chance a user wants to target all asterisks, they'll have the ability.

1 Like

This is fantastic, I can't believe I missed it for so long. Thanks a lot for mentioning it.

For some reason, I had to update manually with this version (no update prompt in Joplin, even after 5 days), I don't know if there's a relation.

This is great. Would you consider doing the same with quotes? I mostly gave up on styling them because I couldn't get a border-left without ruining text selection on multiple lines.

1 Like

I have actually noticed a little bit of wonkiness with this, the hiding of tokens. Which must be why you put it in the at-your-own-risk section.

If you click at the end of the line, the cursor appears positioned within the line for the number of characters worth of hidden tokens. In this cast below, I'm just clicking and typing. The cursor really is at the end of the line which you can see by my typing.
hiddenTokensProblem
Not a deal breaker.

That's odd, I haven't encountered this so far (with the css snippet on github), but it looks like my problem with quote styling. Are you using some sort of display: inline in your css? I feel like this may be related to your Title line formatting. In my case, it became completely unusable if the quote was wrapped on multiple lines.

Nope. Just colour, things like that. And it happens for non-titles as well.

Here's my css:

Summary
.cm-rm-ins.cm-rm-ins-token,
.cm-strong.cm-rm-strong-token, 
.cm-rm-highlight-token, 
.cm-em.cm-rm-em-token, 
.cm-header.cm-header-1.cm-rm-header-token, 
.cm-header.cm-header-2.cm-rm-header-token,
.cm-header.cm-header-3.cm-rm-header-token
{
	display:none;
}

.CodeMirror-activeline .cm-rm-ins.cm-rm-ins-token,
.CodeMirror-activeline .cm-strong.cm-rm-strong-token, 
.CodeMirror-activeline .cm-rm-highlight-token, 
.CodeMirror-activeline .cm-em.cm-rm-em-token,
.CodeMirror-activeline .cm-header.cm-header-1.cm-rm-header-token,
.CodeMirror-activeline .cm-header.cm-header-2.cm-rm-header-token,
.CodeMirror-activeline .cm-header.cm-header-3.cm-rm-header-token
{
	display:inherit;
}``
1 Like

I meant the other parts of your css, like the header styling. Are you still using this for instance?

No, I removed that line and still have the problem. The only display setting I have is for the list tokens, but those aren't hidden.

If you are curious, here's my whole css file

Summary
/* For styling the entire Joplin app (except the rendered Markdown, which is defined in `userstyle.css`) */


.CodeMirror.cm-s-dracula.CodeMirror-wrap {
    background-color: black !important;
}

div.editor-toolbar a.button.disabled {
    display: none;
}

/*remove sync area*/
div.sidebar div:nth-of-type(2) {
    display: none;
}

/*resize sidebar items*/
/*removes left margin*/
div.list-item-container a span {
	font-size:.9em;	
}

div.list-item-container a {
	font-size:.9em;
	font-weight:300;
}

/*reduces the height of list items in sidebars*/
div.sidebar div.list-item-container {
	height:16px!important;
}

/*END OF REDUCING SIDEBAR ITEM SPACING*/


::-webkit-scrollbar-thumb{
background: silver
}

::-webkit-scrollbar-track{
border: 4px solid black
}


div.editor-toolbar{
	padding:0px!important;
}

div.editor-toolbar *{
	font-size:1em;
}

/*selected item in notebook and note list*/
div.selected , div.selected {
	background:#013F74!important;
}


/*??? not sure what this does????????????????????????????????????????*/
.cm-s-material-darker .cm-property{
	color:#5B5B5B!important;
}


/*NOTE LIST -and- NOTEBOOK LIST*/
div.item-list *, a.list-item {
	font-family:"Fira Sans"!important;
	font-weight:100!important;
	font-stretch: extra-condensed!important;
}

/*style note list*/
div.note-list div.list-item-container *{
	font-size:.9em!important;
	
}

/*NOTEBOOK LIST*/
div.list-item-depth-0 {
	padding-left:0px;
}

div.list-item-depth-1 {
	padding-left:5px;
}

div.list-item-depth-2 {
	padding-left:15px;
}

div.list-item-depth-3 {
	padding-left:20px;
}

div.list-item-depth-4 {
	padding-left:25px;
}

div.list-item-container a span {
	padding-right:0px;
	padding-left:5px!important;
	font-family:"Fira Sans"!important;
	font-weight:100!important;
	font-stretch: extra-condensed!important;
}

a.list-item div {
	padding-left:3px;
	font-size:.8em;
	opacity: 0.3;
	font-family:"Fira Sans"!important;
	font-stretch: extra-condensed!important;
}

/*-------------------------------------- E D I T O R  C H R O M E -----------------------------------------------*/
/*toggle arrow*/
.CodeMirror-guttermarker-subtle {
	font-size:1.5em;
	color:purple!important
}


.CodeMirror-activeline
/*was .CodeMirror-activeline-background*/
 {
    background: #021C22 !important;
}

/* Real CodeMirror line numbers */
.CodeMirror-gutters {
  background: none !important;
  border: none !important;
}
.CodeMirror-linenumber {
  color: rgba(150, 150, 150, 0.4) !important;
}

/*-----------------------------------S T Y L I N G  O F  T E X T ------------------------------------------------------ */

/* Render horizontal lines (made with \-\-\- or \*\*\*) as an actual line across the editor. */
.cm-hr {
  border-top: 3px solid #777;
  display: block;
  line-height: 0px;
}

/*REMOVE TOKENS ON UNACTIVE LINES*/
.cm-rm-ins.cm-rm-ins-token,
.cm-strong.cm-rm-strong-token, 
.cm-rm-highlight-token, 
.cm-em.cm-rm-em-token, 
.cm-header.cm-header-1.cm-rm-header-token, 
.cm-header.cm-header-2.cm-rm-header-token,
.cm-header.cm-header-3.cm-rm-header-token
{
	display:none;
}

.CodeMirror-activeline .cm-rm-ins.cm-rm-ins-token,
.CodeMirror-activeline .cm-strong.cm-rm-strong-token, 
.CodeMirror-activeline .cm-rm-highlight-token, 
.CodeMirror-activeline .cm-em.cm-rm-em-token,
.CodeMirror-activeline .cm-header.cm-header-1.cm-rm-header-token,
.CodeMirror-activeline .cm-header.cm-header-2.cm-rm-header-token,
.CodeMirror-activeline .cm-header.cm-header-3.cm-rm-header-token
{
	display:inherit;
}
/* end---REMOVE TOKENS ON UNACTIVE LINES*/



/*make markdown tokens for list into dots*/
.cm-overlay.cm-rm-list-token.cm-overlay.cm-rm-em-token
	{
color: transparent !important;
background-color: #DECB6B!important; 
height: 6px;
width: 6px;
border-radius: 50%;
display: inline-block;
vertical-align: bottom;
margin: 0 0px 8px 8px;
}

/*lists*/
.cm-variable-2, .cm-variable-3, .cm-keyword {
	color:	#DECB6B !important;
}

/*de-emphasize markdown markup*/
.cm-overlay.cm-search-marker.cm-overlay.cm-rm-highlight-token, .cm-strong.cm-rm-strong-token, .cm-em.cm-rm-em-token, .cm-rm-ins.cm-rm-ins-token {
	background: none!important;
	color: #4B505B!important;
}

.cm-rm-ins {
	text-decoration:none!important;
	background-color:#CC0000;
	color:black!important;
	font-weight:bold!important;
}

.cm-rm-link {
	text-decoration:underline
}


.cm-strong {
	color:red!important;
	font-weight: bolder!important;
}


/*strikethrough checked boxes*/
span.cm-rm-checkbox.cm-property + span.cm-rm-checkbox ~ span.cm-rm-checkbox {
	text-decoration: line-through;
	color:#5B5B5B!important;
}

/*HEADER STYLES*/
.cm-header-1{
	color: #794BBB;
	font-weight:bold;
}

.cm-header-2{
	color: #BD93F9;
}

.cm-header-3, .cm-header-4, .cm-header-5, .cm-header-6 {
	color:#CBBBE1;
	font-style:italic;
	text-shadow: 1px 1px 4px #000000;
}

.cm-header-1 {
/*    line-height: 200% !important;*/
/*	display: inline-block; */
	margin-top:.8em;
	margin-bottom:.3em;
}






I tried your css file, but I can't reproduce it, even with the line numbers and folding plugins. I'm almost out of ideas at this point, maybe someone else will have an better understanding of this.

Looking at your css file, I see a lot of font-stretch: extra-condensed!important;, have you tried commenting them out? But I don't see why it would only start being a problem now. In fact, do you have this problem without custom css?

1 Like

Looks like I forgot to publish the latest release, Oops! I've pushed it up now, thanks for letting me know.

Good call, I'll do this for the next release.

I can also reproduce this consistently. Funny enough, if you enable spell checking in the markdown editor (from the options menu) then the issue is resolved. You don't actually need to enable spell checking from the globe icon, just enabling the beta feature seems to make this work.

image

1 Like

I'm totally just guessing, but it seems like the cursor is being placed in the editor physically where you click (before the css to show the token is applied) but then once the css is applied it remains logically where you wanted it. Perhaps the spell checker process changes the timing of these things so the cursor goes physically where it should be.

Close, when that option is selected the editor will use an entirely different component under the hood. Typically CodeMirror will handle cursor placement itself, but when the spellchecking beta is enabled it relinquishes control of the cursor to Electron (kinda) which apparently can handle the tokens appearing and disappearing better.

1 Like

Hold down the CTRL key and click the attachment. The attachment cannot be opened. Is this a bug? thank you

It's a bug, I know what caused it, I'll fix to today.

edit: It should be fixed now, please let me know if it's still not working.

2 Likes

This is exactly what I expect from Joplin. I expect the feature just like Typora. The Rich Markdown takes the first step toward it. Thanks for writing this plugin.

Some reports:
Bug reports:

  1. The > quote not supported;
  2. Unordered list not supported;
  3. When preceding mark is inputted, the rendering works. It's good. But if the succeeding mark does not show up, the rendering does fall back.

Features requested:

  1. After rendering, the marks being hided. But it shows up again when the cursor is on this line.

Besides, the code inline and code block features are not supported, yet.

Hi @JeffW , I'm glad you like the plugin, but could you be a bit more detailed about your feature requests? For example you say that the quote (>) is not supported, but I don't know what you mean by supported. In general I try to be open to feature requests, but I have to understand what you're requesting to do that :sweat_smile:
Please provide more details on the following points:

This is already possible for the more technical users (see above), and I'll be making it more accessible for the rest very soon.

1 Like

Hi, @CalebJohn Thanks for the responding. I downloaded and installed Rich Markdown from Github. The version is 0.6.2. Following is the test page.

  1. The > quote not supported. -> When you type ">" and space, the followed text is not shown as quote, as shown in the right pane.

  2. Unordered list not supported. -> As you may find, the rendering of the ordered list in the left pane is basically the same as that in right pane. But unordered list is not, just shows *.

  3. When preceding mark is inputted, the rendering works. It's good. But if the succeeding mark does not show up, the rendering does fall back. -> I inputted *, and the following Italic is shown in italic. But if I did not input the right * and input return, the correct action should be changing the italic font back to normal, and showing " * Italic". But the plugin still showed * Italic.

  4. Besides, the code inline and code block features are not supported, yet. -> The same, when input ` or ``` leaded block, the block is not rendered as code.

  5. After rendering, the marks being hided. But it shows up again when the cursor is on this line. -> I hope to have the feature, when the editor recognizes the markdown syntax, it automatically renders the text followed, without showing the syntax symbol. But when later the user moves the cursor back to the rendered text, it shows the original text (no rendering). When the cursor leaves, it renders again.

What is it that you expect to be done in the editor? If you want to replace the *s with dots, you can use the following css:

/*make markdown tokens for list into dots*/
.cm-overlay.cm-rm-list-token.cm-overlay.cm-rm-em-token
	{
color: transparent !important;
background-color: #DECB6B!important; 
height: 6px;
width: 6px;
border-radius: 50%;
display: inline-block;
vertical-align: bottom;
margin: 0 0px 8px 8px;
}

Note: this only works for me when I use *, not -, as the token.

You should be able to do this using css. Just add something to select the italic text within the current line. Or are you wanting some kind of selector for being inside the specific italic block of text? Meaning you only want this behaviour when you are within the italic words? That I don't believe is currently supported with the plugin. But if you simply want the current line to turn back into plain text, that should not be difficult with CSS.

EDIT: OK, the following seems to work to change highlighted text back to normal in the current line:

.CodeMirror-activeline .cm-search-marker{
background-color:transparent!important;
color:inherit!important}