skip to Main Content

Im creating my own version of a MarkDown render. My goal is to read a string or file line by line then return the MD rendered as HTML. The problem im facing is my return and line by line functionaility is not-returning what I want and I dont know why. Ive tried debugging but everything seemed fine. Ive also tried chaning my for loop but still no luck.

//function used to render MD for the user

function render(md){
    let code = ""; //For functions return

    let mdLines = md.split('n');

    for(let i = 0; i < mdLines.length; i++){

        //Statements to see what kind of MD header a line is.
        //I only have these statments as I just started this and am still figuring how I want to approach.

        if(mdLines[i].slice(0, 1) == "#"){
           code += code.concat("<h1>" + mdLines[i].replace("#", "") + "</h1>")
        }

        if(mdLines[i].slice(0, 2) == "##"){
           code += code.concat("<h2>" + mdLines[i].replace("##", "") + "</h2>")
        }

        if(mdLines[i].slice(0, 3) == "###"){
           code += code.concat("<h3>" + mdLines[i].replace("###", "") + "</h3>")
        }

        if(mdLines[i].slice(0, 4) == "####"){
           code += code.concat("<h4>" + mdLines[i].replace("#", "") + "</h4>")
        }

        if(mdLines[i].slice(0, 5) == "#####"){
           code += code.concat("<h5>" + mdLines[i].replace("#", "") + "</h5>")
        }

        if(mdLines[i].slice(0, 6) == "######"){
           code += code.concat("<h6>" + mdLines[i].replace("######", "") + "</h6>")
        }
    };
    
    return code;
}


//editor
//This is what the users .js file would be.
//I have it set up like this for testing.

let text1 = "## he#llo n there n# yooo"
let text2 = "# he#llo n there n## yooo"

console.log(render(text1));
console.log(render(text2));

text1 returns <h1># he#llo </h1><h1># he#llo </h1><h2> he#llo </h2>
text2 reutrns <h1> he#llo </h1>

text1 should return <h2>he#llo</h2> there <h1> yooo </h1>
text2 should return <h1> he#llo </h1> there <h2> yooo </h2>

If someone could help me get the proper returns and some potentially reusable code for this issue it would be greatly appreciated.

Ive also looked up the issue with some select terms but it seems no one has documented my very specific issue.

Also for those saying it’s a beginner issue just use Elseif, I did that. It dont work. Soooooo….. womp womp.

2

Answers


  1. Here’s a better and more general way to handle this. In addition, it won’t strip out "#" that are in the middle of a string, as yours would. This relies on the fact that a ### header must be followed by a space.

    function render(md){
        let code = "";
    
        let mdLines = md.split('n');
    
        for(let i = 0; i < mdLines.length; i++){
            
            if(mdLines[i][0] == "#") {
                // We have a header.  How many are there?
                let s = mdLines[i].indexOf(" ")
                if( mdLines[i].slice(0,s) == '#'.repeat(s) )
                    code += "<h"+s+">" + mdLines[i].slice(s+1) + "</h"+s+">";
                else
                    code += mdLines[i];
            }
            else
                code += mdLines[i];
        };
        
        return code;
    }
    
    let text1 = "## he#llo n there n # yooo"
    let text2 = "# he#llo n there n ## yooo"
    
    console.log(render(text1));
    console.log(render(text2));
    

    Output:

    timr@Tims-NUC:~/src$ node x.js
    <h2>he#llo </h2> there  # yooo
    <h1>he#llo </h1> there  ## yooo
    
    timr@Tims-NUC:~/src$
    

    Followup

    Here’s what you apparently MEANT to test with:

    let text1 = "## he#llontheren# yooo"
    let text2 = "# he#llontheren## yooo"
    

    And here’s the output:

    timr@Tims-NUC:~/src$ node x.js
    <h2>he#llo</h2>there<h1>yooo</h1>
    <h1>he#llo</h1>there<h2>yooo</h2>
    timr@Tims-NUC:~/src$
    
    Login or Signup to reply.
  2. After constant requests, I took a look at the expected output, and this is probably not the best/neatest code, but it does work, and is fairly compact

    function render(md) {
        let code = ""; //For functions return
        let mdLines = md.split("n");
        
        const re = /^s*([#]{1,6})s/;
        for (let line of mdLines) {
            const hash = line.match(re);
            if (hash) {
                const h = hash[1].length;
                line = `<h${h}>${line.replace(re, "").trim()}</h${h}>`;
            }
            code += line;
        }
        return code;
    }
    
    let text1 = "## he#llo n there n # yooo";
    let text2 = "# he#llo n there n ## yooo";
    
    console.log(render(text1));
    console.log(render(text2));
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search