The HTML is parsed the way a browser parses it rather than matched with regular expressions. End tags HTML lets you leave out, such as </p>, </li> and </td>, are closed where a browser closes them, entities are decoded from the full HTML5 table, and the contents of <script> and <style> are read as text and then dropped along with comments. Elements a browser does not show are removed too: the hidden attribute, an inline display: none and 1×1 tracking images. Whitespace collapses as it renders, so a run of spaces and line breaks becomes one space, and none at the edge of a block. Each element is then written as Markdown: headings with # or an underline, lists with their start number and nesting, <pre> as a fenced block with the language from class="language-…", and for GitHub Flavored Markdown, tables with column alignment from align or text-align, ~~strikethrough~~ and task lists. Bold and italic written as inline styles, which is how Google Docs exports them, are read from font-weight and font-style.
The step most converters skip is escaping. Text that happens to contain Markdown syntax changes meaning when the Markdown is rendered: a literal * or _ opens emphasis, a backtick opens code, [ and ] start a link, < starts raw HTML, a # or "1." at the start of a line becomes a heading or a list, and & before a name becomes an entity. Each of these is escaped with a backslash, as are | and ~ for GitHub, and bare URLs that GitHub would otherwise turn into links. Emphasis needs more than escaping. CommonMark lets ** open only when the next character is not a space, and not punctuation straight after a letter, so a<b>"x"</b>b cannot be written with asterisks at all. Every bold, italic and strikethrough is checked against the characters that will surround it, and written as <strong>, <em> or <del> where no delimiter would work. The test suite converts a corpus of fragments, renders the Markdown back with this site’s CommonMark renderer and checks that the HTML matches.
The rule for what Markdown cannot express: markup with a meaning of its own — <u>, <sub>, <sup>, <kbd>, <mark>, <abbr title>, <details>, <dl>, <iframe>, <video>, and tables with merged cells or lists inside cells — is kept as raw HTML, which CommonMark passes through; presentational wrappers such as <span>, <div> and <section> are unwrapped; form controls, inline SVG and <canvas> are removed. Tables marked role="presentation", tables that contain tables, and single-column tables without a header are layout, as emails are built, so their cells are unwrapped in order. GitHub strips some raw HTML, such as <iframe>, and links a bare e-mail address whatever the escaping; both are limits of GitHub, not of the conversion.