\W@s|dZddlmZddlmZddlmZddlZddlZddlmZddl m Z ej d Z d d Z Gd d d ZGdddeZGdddeZGdddeZGdddeZGdddeZGdddeZGdddeZGdddeZGdddeZGd d!d!eZdS)"a CORE MARKDOWN BLOCKPARSER =========================================================================== This parser handles basic parsing of Markdown blocks. It doesn't concern itself with inline elements such as **bold** or *italics*, but rather just catches blocks, lists, quotes, etc. The BlockParser is made up of a bunch of BlockProssors, each handling a different type of block. Extensions may add/replace/remove BlockProcessors as they need to alter how markdown blocks are parsed. )absolute_import)division)unicode_literalsN)util) BlockParserMARKDOWNcKst|}t||jdr?rKrLr#r9r;rVrOrrrrrs     $ rc@s.eZdZdZddZddZdS)rz Process code blocks. cCs|jd|jS)Nr))r,r!)r"r&r8rrrr9szCodeBlockProcessor.testcCs|j|}|jd}d}|dk r|jdkrt|r|djdkr|d}|j|\}}tjd|j|jf|_n[tj j |d}tj j |d}|j|\}}tjd|j|_|r|j d|ndS)Nrr*prer z%s %s z%s ) r'rNrJr%r3r AtomicStringr0rstriprRrYrT)r"r&r:rXr8theRestr r_rrrr;s' (zCodeBlockProcessor.runN)r<r=r>r?r9r;rrrrrs  rc@sCeZdZejdZddZddZddZdS) rz(^|\n)[ ]{0,3}>[ ]?(.*)cCst|jj|S)N)boolREsearch)r"r&r8rrrr9szBlockQuoteProcessor.testcs|jd}jj|}|r|d|j}jj||gdjfdd||jdjdD}nj|}|dk r|j dkr|}nt j j |d}jj jdjj||jj jdS)Nrr(csg|]}j|qSr)clean).0r2)r"rr s z+BlockQuoteProcessor.run..Z blockquote)rNrdrestartrrQr/r+r'rJrrRrYrHrPrUrW)r"r&r:r8r]beforerXr r)r"rr;s) zBlockQuoteProcessor.runcCsC|jj|}|jdkr(dS|r;|jdS|SdS)z( Remove ``>`` from beginning of a line. >r*N)rdr[r.r\)r"r2r]rrrrfs  zBlockQuoteProcessor.cleanN) r<r=r>rCrDrdr9r;rfrrrrrs   rc@seZdZdZdZejdZejdZejdZ dZ ddgZ dd Z d d Z d d ZdS)rz Process ordered list blocks. rBz^[ ]{0,3}\d+\.[ ]+(.*)z ^[ ]{0,3}((\d+\.)|[*+-])[ ]+(.*)z^[ ]{4,7}((\d+\.)|[*+-])[ ]+.*1rAcCst|jj|S)N)rcrdr[)r"r&r8rrrr9:szOListProcessor.testc CsU|j|jd}|j|}|dk r]|j|jkr]|}|d jrtjjd}|dj|_d|d_|dj d|n|j|d}|dk r|j rtjj |dd}|j j |_d|_ ntjj |d}|j jjd|jd} |j j|| g|j jjnb|jdkru|}nJtjj ||j}|j jj r|jd kr|j|jd      zOListProcessor.runcCs g}x|jdD]}|jj|}|r| r}|jdkr}tjd}|j|jdj|_n|j|jdq|j j|r|dj d|j rd|d |f|d r?rrrCrDrdrzrErtror9r;rnrrrrr(s    ;rc@s+eZdZdZdZejdZdS)rz Process unordered list blocks. rAz^[ ]{0,3}[*+-][ ]+(.*)N)r<r=r>r?rrrCrDrdrrrrrs rc@s=eZdZdZejdZddZddZdS)rz Process Hash Headers. z.(^|\n)(?P#{1,6})(?P
.*?)#*(\n|$)cCst|jj|S)N)rcrdre)r"r&r8rrrr9szHashHeaderProcessor.testcCs|jd}|jj|}|r|d|j}||jd}|rr|jj||gntjj |dt |j d}|j dj |_ |r|jd|qntjd|dS)Nrzh%dr5headerzWe've got a problem header: %r)rNrdreriendrrQrrRrYr%r\r.r0rTloggerwarn)r"r&r:r8r]rjafterhrrrr;s(zHashHeaderProcessor.runN) r<r=r>r?rCrDrdr9r;rrrrrs  rc@sCeZdZdZejdejZddZddZ dS)rz Process Setext-style Headers. z^.*?\n[=-]+[ ]*(\n|$)cCst|jj|S)N)rcrdr[)r"r&r8rrrr9szSetextHeaderProcessor.testcCs|jdjd}|djdr4d}nd}tjj|d|}|dj|_t|dkr|j ddj |ddndS)Nrr(r=rlzh%d) rNr+r,rrRrYr.r0r%rTr/)r"r&r:r1r5rrrrr;s zSetextHeaderProcessor.runN) r<r=r>r?rCrD MULTILINErdr9r;rrrrrs  rc@sIeZdZdZdZejeejZddZ ddZ dS)rz Process Horizontal Rules. zB^[ ]{0,3}((-+[ ]{0,2}){3,}|(_+[ ]{0,2}){3,}|(\*+[ ]{0,2}){3,})[ ]*cCsW|jj|}|rS|jt|ksF||jdkrS||_dSdS)Nr(TF) SEARCH_RErer|r%r[)r"r&r8r]rrrr9s 4 zHRProcessor.testcCs|jd}|d|jjjd}|rP|jj||gntjj|d||jj dj d}|r|j d|ndS)Nrr(r ) rNr[rirarrQrrRrYr|rqrT)r"r&r:r8ZprelinesZ postlinesrrrr;s""zHRProcessor.runN) r<r=r>r?rdrCrDrrr9r;rrrrrs  rc@s.eZdZdZddZddZdS)rz< Process blocks that are empty or start with an empty line. cCs| p|jdS)Nr()r,)r"r&r8rrrr9szEmptyBlockProcessor.testcCs|jd}d}|rMd}|dd}|rM|jd|qMn|j|}|dk r|jdkrt|r|djdkrtjd|dj|f|d_ndS)Nrz r(rr_r z%s%s)rNrTr'rJr%rr`r0)r"r&r:r8ZfillerrbrXrrrr;s:zEmptyBlockProcessor.runN)r<r=r>r?r9r;rrrrrs  rc@s.eZdZdZddZddZdS)rz Process Paragraph blocks. cCsdS)NTr)r"r&r8rrrr9szParagraphProcessor.testcCs|jd}|jr|jjjdr|j|}|dk r}|jrmd|j|f|_qd||_q|jrd|j|f|_q|j|_qt j j |d}|j|_ndS)NrrZz%s %sz %srM) rNr.rrHrIr'rpr0rqrrRrY)r"r&r:r8rXrMrrrr;s     zParagraphProcessor.runN)r<r=r>r?r9r;rrrrr s  r)r? __future__rrrloggingrCr*rZ blockparserr getLoggerr}rrrrrrrrrrrrrrrr s(   X`(k#