There are 3 ways to highlight code: 1) using start-of-line indentation 2) using 3 or more backticks enclosing a multiline block of code or 3) inline code.
1 and 3 are part of John Gruber original Markdown specification.
Here is the way to achieve this. You need to perform 3 separate regexp tests:
Using indentation
(?:\n{2,}|\A) # Starting at beginning of string or with 2 new lines
(?<code_all>
(?:
(?<code_prefix> # Lines must start with a tab or a tab-width of spaces
[ ]{4}
|
\t
)
(?<code_content>.*\n+) # with some content, possibly nothing followed by a new line
)+
)
(?<code_after>
(?=^[ ]{0,4}\S) # Lookahead for non-space at line-start
|
\Z # or end of doc
)
2a) Using code block with backticks (vanilla markdown)
(?:\n+|\A)? # Necessarily at the begining of a new line or start of string
(?<code_all>
(?<code_start>
[ ]{0,3} # Possibly up to 3 leading spaces
\`{3,} # 3 code marks (backticks) or more
)
\n+
(?<code_content>.*?) # enclosed content
\n+
(?<!`)
\g{code_start} # balanced closing block marks
(?!`)
[ \t]* # possibly followed by some space
\n
)
(?<code_trailing_new_line>\n|\Z) # and a new line or end of string
2b) Using code block with backticks with some class specifier (extended markdown)
(?:\n+|\A)? # Necessarily at the beginning of a new line
(?<code_all>
(?<code_start>
[ ]{0,3} # Possibly up to 3 leading spaces
\`{3,} # 3 code marks (backticks) or more
)
[ \t]* # Possibly some spaces or tab
(?:
(?:
(?<code_class>[\w\-\.]+) # or a code class like html, ruby, perl
(?:
[ \t]*
\{(?<code_def>[^\}]+)\} # a definition block like {.class#id}
)? # Possibly followed by class and id definition in curly braces
)
|
(?:
[ \t]*
\{(?<code_def>[^\}]+)\} # a definition block like {.class#id}
) # Followed by class and id definition in curly braces
)
\n+
(?<code_content>.*?) # enclosed content
\n+
(?<!`)
\g{code_start} # balanced closing block marks
(?!`)
)
(?:\n|\Z) # and a new line or end of string
Using 1 or more backticks for inline code
(?<!\\) # Ensuring this is not escaped
(?<code_all>
(?<code_start>\`{1,}) # One or more backtick(s)
(?<code_content>.+?) # Code content inbetween back sticks
(?<!`) # Not preceded by a backtick
\g{code_start} # Balanced closing backtick(s)
(?!`) # And not followed by a backtick
)