comrak VS commonmark-spec

Compare comrak vs commonmark-spec and see what are their differences.

comrak

CommonMark + GFM compatible Markdown parser and renderer (by kivikakk)

commonmark-spec

CommonMark spec, with reference implementations in C and JavaScript (by commonmark)
InfluxDB - Power Real-Time Data Analytics at Scale
Get real-time insights from all types of time series data with InfluxDB. Ingest, query, and analyze billions of data points in real-time with unbounded cardinality.
www.influxdata.com
featured
SaaSHub - Software Alternatives and Reviews
SaaSHub helps you find the best software and product alternatives
www.saashub.com
featured
comrak commonmark-spec
5 48
1,083 4,836
- 0.2%
8.7 6.9
8 days ago 3 months ago
Rust Python
GNU General Public License v3.0 or later GNU General Public License v3.0 or later
The number of mentions indicates the total number of mentions that we've tracked plus the number of user suggested alternatives.
Stars - the number of stars that a project has on GitHub. Growth - month over month growth in stars.
Activity is a relative number indicating how actively a project is being developed. Recent commits have higher weight than older ones.
For example, an activity of 9.0 indicates that a project is amongst the top 10% of the most actively developed projects that we are tracking.

comrak

Posts with mentions or reviews of comrak. We have used some of these posts to build our list of alternatives and similar projects. The last one was on 2022-10-13.
  • Create a Markdown Editor with Rust and React
    12 projects | dev.to | 13 Oct 2022
    I opened up the src/App.tsx and added a and synced any text changes to React state.

    import { useState } from "react";
    import reactLogo from "./assets/react.svg";
    import { invoke } from "@tauri-apps/api/tauri";
    import "./App.css";
    
    function App() {
      const [markdown, setMarkdown] = useState("");
    
      return (
        
    className="container">

    Welcome to Tauri!

    className="row"> href="https://vitejs.dev" target="_blank"> src="/vite.svg" className="logo vite" alt="Vite logo" /> href="https://tauri.app" target="_blank"> src="/tauri.svg" className="logo tauri" alt="Tauri logo" /> href="https://reactjs.org" target="_blank"> src={reactLogo} className="logo react" alt="React logo" />

    Click on the Tauri, Vite, and React logos to learn more.

    className="row">
    id</span><span class="o">=</span><span class="s2">"greet-input"</span> <span class="nv">onChange</span><span class="o">={(</span>e<span class="o">)</span> <span class="o">=></span> setMarkdown<span class="o">(</span>e.currentTarget.value<span class="o">)}</span> /> </div> </div> </div> <span class="o">)</span><span class="p">;</span> <span class="o">}</span> <span class="nb">export </span>default App<span class="p">;</span> </code></pre> <div class="highlight__panel js-actions-panel"> <div class="highlight__panel-action js-fullscreen-code-action"> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-on"><title>Enter fullscreen mode</title> <path d="M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z"></path> </svg> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-off"><title>Exit fullscreen mode</title> <path d="M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z"></path> </svg> </div> </div> </div> <p>Now that we have a textbox we can write Markdown inside, let’s convert that to HTML to preview.</p> <h2> <a name="creating-a-tauri-command" href="#creating-a-tauri-command"> </a> Creating a Tauri command </h2> <p>We’ll need to use <a href="https://tauri.app/v1/guides/features/command/">Tauri commands</a> to communicate between the frontend and backend - and vice versa (similar to <a href="https://www.electronjs.org/docs/latest/tutorial/ipc">the IPC layer in Electron</a>).</p> <p>Tauri comes with an example Tauri command called <code>greet()</code> already setup, so let’s use that and change it to parse Markdown. Open up <code>src-tauri/src/main.rs</code> and change it to the following:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight rust"><code><span class="nd">#![cfg_attr(</span> <span class="nd">all(not(debug_assertions),</span> <span class="nd">target_os</span> <span class="nd">=</span> <span class="s">"windows"</span><span class="nd">),</span> <span class="nd">windows_subsystem</span> <span class="nd">=</span> <span class="s">"windows"</span> <span class="nd">)]</span> <span class="c1">// Import comrak</span> <span class="k">use</span> <span class="nn">comrak</span><span class="p">::{</span><span class="n">markdown_to_html</span><span class="p">,</span> <span class="n">ComrakOptions</span><span class="p">};</span> <span class="c1">// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command</span> <span class="nd">#[tauri::command]</span> <span class="k">fn</span> <span class="nf">greet</span><span class="p">(</span><span class="n">markdown</span><span class="p">:</span> <span class="o">&</span><span class="nb">str</span><span class="p">)</span> <span class="k">-></span> <span class="nb">String</span> <span class="p">{</span> <span class="c1">// format!("Hello, {}! You've been greeted from Rust!", name)</span> <span class="c1">// Parse the markdown text to HTML</span> <span class="k">let</span> <span class="n">html</span> <span class="o">=</span> <span class="nf">markdown_to_html</span><span class="p">(</span><span class="o">&</span><span class="n">markdown</span><span class="p">,</span> <span class="o">&</span><span class="nn">ComrakOptions</span><span class="p">::</span><span class="nf">default</span><span class="p">());</span> <span class="nd">println!</span><span class="p">(</span><span class="s">"Markdown parsed into HTML </span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="nd">println!</span><span class="p">(</span><span class="s">"{html}"</span><span class="p">);</span> <span class="c1">// We return the HTML to the frontend (in Rust, we return by omitting the `;`)</span> <span class="n">html</span> <span class="p">}</span> <span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span> <span class="nn">tauri</span><span class="p">::</span><span class="nn">Builder</span><span class="p">::</span><span class="nf">default</span><span class="p">()</span> <span class="c1">// Here is where we add our Tauri commands to our app</span> <span class="nf">.invoke_handler</span><span class="p">(</span><span class="nn">tauri</span><span class="p">::</span><span class="nd">generate_handler!</span><span class="p">[</span><span class="n">greet</span><span class="p">])</span> <span class="nf">.run</span><span class="p">(</span><span class="nn">tauri</span><span class="p">::</span><span class="nd">generate_context!</span><span class="p">())</span> <span class="nf">.expect</span><span class="p">(</span><span class="s">"error while running tauri application"</span><span class="p">);</span> <span class="p">}</span> </code></pre> <div class="highlight__panel js-actions-panel"> <div class="highlight__panel-action js-fullscreen-code-action"> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-on"><title>Enter fullscreen mode</title> <path d="M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z"></path> </svg> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-off"><title>Exit fullscreen mode</title> <path d="M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z"></path> </svg> </div> </div> </div> <p>And in our frontend, let’s create a <code><button></code> we can press to run the Tauri command. We use the <code>invoke</code> function provided by Tauri that’ll call a Tauri command with the same name.<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight jsx"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">useState</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">react</span><span class="dl">"</span><span class="p">;</span> <span class="k">import</span> <span class="nx">reactLogo</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">./assets/react.svg</span><span class="dl">"</span><span class="p">;</span> <span class="k">import</span> <span class="p">{</span> <span class="nx">invoke</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@tauri-apps/api/tauri</span><span class="dl">"</span><span class="p">;</span> <span class="k">import</span> <span class="dl">"</span><span class="s2">./App.css</span><span class="dl">"</span><span class="p">;</span> <span class="kd">function</span> <span class="nx">App</span><span class="p">()</span> <span class="p">{</span> <span class="kd">const</span> <span class="p">[</span><span class="nx">html</span><span class="p">,</span> <span class="nx">setHtml</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="dl">""</span><span class="p">);</span> <span class="kd">const</span> <span class="p">[</span><span class="nx">markdown</span><span class="p">,</span> <span class="nx">setMarkdown</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="dl">""</span><span class="p">);</span> <span class="k">async</span> <span class="kd">function</span> <span class="nx">greet</span><span class="p">()</span> <span class="p">{</span> <span class="c1">// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command</span> <span class="nx">setHtml</span><span class="p">(</span><span class="k">await</span> <span class="nx">invoke</span><span class="p">(</span><span class="dl">"</span><span class="s2">greet</span><span class="dl">"</span><span class="p">,</span> <span class="p">{</span> <span class="nx">markdown</span> <span class="p">}));</span> <span class="p">}</span> <span class="k">return</span> <span class="p">(</span> <span class="p"><</span><span class="nt">div</span> <span class="na">className</span><span class="p">=</span><span class="s">"container"</span><span class="p">></span> <span class="p"><</span><span class="nt">h1</span><span class="p">></span>Welcome to Tauri!<span class="p"></</span><span class="nt">h1</span><span class="p">></span> <span class="p"><</span><span class="nt">div</span> <span class="na">className</span><span class="p">=</span><span class="s">"row"</span><span class="p">></span> <span class="p"><</span><span class="nt">a</span> <span class="na">href</span><span class="p">=</span><span class="s">"https://vitejs.dev"</span> <span class="na">target</span><span class="p">=</span><span class="s">"_blank"</span><span class="p">></span> <span class="p"><</span><span class="nt">img</span> <span class="na">src</span><span class="p">=</span><span class="s">"/vite.svg"</span> <span class="na">className</span><span class="p">=</span><span class="s">"logo vite"</span> <span class="na">alt</span><span class="p">=</span><span class="s">"Vite logo"</span> <span class="p">/></span> <span class="p"></</span><span class="nt">a</span><span class="p">></span> <span class="p"><</span><span class="nt">a</span> <span class="na">href</span><span class="p">=</span><span class="s">"https://tauri.app"</span> <span class="na">target</span><span class="p">=</span><span class="s">"_blank"</span><span class="p">></span> <span class="p"><</span><span class="nt">img</span> <span class="na">src</span><span class="p">=</span><span class="s">"/tauri.svg"</span> <span class="na">className</span><span class="p">=</span><span class="s">"logo tauri"</span> <span class="na">alt</span><span class="p">=</span><span class="s">"Tauri logo"</span> <span class="p">/></span> <span class="p"></</span><span class="nt">a</span><span class="p">></span> <span class="p"><</span><span class="nt">a</span> <span class="na">href</span><span class="p">=</span><span class="s">"https://reactjs.org"</span> <span class="na">target</span><span class="p">=</span><span class="s">"_blank"</span><span class="p">></span> <span class="p"><</span><span class="nt">img</span> <span class="na">src</span><span class="p">=</span><span class="si">{</span><span class="nx">reactLogo</span><span class="si">}</span> <span class="na">className</span><span class="p">=</span><span class="s">"logo react"</span> <span class="na">alt</span><span class="p">=</span><span class="s">"React logo"</span> <span class="p">/></span> <span class="p"></</span><span class="nt">a</span><span class="p">></span> <span class="p"></</span><span class="nt">div</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span><span class="p">></span>Click on the Tauri, Vite, and React logos to learn more.<span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">div</span> <span class="na">className</span><span class="p">=</span><span class="s">"row"</span><span class="p">></span> <span class="p"><</span><span class="nt">div</span><span class="p">></span> <span class="p"><</span><span class="nt">textarea</span> <span class="na">id</span><span class="p">=</span><span class="s">"greet-input"</span> <span class="na">onChange</span><span class="p">=</span><span class="si">{</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="o">=></span> <span class="nx">setMarkdown</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">currentTarget</span><span class="p">.</span><span class="nx">value</span><span class="p">)</span><span class="si">}</span> <span class="p">/></span> <span class="p"><</span><span class="nt">button</span> <span class="na">type</span><span class="p">=</span><span class="s">"button"</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="p">()</span> <span class="o">=></span> <span class="nx">greet</span><span class="p">()</span><span class="si">}</span><span class="p">></span> Convert to HTML <span class="p"></</span><span class="nt">button</span><span class="p">></span> <span class="p"></</span><span class="nt">div</span><span class="p">></span> <span class="p"></</span><span class="nt">div</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span><span class="p">></span><span class="si">{</span><span class="nx">html</span><span class="si">}</span><span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"></</span><span class="nt">div</span><span class="p">></span> <span class="p">);</span> <span class="p">}</span> <span class="k">export</span> <span class="k">default</span> <span class="nx">App</span><span class="p">;</span> </code></pre> <div class="highlight__panel js-actions-panel"> <div class="highlight__panel-action js-fullscreen-code-action"> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-on"><title>Enter fullscreen mode</title> <path d="M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z"></path> </svg> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-off"><title>Exit fullscreen mode</title> <path d="M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z"></path> </svg> </div> </div> </div> <p>If you type some Markdown into the text box and click the button, it should print out raw HTML representing your Markdown. Here’s <a href="https://github.com/whoisryosuke/tauri-markdown-editor/commit/321f5bcfb1c0e370c27b8781d6f70fd74e6b67df">the commit on Github for reference.</a></p> <h3> <a name="but-how-do-we-preview-the-html" href="#but-how-do-we-preview-the-html"> </a> But how do we preview the HTML? </h3> <p>If we wanted to preview the HTML, we could use React’s <code>dangerouslySetInnerHTML</code> to inject the HTML inside our app:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight jsx"><code><span class="kd">const</span> <span class="nx">createMarkdownMarkup</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=></span> <span class="p">({</span> <span class="na">__html</span><span class="p">:</span> <span class="nx">html</span> <span class="p">})</span> <span class="o"><</span><span class="nx">div</span> <span class="nx">dangerouslySetInnerHTML</span><span class="o">=</span><span class="p">{</span><span class="nx">createMarkdownMarkup</span><span class="p">()}</span> <span class="sr">/</span><span class="err">> </span></code></pre> <div class="highlight__panel js-actions-panel"> <div class="highlight__panel-action js-fullscreen-code-action"> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-on"><title>Enter fullscreen mode</title> <path d="M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z"></path> </svg> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-off"><title>Exit fullscreen mode</title> <path d="M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z"></path> </svg> </div> </div> </div> <p>And ideally, this isn’t as “dangerous” as it sounds, because <a href="https://github.com/kivikakk/comrak#security">Comrak sanitizes the Markdown output for any malicious code</a> before converting to HTML 👍</p> <p>We could also update the <code>onChange</code> function to run our conversion process, instead of waiting for a button press, so we “instantly” see a live preview. In my case, I do it in a useEffect with a refresh boolean — but it’s all good. <em>Note, this is a little risky, since the user might be able to break the app, so in production it’d be best to create a cache of the last “working” preview just in case one fails.</em><br> </p> <div class="highlight js-code-highlight"> <pre class="highlight jsx"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">useEffect</span><span class="p">,</span> <span class="nx">useRef</span><span class="p">,</span> <span class="nx">useState</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">react</span><span class="dl">"</span><span class="p">;</span> <span class="k">import</span> <span class="nx">reactLogo</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">./assets/react.svg</span><span class="dl">"</span><span class="p">;</span> <span class="k">import</span> <span class="p">{</span> <span class="nx">invoke</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@tauri-apps/api/tauri</span><span class="dl">"</span><span class="p">;</span> <span class="k">import</span> <span class="dl">"</span><span class="s2">./App.css</span><span class="dl">"</span><span class="p">;</span> <span class="kd">function</span> <span class="nx">App</span><span class="p">()</span> <span class="p">{</span> <span class="kd">const</span> <span class="p">[</span><span class="nx">html</span><span class="p">,</span> <span class="nx">setHtml</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="dl">""</span><span class="p">);</span> <span class="kd">const</span> <span class="p">[</span><span class="nx">markdown</span><span class="p">,</span> <span class="nx">setMarkdown</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="dl">""</span><span class="p">);</span> <span class="kd">const</span> <span class="p">[</span><span class="nx">refreshCheck</span><span class="p">,</span> <span class="nx">setRefreshCheck</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span> <span class="k">async</span> <span class="kd">function</span> <span class="nx">greet</span><span class="p">()</span> <span class="p">{</span> <span class="nx">setRefreshCheck</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span> <span class="p">}</span> <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=></span> <span class="p">{</span> <span class="kd">const</span> <span class="nx">parseMarkdown</span> <span class="o">=</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=></span> <span class="p">{</span> <span class="nx">setHtml</span><span class="p">(</span><span class="k">await</span> <span class="nx">invoke</span><span class="p">(</span><span class="dl">"</span><span class="s2">greet</span><span class="dl">"</span><span class="p">,</span> <span class="p">{</span> <span class="nx">markdown</span> <span class="p">}));</span> <span class="nx">setRefreshCheck</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">new markdown</span><span class="dl">"</span><span class="p">);</span> <span class="p">};</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">refreshed</span><span class="dl">"</span><span class="p">);</span> <span class="k">if</span> <span class="p">(</span><span class="nx">refreshCheck</span><span class="p">)</span> <span class="p">{</span> <span class="nx">parseMarkdown</span><span class="p">();</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">parsing!</span><span class="dl">"</span><span class="p">);</span> <span class="p">}</span> <span class="p">},</span> <span class="p">[</span><span class="nx">refreshCheck</span><span class="p">]);</span> <span class="kd">const</span> <span class="nx">createMarkdownMarkup</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=></span> <span class="p">({</span> <span class="na">__html</span><span class="p">:</span> <span class="nx">html</span><span class="p">,</span> <span class="p">});</span> <span class="kd">const</span> <span class="nx">handleTextArea</span> <span class="o">=</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span> <span class="nx">setMarkdown</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">currentTarget</span><span class="p">.</span><span class="nx">value</span><span class="p">);</span> <span class="nx">setRefreshCheck</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">need new markdown!</span><span class="dl">"</span><span class="p">);</span> <span class="p">};</span> <span class="k">return</span> <span class="p">(</span> <span class="p"><</span><span class="nt">div</span><span class="p">></span> <span class="p"><</span><span class="nt">div</span> <span class="na">className</span><span class="p">=</span><span class="s">"row"</span><span class="p">></span> <span class="p"><</span><span class="nt">div</span><span class="p">></span> <span class="p"><</span><span class="nt">textarea</span> <span class="na">id</span><span class="p">=</span><span class="s">"greet-input"</span> <span class="na">onChange</span><span class="p">=</span><span class="si">{</span><span class="nx">handleTextArea</span><span class="si">}</span> <span class="p">/></span> <span class="p"><</span><span class="nt">button</span> <span class="na">type</span><span class="p">=</span><span class="s">"button"</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="p">()</span> <span class="o">=></span> <span class="nx">greet</span><span class="p">()</span><span class="si">}</span><span class="p">></span> Convert to HTML <span class="p"></</span><span class="nt">button</span><span class="p">></span> <span class="p"></</span><span class="nt">div</span><span class="p">></span> <span class="p"></</span><span class="nt">div</span><span class="p">></span> <span class="p"><</span><span class="nt">div</span> <span class="na">dangerouslySetInnerHTML</span><span class="p">=</span><span class="si">{</span><span class="nx">createMarkdownMarkup</span><span class="p">()</span><span class="si">}</span> <span class="p">/></span> <span class="p"></</span><span class="nt">div</span><span class="p">></span> <span class="p">);</span> <span class="p">}</span> <span class="k">export</span> <span class="k">default</span> <span class="nx">App</span><span class="p">;</span> </code></pre> <div class="highlight__panel js-actions-panel"> <div class="highlight__panel-action js-fullscreen-code-action"> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-on"><title>Enter fullscreen mode</title> <path d="M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z"></path> </svg> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-off"><title>Exit fullscreen mode</title> <path d="M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z"></path> </svg> </div> </div> </div> <p>Here’s <a href="https://github.com/whoisryosuke/tauri-markdown-editor/commit/4a3b351509d1ec0b363950c778f4ea42f92a32f6">the commit on Github for reference.</a></p> <h1> <a name="the-world-is-your-markdown" href="#the-world-is-your-markdown"> </a> The world is your Markdown </h1> <p>Now you can parse Markdown using Rust, there’s lots of cool stuff you can do! From CLIs to UI apps, you can make tools that help people use Markdown. And ideally, this will run faster than most other implementations (like Electron apps) because it’s running in Rust <em>(unless you can write Markdown tooling in C or something)</em>.</p> <p>I hope this helped you understand some Rust fundamentals and new techniques to use down the line.</p> <p>As always, if you have any questions or make something using this guide, <a href="https://twitter.com/whoisryosuke">tag me on Twitter</a>. I’d love to help or see what cool stuff you’re hacking on.</p> <p><strong>You can find the complete code for this post in <a href="https://github.com/whoisryosuke/tauri-markdown-editor">my tauri-markdown-editor repo</a>.</strong></p> <p>Stay regular!<br> Ryo</p>
  • Right-to-left languages rendering issue on the new reddit website and app
    2 projects | /r/ModSupport | 17 Mar 2022
    I was going to contribute to [comrak](https://github.com/kivikakk/comrak) the upstream project of snoomark (Reddit's Markdown renderer) to add bidirectional Markdown support, however, the spec isn't ready yet and a lot of things need to be clarified before considering using it in production.
    1 project | /r/bugs | 17 Mar 2022
    Bidirectional text is not supported on Reddit. Related issue: https://github.com/kivikakk/comrak/issues/205
  • In Defence of the Boring Web
    5 projects | news.ycombinator.com | 30 Jan 2022
    Jumping on the bandwagon of the guy that jumped on the bandwagon, because you mentioned potentially re-doing your own code at some point so might be interested: my personal site [0] looks very much like this (and is also written in Rust), but uses the comrak [1] crate to convert blog posts from Markdown to HTML on the fly before formatting with the header/footer theme. Using comrak lets you write in-line HTML (so you're not stuck with only Markdown syntax if you want to do something fancier like code blocks or ), and the whole site is <100 LoC, including route definitions.

    It handled the one potential HN hug-of-death event I've had without issues while running on the smallest DO droplet offered, and has basically been issue-free since I got it up and running.

    [0] https://github.com/quietlychris/site

    [1] https://github.com/kivikakk/comrak

  • Meta Programming
    3 projects | dev.to | 29 Oct 2021
    I chose to use comrak. It is one of the most developed and well known markdown to html crates and is very easy to use. The main logic of my code is very simple and is done as such

commonmark-spec

Posts with mentions or reviews of commonmark-spec. We have used some of these posts to build our list of alternatives and similar projects. The last one was on 2023-12-06.
  • How to add a man page to your Ruby project, using kramdown-man and markdown
    2 projects | /r/ruby | 6 Dec 2023
    Edit: this is because GitHub uses cmark-gfm, which is a fork of cmark, which implements the CommonMark variant of markdown. Looks like CommonMark still doesn't support definition lists. :(
  • How do you host documentation for your spouse or other users?
    4 projects | /r/selfhosted | 6 Dec 2023
    BookStack dev here. There's no specific "import" option but you can use the Markdown editor in BookStack and paste in your Markdown content there. The API is essentially just an endpoint to accept the same kind of data, for of course you could automate against the API for batch import. One thing to keep in mind is that BookStack markdown support is fairly tightly scoped to (commonmark + tables + tasklists), although HTML within MD is supported.
  • On why Markdown is not a good, or even a half-decent, markup language
    9 projects | news.ycombinator.com | 19 Jul 2023
    >A single canonical reference

    https://commonmark.org/

  • Get ready for Bear 2 - We have a quick blog post with some important details and ways you can get notified once it's out!
    1 project | /r/bearapp | 6 Jul 2023
    Typically with major new releases of software, when the number left of the dot (e.g. 2.0) increases, it’s shipped as a separate product. Not always, but generally. The Bear folks can speak for themselves but IIRC a lot of the code was refactored / rewritten to support, for example, CommonMark. So, under the hood, it’s literally brand new in some respects.
  • Best website to write a rulebook for ttrpgs
    3 projects | /r/rpg | 17 May 2023
    I use Obsidian (https://obsidian.md) for a lot of things, including my RPG stuff, and there are options for exporting things as PDFs. It’s great for getting organized and doing research, but I would use other tools for long-form writing and layout. What I like about Obsidian though is that everything is done in Markdown (https://commonmark.org) and I can use Pandoc (https://pandoc.org) to transform the source to whatever I need. The caveat is that Obsidian uses a flavor of Markdown with some non-standard extensions, so a pure Markdown editor like Typora (https://typora.io) might be a better choice depending on your needs.
  • What is the most minimal, strictest variant of Markdown?
    1 project | /r/Markdown | 18 Apr 2023
  • How to display an image
    1 project | /r/gohugo | 11 Apr 2023
    yes, this is the "inventor" of markdown and those rules will always work. Hugo uses something called "Commonmark" which is developed on top of the original markdown. But the original rules will always work too.
  • Lightweight Markup for Ukrainian Texts?
    1 project | /r/Ukrainian | 10 Apr 2023
    Reddit and many other sites support Markdown as an easy way to add emphasis, links, headings, etc. Markdown does not contain any keywords, as it is intended to be language-independent. However, Markdown syntax makes heavy use of square brackets [] and other characters that are difficult to type with an Ukrainian keyboard layout, e.g., the backtick `.
  • I wish Asciidoc was more popular
    4 projects | /r/programming | 6 Feb 2023
    Check out commonmark, that is the Markdown standard supported by numerous converters including pandoc.
  • I wrote a markdown to html converter
    6 projects | /r/golang | 1 Feb 2023
    And if this is an exercise into that you can use a Markdown spec like CommonMark which is the spec Reddit and a variety of other sites use.

What are some alternatives?

When comparing comrak and commonmark-spec you can also consider the following projects:

markdown-rs - CommonMark compliant markdown parser in Rust with ASTs and extensions

pandoc - Universal markup converter

no-style-please - A (nearly) no-CSS, fast, minimalist Jekyll theme.

kramdown - kramdown is a fast, pure Ruby Markdown superset converter, using a strict syntax definition and supporting several common extensions.

tauri-markdown-editor

marktext - 📝A simple and elegant markdown editor, available for Linux, macOS and Windows.

mdcat - cat for markdown

markdown-it-katex - Add Math to your Markdown with a KaTeX plugin for Markdown-it

Docusaurus - Easy to maintain open source documentation websites.

Joplin - Joplin - the secure note taking and to-do app with synchronisation capabilities for Windows, macOS, Linux, Android and iOS.

mdcat - cat for markdown

rehype-sanitize - plugin to sanitize HTML