Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Jan Skovgaard 11280 posts 23678 karma points MVP 11x admin c-trib
    Apr 10, 2014 @ 15:44
    Jan Skovgaard
    0

    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

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Apr 10, 2014 @ 16:51
    Jeroen Breuer
    0

    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

  • Jan Skovgaard 11280 posts 23678 karma points MVP 11x admin c-trib
    Apr 10, 2014 @ 16:52
    Jan Skovgaard
    0

    Hi Jeroen

    Thanks for the input - But I need to have the other information in my markup as well :)

    /Jan

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Apr 10, 2014 @ 16:57
    Jeroen Breuer
    1

    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

  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    Apr 10, 2014 @ 17:04
    Matt Brailsford
    1

    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)

  • Jan Skovgaard 11280 posts 23678 karma points MVP 11x admin c-trib
    Apr 10, 2014 @ 17:18
    Jan Skovgaard
    0

    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

  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    Apr 10, 2014 @ 18:50
    Matt Brailsford
    1

    Ok, so given the format:

    ![firstName](Enter first name here)
    

    Using a regex of:

    /\!\[([^\]]+)\]\(([^\)]+)\)/g
    

    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.

    @Html.Raw(Regex.Replace(Model.Content.GetPropertyValue<string>("bodyText"), "\!\[([^\]]+)\]\(([^\)]+)\)", "<span id=\"$1\" contenteditable=\"true\">$2</span>", RegexOptions.Singleline))
    

    (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

  • Jan Skovgaard 11280 posts 23678 karma points MVP 11x admin c-trib
    Apr 10, 2014 @ 18:54
    Jan Skovgaard
    0

    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

  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    Apr 10, 2014 @ 19:03
    Matt Brailsford
    0

    No worries, good luck. It's all about the capture groups :)

    Matt

  • Anders Bjerner 487 posts 2990 karma points MVP 8x admin c-trib
    Apr 10, 2014 @ 19:05
    Anders Bjerner
    1

    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.

  • Jan Skovgaard 11280 posts 23678 karma points MVP 11x admin c-trib
    Apr 10, 2014 @ 19:07
    Jan Skovgaard
    0

    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

  • Anders Bjerner 487 posts 2990 karma points MVP 8x admin c-trib
    Apr 10, 2014 @ 19:14
    Anders Bjerner
    0

    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.

  • Jan Skovgaard 11280 posts 23678 karma points MVP 11x admin c-trib
    Apr 10, 2014 @ 19:15
    Jan Skovgaard
    0

    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

  • Jan Skovgaard 11280 posts 23678 karma points MVP 11x admin c-trib
    Apr 11, 2014 @ 12:37
    Jan Skovgaard
    0

    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

    ID|Type - 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

    Hi

    Write your firstname

    But in this case I need

    Hi Write your firstname

    Does it make sense?

    And...any ideas? :)

    Cheers, Jan

  • Jan Skovgaard 11280 posts 23678 karma points MVP 11x admin c-trib
    Apr 11, 2014 @ 16:17
    Jan Skovgaard
    0

    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

  • Anders Bjerner 487 posts 2990 karma points MVP 8x admin c-trib
    Apr 11, 2014 @ 16:39
    Anders Bjerner
    0

    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:

    @{
    
        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 type = match.Groups[4].Value;
            string text = match.Groups[5].Value;
    
            return "<p id=\"" + id + "\"><span contenteditable=\"true\">" + text + "</span></p>";
    
        });
    
        @Html.Raw(html)
    }
    

    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

  • Jan Skovgaard 11280 posts 23678 karma points MVP 11x admin c-trib
    Apr 11, 2014 @ 16:46
    Jan Skovgaard
    0

    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

  • Anders Bjerner 487 posts 2990 karma points MVP 8x admin c-trib
    Apr 11, 2014 @ 16:57
    Anders Bjerner
    0

    Still not sure I understand. Can you try explaining it in Danish perhaps?

  • Jan Skovgaard 11280 posts 23678 karma points MVP 11x admin c-trib
    Apr 11, 2014 @ 17:01
    Jan Skovgaard
    0

    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

Please Sign in or register to post replies

Write your reply to:

Draft