{"action":"created","issue":{"url":"https://api.github.com/repos/ShadowKyogre/mikidown/issues/53","labels_url":"https://api.github.com/repos/ShadowKyogre/mikidown/issues/53/labels{/name}","comments_url":"https://api.github.com/repos/ShadowKyogre/mikidown/issues/53/comments","events_url":"https://api.github.com/repos/ShadowKyogre/mikidown/issues/53/events","html_url":"https://github.com/ShadowKyogre/mikidown/pull/53","id":107093355,"number":53,"title":"A better regex for parsing headers","user":{"login":"kekh","id":8396153,"avatar_url":"https://avatars.githubusercontent.com/u/8396153?v=3","gravatar_id":"","url":"https://api.github.com/users/kekh","html_url":"https://github.com/kekh","followers_url":"https://api.github.com/users/kekh/followers","following_url":"https://api.github.com/users/kekh/following{/other_user}","gists_url":"https://api.github.com/users/kekh/gists{/gist_id}","starred_url":"https://api.github.com/users/kekh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kekh/subscriptions","organizations_url":"https://api.github.com/users/kekh/orgs","repos_url":"https://api.github.com/users/kekh/repos","events_url":"https://api.github.com/users/kekh/events{/privacy}","received_events_url":"https://api.github.com/users/kekh/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-09-17T22:59:21Z","updated_at":"2015-09-23T17:14:13Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/ShadowKyogre/mikidown/pulls/53","html_url":"https://github.com/ShadowKyogre/mikidown/pull/53","diff_url":"https://github.com/ShadowKyogre/mikidown/pull/53.diff","patch_url":"https://github.com/ShadowKyogre/mikidown/pull/53.patch"},"body":"Not so sexy mainly because of my lacks of knowledge, plus this [shitty limitation](http://stackoverflow.com/questions/9030305/regular-expression-lookbehind-doesnt-work-with-quantifiers-or)...\r\nBut at least now you can write fenced codes blocks without polluting your Table of contents!\r\n\r\nNote: headers must now contain a space after the `#` char(s).. because all examples in Markdown documentation use this syntax, but it's trivial to reverse."},"comment":{"url":"https://api.github.com/repos/ShadowKyogre/mikidown/issues/comments/142667956","html_url":"https://github.com/ShadowKyogre/mikidown/pull/53#issuecomment-142667956","issue_url":"https://api.github.com/repos/ShadowKyogre/mikidown/issues/53","id":142667956,"user":{"login":"ShadowKyogre","id":673620,"avatar_url":"https://avatars.githubusercontent.com/u/673620?v=3","gravatar_id":"","url":"https://api.github.com/users/ShadowKyogre","html_url":"https://github.com/ShadowKyogre","followers_url":"https://api.github.com/users/ShadowKyogre/followers","following_url":"https://api.github.com/users/ShadowKyogre/following{/other_user}","gists_url":"https://api.github.com/users/ShadowKyogre/gists{/gist_id}","starred_url":"https://api.github.com/users/ShadowKyogre/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ShadowKyogre/subscriptions","organizations_url":"https://api.github.com/users/ShadowKyogre/orgs","repos_url":"https://api.github.com/users/ShadowKyogre/repos","events_url":"https://api.github.com/users/ShadowKyogre/events{/privacy}","received_events_url":"https://api.github.com/users/ShadowKyogre/received_events","type":"User","site_admin":false},"created_at":"2015-09-23T17:14:13Z","updated_at":"2015-09-23T17:14:13Z","body":"Finally got back here after twiddling with the code. I haven't merged this upstream yet because I made some improvements on the code that pass that particular test case I found.\r\n\r\n~~~python\r\ndef parseHeaders(source, strip_fenced_block=False, strip_ascii_math=False):\r\n    \"\"\" Parse headers to construct Table Of Contents\r\n        return: [(level, text, position, anchor)]\r\n        position/anchor is the header position in notesEdit/notesView\r\n    \"\"\"\r\n\r\n    hdrs = []\r\n    headers = []\r\n    used_ids = set()           # In case there are headers with the same name.\r\n\r\n    # copied from the asciimathml so we don't have to have a hard dependency to strip\r\n    ASCIIMATHML_RE = re.compile(r'^(.*)\\$\\$([^\\$]*)\\$\\$(.*)$', re.M)\r\n\r\n    # copied from the fenced block code\r\n    FENCED_BLOCK_RE = re.compile(r'''\r\n(?P<fence>^(?:~{3,}|`{3,}))[ ]*         # Opening ``` or ~~~\r\n(\\{?\\.?(?P<lang>[a-zA-Z0-9_+-]*))?[ ]*  # Optional {, and lang\r\n# Optional highlight lines, single- or double-quote-delimited\r\n(hl_lines=(?P<quot>\"|')(?P<hl_lines>.*?)(?P=quot))?[ ]*\r\n}?[ ]*\\n                                # Optional closing }\r\n(?P<code>.*?)(?<=\\n)\r\n(?P=fence)[ ]*$''', re.MULTILINE | re.DOTALL | re.VERBOSE)\r\n\r\n    # hash headers\r\n    #HRE = re.compile(r'^(#+)(.+)')\r\n    # setext headers\r\n    #SRE = re.compile(r'(.+)\\n([=-]+[ ]*)(\\n|$)')\r\n\r\n    in_code_block = False\r\n\r\n    filtered_source = source\r\n    #if applicable, strip out any trouble text before we start parsing the headers\r\n    if strip_fenced_block:\r\n        filtered_source = FENCED_BLOCK_RE.sub(\"\", filtered_source)\r\n    if strip_ascii_math:\r\n        filtered_source = ASCIIMATHML_RE.sub(\"\", filtered_source)\r\n\r\n    RE = re.compile(r'(?:(?<!```\\s)^(\\S+#+ )(.+)$(?!\\s```))', re.MULTILINE)\r\n    for m in RE.finditer(filtered_source):\r\n        level = len(m.group(1))\r\n        hdr = m.group(2)\r\n        pos = m.start()\r\n        hdrs.append((pos, level, hdr))\r\n\r\n    RE = re.compile(r'(.+)\\n([=-]+[ ]*)(\\n|$)', re.MULTILINE)\r\n    for m in RE.finditer(filtered_source):\r\n        if m.group(2).startswith('='):\r\n            level = 1\r\n        else:\r\n            level = 2\r\n        hdr = m.group(1)\r\n        pos = m.start()\r\n        hdrs.append((pos, level, hdr))\r\n\r\n    hdrs.sort()\r\n    for (p, l, h) in hdrs:\r\n        anchor = unique(slugify(h, '-'), used_ids)\r\n        headers.append((l, h, p, anchor))\r\n    return headers\r\n~~~\r\n\r\nLet me know if I should close the pull request and/or send a pull request so your personal fork can be updated too. Currently testing how the updated function compares to yours for header parsing."}}