ó Šç\c@@sîdZddlmZddlmZddlmZddlmZddlZyddlm Z m Z Wn'e k r•ddl m Z m Z nXydd l m Z Wne k rÉddlZ nXd „Zd Zd ed deddedZdZdZdZdZdZdZdZdZeedZdedZeedZedZdedZdZdZ d Z!d!Z"d"Z#d#Z$d$„Z%ej&d%ƒZ'd&„Z(d'e)fd(„ƒYZ*d)e*fd*„ƒYZ+d+e*fd,„ƒYZ,d-e*fd.„ƒYZ-d/e-fd0„ƒYZ.d1e*fd2„ƒYZ/d3e-fd4„ƒYZ0d5e*fd6„ƒYZ1d7e*fd8„ƒYZ2d9e2fd:„ƒYZ3d;e2fd<„ƒYZ4d=e4fd>„ƒYZ5d?e*fd@„ƒYZ6dAe*fdB„ƒYZ7dS(Cuƒ INLINE PATTERNS ============================================================================= Inline patterns such as *emphasis* are handled by means of auxiliary objects, one per pattern. Pattern objects must be instances of classes that extend markdown.Pattern. Each pattern object uses a single regular expression and needs support the following methods: pattern.getCompiledRegExp() # returns a regular expression pattern.handleMatch(m) # takes a match object and returns # an ElementTree element or just plain text All of python markdown's built-in patterns subclass from Pattern, but you can add additional patterns that don't. Also note that all the regular expressions used by inline must capture the whole block. For this reason, they all start with '^(.*)' and end with '(.*)!'. In case with built-in expression Pattern takes care of adding the "^(.*)" and "(.*)!". Finally, the order in which regular expressions are applied is very important - e.g. if we first replace http://.../ links with tags and _then_ try to replace inline html, we would end up with a mess. So, we apply the expressions in the following order: * escape and backticks have to go before everything else, so that we can preempt any markdown patterns by escaping them. * then we handle auto-links (must be done before inline html) * then we handle inline HTML. At this point we will simply replace all inline HTML strings with a placeholder and add the actual HTML to a hash. * then inline images (must be done before links) * then bracketed links, first regular then reference-style * finally we apply strong and emphasis i(tabsolute_import(tunicode_literalsi(tutil(todictN(turlparset urlunparse(tentitiescK@s~tjƒ}ttƒ|d|((?:(?:\(.*?\))|[^\(\)]))*?)\s*((['"])(.*?)\12\s*)?\)u\!u%\s*\((<.*?>|([^")]+"[^"]*"|[^\)]*))\)u\s?\[([^\]]*)\]u \[([^\]]+)\]u((^| )(\*|_)( |$))u*<((?:[Ff]|[Hh][Tt])[Tt][Pp][Ss]?://[^>]*)>u<([^> \!]*@[^> ]*)>u"(\<([a-zA-Z/][^\>]*?|\!--.*?--)\>)u(&[\#a-zA-Z0-9]*;)u \ncC@sO|jdƒr|jdƒs<|jdƒrG|jdƒrG|dd!S|SdS(u#Remove quotes from around a string.u"u'iiÿÿÿÿN(t startswithtendswith(tstring((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pytdequote|s u\{@([^\}]*)=([^\}]*)}c@s‡fd†}tj||ƒS(uDSet values of an element based on attribute definitions ({@id=123}).c@s2ˆj|jdƒ|jdƒjddƒƒdS(Niiu u (tsettgrouptreplace(tmatch(tparent(s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pytattributeCallbackˆs(tATTR_REtsub(ttextR5R6((R5s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pythandleAttributes†stPatterncB@s>eZdZdd„Zd„Zd„Zd„Zd„ZRS(u*Base class that inline patterns subclass. cC@sK||_tjd|tjtjBƒ|_t|_|rG||_ndS(u– Create an instant of an inline pattern. Keyword arguments: * pattern: A regular expression that matches a pattern u^(.*?)%s(.*?)$N( tpatterntretcompiletDOTALLtUNICODEt compiled_retFalset safe_modetmarkdown(tselfR<tmarkdown_instance((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyt__init__•s   cC@s|jS(u' Return a compiled regular expression. (RA(RE((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pytgetCompiledRegExp§scC@sdS(uÌReturn a ElementTree element from the given match. Subclasses should override this method. Keyword arguments: * m: A re match object containing a match of the pattern. N((REtm((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyt handleMatch«s cC@s |jjS(u+ Return class name, to define pattern type (t __class__t__name__(RE((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyttype·sc@s`y|jjdj‰Wntk r+|SX‡fd†‰‡‡fd†}tjj||ƒS(u> Return unescaped text given text with an inline placeholder. uinlinec3@s…|j}t|tjƒ r,|dk r,dS|jr@|jVnx>|D]6}xˆ|ƒD] }|VqZW|jrG|jVqGqGWdS(u8 Reimplement Element.itertext for older python versions N(ttagt isinstanceRt string_typetNoneR9ttail(telRNtets(titertext(s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRVÁs      c@sZ|jdƒ}|ˆkrVˆj|ƒ}t|tjƒr@|Sdjˆ|ƒƒSndS(Niu(R2tgetRORRPtjoin(RItidtvalue(RVtstash(s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyt get_stashÍs  (RDttreeprocessorst stashed_nodestKeyErrorRtINLINE_PLACEHOLDER_RER8(RER9R\((RVR[s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pytunescape»s   N( RLt __module__t__doc__RQRGRHRJRMRa(((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyR;’s    RcB@seZdZd„ZRS(u0 Return a simple text of group(2) of a Pattern. cC@s&|jdƒ}|tjkr"dS|S(Ni(R2RtINLINE_PLACEHOLDER_PREFIXRQ(RERIR9((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRJÛs(RLRbRcRJ(((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRÙsR cB@seZdZd„ZRS(u Return an escaped character. cC@sF|jdƒ}||jjkr>dtjt|ƒtjfSdSdS(Niu%s%s%s(R2RDt ESCAPED_CHARSRtSTXtordtETXRQ(RERItchar((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRJås(RLRbRcRJ(((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyR âsR#cB@s eZdZd„Zd„ZRS(u[ Return element of type `tag` with a text attribute of group(3) of a Pattern. cC@stj||ƒ||_dS(N(R;RGRN(RER<RN((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRGóscC@s+tjj|jƒ}|jdƒ|_|S(Ni(RtetreetElementRNR2R9(RERIRS((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRJ÷s(RLRbRcRGRJ(((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyR#ís RcB@seZdZd„ZRS(u3 Return an element of type `tag` with no children. cC@stjj|jƒS(N(RRjRkRN(RERI((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRJÿs(RLRbRcRJ(((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRýsRcB@s eZdZd„Zd„ZRS(u9 Return a `` element containing the matching text. cC@stj||ƒd|_dS(Nucode(R;RGRN(RER<((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRGscC@s:tjj|jƒ}tj|jdƒjƒƒ|_|S(Ni(RRjRkRNt AtomicStringR2tstripR9(RERIRS((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRJ s!(RLRbRcRGRJ(((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRs R!cB@seZdZd„ZRS(ufReturn a ElementTree element nested in tag2 nested in tag1. Useful for strong emphasis etc. cC@sU|jjdƒ\}}tjj|ƒ}tjj||ƒ}|jdƒ|_|S(Nu,i(RNtsplitRRjRkt SubElementR2R9(RERIttag1ttag2tel1tel2((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRJs (RLRbRcRJ(((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyR!sRcB@s eZdZd„Zd„ZRS(u1 Store raw inline html and return a placeholder. cC@s1|j|jdƒƒ}|jjj|ƒ}|S(Ni(RaR2RDt htmlStashtstore(RERItrawhtmlt place_holder((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRJsc@sQyˆjjdj‰Wntk r+|SX‡‡fd†}tjj||ƒS(u> Return unescaped text given text with an inline placeholder. uinlinec@sT|jdƒ}ˆj|ƒ}|dk rPyˆjj|ƒSWqPd|SXndS(Niu\%s(R2RWRQRDt serializer(RIRYRZ(RER[(s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyR\*s (RDR]R^R_RR`R8(RER9R\((RER[s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRa$s   (RLRbRcRJRa(((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRs RcB@s eZdZd„Zd„ZRS(u- Return a link element from the given match. cC@sÕtjjdƒ}|jdƒ|_|jdƒ}|jdƒ}|r“|ddkrh|dd!}n|jd |j|j|jƒƒƒƒn|jd d ƒ|rÑt |j|ƒƒ}|jd |ƒn|S( Nuaii i iu), we whitelist known safe url formats. Most urls contain a network location, however some are known not to (i.e.: mailto links). Script urls do not contain a location. Additionally, for `javascript:...`, the scheme would be "javascript" but some aliases will appear to `urlparse()` to have no scheme. On top of that relative links (i.e.: "foo/bar.html") have no scheme. Therefore we must check "path", "parameters", "query" and "fragment" for any literal colons. We don't check "scheme" for colons because it *should* never have any and "netloc" must allow the form: `username:password@host:port`. uumailtounewsuhttpuhttpsuftpuftpsiu:(RDRRt ValueErrorR( REturltschemetnetloctpathtparamstquerytfragmenttlocless_schemestallowed_schemestpart((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRyJs  &   (RLRbRcRJRy(((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyR6s RcB@seZdZd„ZRS(u, Return a img element from the given match. cC@s0tjjdƒ}|jdƒjƒ}|rŒ|d}|ddkrg|ddkrg|dd!}n|jd|j|j|ƒƒƒn|jdd ƒt|ƒdkrÝ|jd t |jd j |dƒƒƒƒn|j j rt |jd ƒ|ƒ}n|jd ƒ}|jd |j|ƒƒ|S(Nuimgi iuiusrcuutitleu iualt(RRjRkR2RnR1RyRatlenR0RXRDtenable_attributesR:(RERIRSt src_partstsrcttruealt((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRJys  %/ (RLRbRcRJ(((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRwsR cB@s5eZdZejdejƒZd„Zd„ZRS(u6 Match to a stored reference and return link element. u[ ]?\ncC@s´y|jdƒjƒ}Wntk r2d}nX|sQ|jdƒjƒ}n|jjd|ƒ}||jjkr|dS|jj|\}}|jdƒ}|j|||ƒS(Ni iu ( R2tlowert IndexErrorRQtNEWLINE_CLEANUP_RER8RDt referencestmakeTag(RERIRYR{RzR9((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRJ“s  cC@sQtjjdƒ}|jd|j|ƒƒ|rD|jd|ƒn||_|S(Nuauhrefutitle(RRjRkR1RyR9(RER{RzR9RS((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyR¦s  ( RLRbRcR=R>t MULTILINERŽRJR(((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyR Žs RcB@seZdZd„ZRS(u5 Match to a stored reference and return img element. cC@stjjdƒ}|jd|j|ƒƒ|rD|jd|ƒn|jjrbt||ƒ}n|jd|j|ƒƒ|S(Nuimgusrcutitleualt( RRjRkR1RyRDRˆR:Ra(RER{RzR9RS((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyR³s (RLRbRcR(((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyR±sRcB@seZdZd„ZRS(uC Return a link Element given an autolink (``). cC@sStjjdƒ}|jd|j|jdƒƒƒtj|jdƒƒ|_|S(Nuauhrefi(RRjRkR1RaR2RlR9(RERIRS((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRJÂs"(RLRbRcRJ(((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRÀsRcB@seZdZd„ZRS(uT Return a mailto link Element given an automail link (``). cC@sætjjdƒ}|j|jdƒƒ}|jdƒrL|tdƒ}nd„}g|D]}|t|ƒƒ^q\}tjdj |ƒƒ|_ d|}dj g|D]}tj dt|ƒ^q¬ƒ}|j d|ƒ|S(Nuaiumailto:cS@s>tjj|ƒ}|r)dtj|fSdtj|fSdS(u=Return entity definition by code, or the code if not defined.u%s%s;u%s#%d;N(Rtcodepoint2nameRWRtAMP_SUBSTITUTE(tcodetentity((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyR’Òsuu#%d;uhref( RRjRkRaR2R-R‡RgRlRXR9R“R1(RERIRStemailR’tlettertletterstmailto((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRJÌs %  *(RLRbRcRJ(((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyRÈs(8Rct __future__RRtRRR=t urllib.parseRRt ImportErrorthtmlRthtmlentitydefsR,t NOBRACKETtBRKtNOIMGR R R%R$R"R'R(RRR RRR RRRRRR0R>R7R:tobjectR;RR R#RRR!RRRR RRR(((s;/usr/lib/python2.7/site-packages/markdown/inlinepatterns.pyt*sj    !&   G   A#