Using markdown like syntax in the Rich text editor
Hi guys
I have a situation where I want my editor to be able to write some "markdown-like" syntax in a rich text editor. I want to replace the parts of the RTE where the "markdown-syntax" is in use with some code-blocks in the rendered output without loosing the content context.
For instance a rich text could look like this
![FirstName](Write your first name)
FirstName is going to be an id on an element and the "Write your first name" is going to be an element text - so it should be converted like
Write your first name
There can be placed many instances of the "markdown" syntax in the rich text and it can also be placed in a sentence. Each time I see the syntax in my output I want to render a block of HTML like shown above.
I tried using Razor to create an array of the html...but I did not succeed so before wasting anymore time on this I thought I would get some input from the best community in the world :) - Could I use the http://htmlagilitypack.codeplex.com/ to achieve my goal?
If you want to do it really simple you could just replace parts of the html. Have a look at the screenshots of the Digibiz Email Form with TinyMCE package.
[firstName] is just replaced with html.Replace("[firstName]", "Jan").
Couldn't you use regex to capture the markup (capturing the text in regex groups) and then use regex replace to replace the value in the RTE with markup (pushing in the captured text). Then use Html.Raw(..) to output the value? (You may want to look at what Umbraco.Field does internally though and replicate it so that you replace internal link etc)
Could you perhaps write some code to illustrate the concept? I get what you're saying but I can't wrap my head around how to actually do it in code...You're speaking to a XSLT warrior who is still a c#/Razor n00b :)
Will capture that structure and put "firstName" into replacement variable $1, and "Enter first name here" into $2, so in theory you should be able to do something like.
Awesome! I think it's the part of replacement variables that always seem to confuse me. Think I need to read a bit more about that concept to "get it".
Don't worry about the Regex...I'll figure that part out - Now I at least have a clue! Thank you very much, will try it out tomorrow and let you know how it goes.
Matt's code seems to do the job, but if you need something more complex, have a look at this example:
string html = "hello world ![FirstName](Write your first name) goodbye world";
html = Regex.Replace(html, "(!)?()\\[(.+?)\\]\\((.+?)\\)", delegate(Match match) {
bool required = match.Groups[1].Value == "!";
string name = match.Groups[3].Value;
string text = match.Groups[4].Value;
return "<label><strong>" + text + "</strong>" + (required ? " (Required)" : "") + "<input type=\"text\" name=\"" + name + "\" value=\"\" /></label>";
});
This will create a <label> with the text. Assuming the exclamation marker means the field is required, a "required" text will be added as well. Finally the <label> will also contain the <input> field.
Wow thanks - Can't wait to check in to work tomorrow - Gonna feel so awesome :D
One question though - The example you provide would be able to handle that I have more than one "markdown" instance, right? I just need to pass the content of my rte to the html variable casting it to a string, right?
Depending on your use case, the regex might also need to be adjusted a bit. Changing it to "(!)?()\\[([a-z-A-Z0-9]+)\\]\\((.+?)\\)" will for instance require the name to be alphanumeric.
Cool - Yes that allright, just could not wrap my head around how to get the syntax right etc. - Tweaking the regex seems like the smaller part now. (Never though I would say that about regex) :D
This works really well - And the regex is good too. However...how would the regex need to be modified if I need to have a markdown syntax that looks like this
- Which could be for instance
![FirstName|Text](My text for the field)
I need the type to decide wether the contenteditable attribute should be added or if I should add a class instead.
Also I need to handle a scenario where I just want the expression to be displayed inline.
Currently my code looks like this
@{
string html = blocks.templateText.ToString();
html = Regex.Replace(html, "(!)?()\\[(.+?)\\]\\((.+?)\\)", delegate(Match match) {
bool required = match.Groups[1].Value == "!";
string id = match.Groups[3].Value;
string text = match.Groups[4].Value;
return "<p id=\"" + id +"\"><span contenteditable=\"true\">" + text + "</span></p>";
});
@Html.Raw(html)
}
My text could for instance look like this
Hi ![FirstName|Text](Write your first name)
Please write something about yourself in the field below
![PersonInformation|RichText](Write about your skills)
Kind regards
John Doe
As you can see the first line, where it says "Hi..." currently would be output as
Ok, so seems like my "markdown" sample reminded to much of some actual markdown to insert an image in the markdown editor of this forum :D
But nevermind the Regular expression stuff from my post above. I got that covered now. Need to digg into it some more - Perhaps there should be a regex workshop at codegarden!
Still puzzled about my other issue though and would love any pointers.
I have a richtext editor where the "markdown syntax" can be used in it's own line (block) or within a text context (inline).
It's rendering those that are used inline that is troubling me.
Consider this example (The text is bogus, but look at the context)
We would like to know your ![FirstName|Text](Enter your first name) and we would also like to know your ![LastName|Text](Enter your last name) as well.
Ok, when rendering this as ordinary rich text the HTML output would be
We would like to know your ![FirstName|Text](Enter your first name) and we would also like to know your ![LastName|Text](Enter your last name) as well.*
So in this case where the "markdown" is being used inline I only want to replace the expressions with elements, inside of the exisitng
Using markdown like syntax in the Rich text editor
Hi guys
I have a situation where I want my editor to be able to write some "markdown-like" syntax in a rich text editor. I want to replace the parts of the RTE where the "markdown-syntax" is in use with some code-blocks in the rendered output without loosing the content context.
For instance a rich text could look like this
![FirstName](Write your first name)
FirstName is going to be an id on an element and the "Write your first name" is going to be an element text - so it should be converted like
Write your first name
There can be placed many instances of the "markdown" syntax in the rich text and it can also be placed in a sentence. Each time I see the syntax in my output I want to render a block of HTML like shown above.
I tried using Razor to create an array of the html...but I did not succeed so before wasting anymore time on this I thought I would get some input from the best community in the world :) - Could I use the http://htmlagilitypack.codeplex.com/ to achieve my goal?
Thankfull for any input.
Cheers, Jan
If you want to do it really simple you could just replace parts of the html. Have a look at the screenshots of the Digibiz Email Form with TinyMCE package.
[firstName] is just replaced with html.Replace("[firstName]", "Jan").
Jeroen
Hi Jeroen
Thanks for the input - But I need to have the other information in my markup as well :)
/Jan
Hmm in that case the HtmlAgilityPack is really useful. The dll is already in the bin folder of Umbraco.
I've used it before. Here's an example: http://our.umbraco.org/forum/developers/extending-umbraco/20810-Embed-image-in-email#comment78715
Jeroen
Couldn't you use regex to capture the markup (capturing the text in regex groups) and then use regex replace to replace the value in the RTE with markup (pushing in the captured text). Then use Html.Raw(..) to output the value? (You may want to look at what Umbraco.Field does internally though and replicate it so that you replace internal link etc)
Hi Matt
Thanks for your input!
Could you perhaps write some code to illustrate the concept? I get what you're saying but I can't wrap my head around how to actually do it in code...You're speaking to a XSLT warrior who is still a c#/Razor n00b :)
/Jan
Ok, so given the format:
Using a regex of:
Will capture that structure and put "firstName" into replacement variable $1, and "Enter first name here" into $2, so in theory you should be able to do something like.
(Obviously you can put that in a helper method and break it up onto multiple lines to be a bit nicer, but you get the idea)
The regex replace bit was done by memory, so can't be sure this will work exactly as is copy-and-paste, but it should get you started :)
Matt
Hi Matt
Awesome! I think it's the part of replacement variables that always seem to confuse me. Think I need to read a bit more about that concept to "get it".
Don't worry about the Regex...I'll figure that part out - Now I at least have a clue! Thank you very much, will try it out tomorrow and let you know how it goes.
Cheers, Jan
No worries, good luck. It's all about the capture groups :)
Matt
Matt's code seems to do the job, but if you need something more complex, have a look at this example:
This will create a <label> with the text. Assuming the exclamation marker means the field is required, a "required" text will be added as well. Finally the <label> will also contain the <input> field.
Hi Anders
Wow thanks - Can't wait to check in to work tomorrow - Gonna feel so awesome :D
One question though - The example you provide would be able to handle that I have more than one "markdown" instance, right? I just need to pass the content of my rte to the html variable casting it to a string, right?
Thanks in advance.
/Jan
Yes, it will replace all occurrences ;)
Depending on your use case, the regex might also need to be adjusted a bit. Changing it to
"(!)?()\\[([a-z-A-Z0-9]+)\\]\\((.+?)\\)"
will for instance require the name to be alphanumeric.Cool - Yes that allright, just could not wrap my head around how to get the syntax right etc. - Tweaking the regex seems like the smaller part now. (Never though I would say that about regex) :D
/Jan
Hi Anders
This works really well - And the regex is good too. However...how would the regex need to be modified if I need to have a markdown syntax that looks like this
- Which could be for instance
![FirstName|Text](My text for the field)
I need the type to decide wether the contenteditable attribute should be added or if I should add a class instead.
Also I need to handle a scenario where I just want the expression to be displayed inline.
Currently my code looks like this
@{ string html = blocks.templateText.ToString();
}
My text could for instance look like this
Hi ![FirstName|Text](Write your first name)
Please write something about yourself in the field below ![PersonInformation|RichText](Write about your skills)
Kind regards John Doe
As you can see the first line, where it says "Hi..." currently would be output as
Hi
Write your firstname
But in this case I need
Hi Write your firstname
Does it make sense?
And...any ideas? :)
Cheers, Jan
Ok, so seems like my "markdown" sample reminded to much of some actual markdown to insert an image in the markdown editor of this forum :D
But nevermind the Regular expression stuff from my post above. I got that covered now. Need to digg into it some more - Perhaps there should be a regex workshop at codegarden!
Still puzzled about my other issue though and would love any pointers.
/Jan
I'm not sure that I totally understand your remaining issue. Is it specifying the type of the field?
Getting the type would be something like:
If there ever will be a regex workshop, this definitely needs to the given on completion http://store-xkcd-com.myshopify.com/products/i-know-regular-expressions ;)
/Anders
Hi Anders
My main remaining issue is this...
I have a richtext editor where the "markdown syntax" can be used in it's own line (block) or within a text context (inline).
It's rendering those that are used inline that is troubling me.
Consider this example (The text is bogus, but look at the context)
We would like to know your ![FirstName|Text](Enter your first name) and we would also like to know your ![LastName|Text](Enter your last name) as well.
Ok, when rendering this as ordinary rich text the HTML output would be
We would like to know your ![FirstName|Text](Enter your first name) and we would also like to know your ![LastName|Text](Enter your last name) as well.*
So in this case where the "markdown" is being used inline I only want to replace the expressions with elements, inside of the exisitng
element.
Does this make more sense? :)
/Jan
Still not sure I understand. Can you try explaining it in Danish perhaps?
Hi Anders
I'll see if I can post a screendump on monday :)
But in short...if the "markdown" stands on it's own line I want the current output, which writes
My text
.But if it's used "inline" then I just want to replace the group with My text
/Jan
is working on a reply...