3 \52@sddlmZddlmZddlmZddlmZddlmZddZd d ZGd d d ej Z Gd dde Z Gddde Z dS))unicode_literals)absolute_import)util)odict)inlinepatternscKs$tj}t||d<t||d<|S)z0 Build the default treeprocessors for Markdown. ZinlineZprettify)r OrderedDictInlineProcessorPrettifyTreeprocessor) md_instancekwargstreeprocessorsr$build/lib/markdown/treeprocessors.pybuild_treeprocessorss  rcCst|tjst|tjSdS)z Check if it's string F) isinstancer AtomicString string_type)srrrisStrings  rc@seZdZdZddZdS) Treeprocessora' Treeprocessors are run on the ElementTree object before serialization. Each Treeprocessor implements a "run" method that takes a pointer to an ElementTree, modifies it as necessary and returns an ElementTree object. Treeprocessors must extend markdown.Treeprocessor. cCsdS)a" Subclasses of Treeprocessor should implement a `run` method, which takes a root ElementTree. This method can return another ElementTree object, and the existing root ElementTree will be replaced, or it can modify the current tree and return None. Nr)selfrootrrrrun"szTreeprocessor.runN)__name__ __module__ __qualname____doc__rrrrrrs rc@s^eZdZdZddZddZddZdd Zdd d ZdddZ ddZ dddZ ddZ dS)r zJ A Treeprocessor that traverses a tree, applying inline patterns. cCs<tj|_tj|_dt|jt|j|_tj|_||_ dS)N) rINLINE_PLACEHOLDER_PREFIX$_InlineProcessor__placeholder_prefixETXZ$_InlineProcessor__placeholder_suffixlenZ$_InlineProcessor__placeholder_lengthINLINE_PLACEHOLDER_RE _InlineProcessor__placeholder_remarkdown)rmdrrr__init__1s zInlineProcessor.__init__cCs dt|j}tj|}||fS)z Generate a placeholder z%04d)r" stashed_nodesrINLINE_PLACEHOLDER)rtypeidhashrrrZ__makePlaceholder9s z!InlineProcessor.__makePlaceholdercCs4|jj||}|r$|jd|jfSd|dfSdS)z Extract id from data string, start from index Keyword arguments: * data: string * index: index, from which we start search Returns: placeholder id and string index, after the found placeholder. rN)r$searchgroupend)rdataindexmrrrZ__findPlaceholder?s z!InlineProcessor.__findPlaceholdercCs|j|\}}||j|<|S)z Add node to stash )!_InlineProcessor__makePlaceholderr()rnoder* placeholderr+rrrZ __stashNodeQs zInlineProcessor.__stashNodercCsVt|tjsRd}x@|t|jjkrP|j|jjj||||\}}}|s|d7}qW|S)a Process string with inline patterns and replace it with placeholders Keyword arguments: * data: A line of Markdown text * patternIndex: The index of the inlinePattern to start with Returns: String with placeholders. rr)rrrr"r%inlinePatterns_InlineProcessor__applyPatternvalue_for_index)rr0 patternIndex startIndexZmatchedrrrZ__handleInlineWs   zInlineProcessor.__handleInlineTcCs||r|j}d|_n |j}d|_|j||}| rR||k rRt|j|}|j|nd}|jx|D]}|j||qdWdS)a4 Process placeholders in Element.text or Element.tail of Elements popped from self.stashed_nodes. Keywords arguments: * node: parent node * subnode: processing node * isText: bool variable, True - it's text, False - it's tail Returns: None Nr)texttail%_InlineProcessor__processPlaceholderslistr1removereverseinsert)rr4ZsubnodeZisTextr;Z childResultposnewChildrrrZ__processElementTextns   z$InlineProcessor.__processElementTextc sPfdd}gd}x2|rJ|j|j|}|dkr|j||\}}||jkr|jj|}|dkrz|||} || t|sx`|gt|D]>} | jr| jjr|j || d| j r| j jr|j | | qWn|||}q|}j |n"|t |j} |||| | }q||d} t |tjr.linkTextrrFNrD)findr !_InlineProcessor__findPlaceholderr(getrr>r<strip$_InlineProcessor__processElementTextr;appendr"rrr) rr0rErGZ strartIndexr1r+Z phEndIndexr4r;childr/r)rErFrZ__processPlaceholderssD            z%InlineProcessor.__processPlaceholdersc Cs|jj||d}|d|}|s0|ddfS|j|}|dkrf|dt||jt|jdfSt|st|jt j sxN|gt |D]<}t|s|jr|j |j|d|_|j r|j |j ||_ qW|j||j} d||jd| |jdfddfS)a Check if the line fits the pattern, create the necessary elements, add it to stashed_nodes. Keyword arguments: * data: the text to be processed * pattern: the pattern to be checked * patternIndex: index of current pattern * startIndex: string index, from which we start searching Returns: String with placeholders instead of ElementTree elements. NFrTrz%s%s%s%srD)ZgetCompiledRegExpmatchZ handleMatchr"spangroupsrrr;rrr>_InlineProcessor__handleInliner<_InlineProcessor__stashNoder*r.) rpatternr0r9r:rPZleftDatar4rOr5rrrZ__applyPatterns*   $  zInlineProcessor.__applyPatterncCsi|_|g}x|r|j}g}x|D]}|jrvt|jtj rv|j}d|_|j|j||}||7}|j||f|j r|j|j }tj j d} |j|| } | jr| j|_ nd|_ t |j |d} | jx| D]} |j| | qWt|r(|j|q(Wx|D]\} }|jjr<| jrr1r@rAr"r%enable_attributesrrZhandleAttributes)rtreestackZ currElementZ insertQueuerOr;lstr<ZdumbyZ tailResultrBrCelementirrrrsV            zInlineProcessor.runN)r)T)r) rrrrr'r3rJrTrSrMr=r7rrrrrr ,s  !D ,r c@s eZdZdZddZddZdS)r z& Add linebreaks to the html document. cCsd}tj|jr|jdkr|j s.|jj rLt|rLtj|djrL||_x"|D]}tj|jrR|j|qRW|j s|jj r||_|j s|jj r||_dS)z5 Recursively add linebreaks to ElementTree children.  codeprerN)rarb)r isBlockLeveltagr;rLr"_prettifyETreer<)relemr_errrreHs  z$PrettifyTreeprocessor._prettifyETreecCs|j||jd}x4|D],}|j s2|jj r:d|_qd|j|_qW|jd}x:|D]2}t|rZ|djdkrZ|djjd|d_qZWdS)z, Add linebreaks to ElementTree root object. brr`z %srbrraN)re getiteratorr<rLr"rdr;rstrip)rrZbrsrhZpresrbrrrrXs     zPrettifyTreeprocessor.runN)rrrrrerrrrrr Esr N) __future__rrrHrrrrr Processorrr r rrrrs