B ˝`z} @sPUdZddlZddlZddlZddlZddlmZddlm Z ddlm Z ddl m Z ddl mZdd l mZdd lmZdd lmZdd lmZdd lmZddlmZejrddlZddlmZddlmZddlmZGdddejZ Gddde Z!ej"e e!fZ#dZ$ej%e&dfe'd<e(dZ)GdddZ*eeej+ej+ej"ej+efdddZ,ej-e&ge&fej-de&fdd d!Z.ej-e&e&e/ge&fej-de&fdd"d#Z0ej-e&e&ge&fej-de&fdd$d%Z1ej-e&e&e&e/ge&fej-de&fdd&d'Z2Gd(d)d)e*Z3Gd*d+d+e*Z4Gd,d-d-e*Z5Gd.d/d/e*Z6Gd0d1d1e*Z7Gd2d3d3e*Z8e$d4fe j9ej:e&e;ejGd8d9d9Z?ej@ej:e&ej:e&ejAe&ej+fejrNodeListrAr rCrDExprKeywordrIrJrrrrr'7s( $  @r') __contextrErFrcOs|j|df||S)Nr)callZresolve)rVrErFrrr_gettext_aliassrX)funcrcs"ttttjtdfdd }|S)N)rV__string variablesrcs$||}|jjrt|}||S)N)rWeval_ctx autoescaper)rVrZr[r7)rYrrrs z"_make_new_gettext..gettext)r r rr0Any)rYrr)rYr_make_new_gettexts r_cs&ttttttjtdfdd }|S)N)rV __singular__plural__numr[rcs4|d|||||}|jjr,t|}||S)Nnum) setdefaultrWr\r]r)rVr`rarbr[r7)rYrrrs  z$_make_new_ngettext..ngettext)r r rr r0r^)rYrr)rYr_make_new_ngettextsrecs$tttttjtdfdd }|S)N)rV __string_ctxrZr[rcs2|d||||}|jjr*t|}||S)Nr")rdrWr\r]r)rVrfrZr[r7)rYrrr#s  z$_make_new_pgettext..pgettext)r r rr0r^)rYr#r)rYr_make_new_pgettexts  rgc s(tttttttjtdfdd }|S)N)rVrfr`rarbr[rcsB|d||d||||||}|jjr:t|}||S)Nr"rc)rdrWr\r]r)rVrfr`rarbr[r7)rYrrr$s  z&_make_new_npgettext..npgettext)r r rr r0r^)rYr$r)rYr_make_new_npgettexts rhc seZdZdZdhZeddfdd Zd%deje ddd d Z d&eje dd d d Z d'ej e ge fej e e ege feje ejej e e ge fejej e e e ege fddddZdddddZefeje ejfeje ejejee ejeje ejeje dfffdddZdejejejejfdddZefe eje e dddZde ejeje e fdd d!Ze eje ej e ej!fejej!e e ej"d"d#d$Z#Z$S)(InternationalizationExtensionz-This extension adds gettext support to Jinja.ZtransN)r.rcs:t|t|jd<|j|j|j|j|j|j dddS)Nr%F)Zinstall_gettext_translationsZinstall_null_translationsZinstall_gettext_callablesZuninstall_gettext_translationsZextract_translationsnewstyle_gettext) superr/rXglobalsextend_install _install_null_install_callables _uninstall_extract)rr.)r4rrr/s  z&InternationalizationExtension.__init___SupportedTranslations) translationsnewstylercCsdt|dd}|dkr|j}t|dd}|dkr4|j}t|dd}t|dd}|j|||||ddS)NZugettextZ ungettextr#r$)rur#r$)getattrrrrp)rrtrurrr#r$rrrrns    z&InternationalizationExtension._install)rurcCsxddl}|}t|dr"|j}ntttddd}t|drF|j}ntttttddd }|j|j|j|||d dS) Nrr#)csrcSs|S)Nr)rwrxrrrr#*sz=InternationalizationExtension._install_null..pgettextr$)rwrxprrcSs|dkr |S|S)Nrr)rwrxryrrrrr$1sz>InternationalizationExtension._install_null..npgettext)rrrur#r$) rZNullTranslationshasattrr#rr$r rpr)rrurrtr#r$rrrro s  z+InternationalizationExtension._install_null)rrrur#r$rcCsb|dk r||j_|jjrHt|}t|}|dk r8t|}|dk rHt|}|jjj||||ddS)N)rrr#r$)r.rjr_rergrhrlr6)rrrrur#r$rrrrp<sz0InternationalizationExtension._install_callables)rtrcCs"xdD]}|jj|dqWdS)N)rrr#r$)r.rlpop)rrtkeyrrrrqTs z(InternationalizationExtension._uninstall.)r9gettext_functionsrcCs t|tr|j|}t||S)N) isinstancerr.rAextract_from_ast)rr9r}rrrrrXs  z&InternationalizationExtension._extractr)r?rcCst|jj}d}d}d}i}d}x|jjjdkr:|rD|jd|jdrRP|jd}|j|kr|jd|jd|jt d |jjjd krt|j| ||j<} n8|dkr|jd kr|jd k}q$nt |jd ||j<} |dkr$t | t jr*t dd }|||j<t t dd| }n| }|jdk}q$W|jdd} d} t} ||d\} }| r| | |dkrt | dd }| ddk}|jjdrDd} t|j|jjjdkr|jd}|j|kr|jd|jd|jt d ||j}|jdk}|jd||d\}} t|j| |n t|jx(| D] }||krTt |d ||<qTW| sd}n|dkr|d||dkr|jjd}|r||}| r|| } ||| ||t| |o| }|||dk r ||gS|SdS)zParse a translatable tag.FNZ block_endZcommaZcolonr:ztranslatable variable z defined twice.)excZassign)trimmedZ notrimmedrloadZ_transZstorercTrzname:pluralizezunknown variable z for pluralizationzpluralize without variableszext.i18n.trimmed)nextr=rBcurrenttypeexpectZskip_ifvaluefailrZparse_expressionrNamer~rIZAssignrM _parse_blockr6testr.policies_trim_whitespace _make_nodeboolZ set_lineno)rr?rBnum_called_num plural_exprZplural_expr_assignmentr[rtokenvarrZ have_plural referencedZsingular_namesrZ plural_namesr:noderrrrAcs                                   z#InternationalizationExtension.parse)string_ws_rercCs|d|S)N )substrip)rrrrrrrsz.InternationalizationExtension._trim_whitespace)r?allow_pluralizercCs g}g}x|jjjdkr<||jjjddt|jq |jjjdkrt|j|jdj}|||d|d|jdq |jjjd krt|j|jjd rPn|jjd r|rP| d | d q |jj r| dq t dq W|t |fS)z1Parse until the next block tag with a given name.data%z%%Zvariable_beginr:z%(z)sZ variable_endZ block_beginz name:endtranszname:pluralizez:a translatable section can have only one pluralize sectionz;control structures in translatable sections are not allowedzunclosed translation blockzinternal parser error) r=rrappendrreplacerrrrZeos RuntimeErrorr )rr?rrZbufr:rrrrs6      z*InternationalizationExtension._parse_block)rrr[rvars_referencedrrc Cs|jj}|s,|s,|dd}|r,|dd}|dkr\tdd}t|t|ggdd} n0tdd} t| t|t||ggdd} |rxf|D]*\} } |r| dkrq| j t | | qWn.t | } |rt | t dd |D} t| gS) z/Generates a useful node from the data provided.z%%rNrrrrccSs"g|]\}}tt||qSr)rZPairConst).0r|rrrr 7sz.)r.rjrrrrIritemsrFrrUZMarkSafeIfAutoescapeZModDictOutput) rrrr[rrrrurrrr|rrrrrs8       z(InternationalizationExtension._make_node)N)N)NNN)%rrrrKr,rr/r0rOrrnroCallablerr rprqr&rPrTemplateSequenceIteratorTuplerrrRrSrArPatternrrrrTrr __classcell__rr)r4rris2   Z<$s% ric@s(eZdZdZdhZdejdddZdS)ExprStmtExtensionzrAdds a `do` tag to Jinja that works like the print statement just that it doesn't print the return value. dor)r?rcCs"tjt|jjd}||_|S)N)rB)rExprStmtrr=rBZ parse_tupler)rr?rrrrrAFs zExprStmtExtension.parseN)rrrrKr,rrrArrrrr?src@s6eZdZdZddhZdejejej fdddZ dS) LoopControlExtensionz/Adds break and continue to the template engine.breakcontinuer)r?rcCs0t|j}|jdkr"tj|jdStj|jdS)Nr)rB)rr=rrBreakrBContinue)rr?rrrrrAQs  zLoopControlExtension.parseN) rrrrKr,r0rPrrrrArrrrrLsrcs$eZdZeddfdd ZZS) WithExtensionN)r.rcs t|tjdtdddS)NzZThe 'with' extension is deprecated and will be removed in Jinja 3.1. This is built in now.) stacklevel)rkr/warningswarnDeprecationWarning)rr.)r4rrr/Ys  zWithExtension.__init__)rrrrr/rrr)r4rrXsrcs$eZdZeddfdd ZZS)AutoEscapeExtensionN)r.rcs t|tjdtdddS)Nz`The 'autoescape' extension is deprecated and will be removed in Jinja 3.1. This is built in now.r)r)rkr/rrr)rr.)r4rrr/ds  zAutoEscapeExtension.__init__)rrrrr/rrr)r4rrcsrc@s8eZdZdZdhZdejdddZee ddd Z d S) DebugExtensionaA ``{% debug %}`` tag that dumps the available variables, filters, and tests. .. code-block:: html+jinja
{% debug %}
.. code-block:: text {'context': {'cycler': , ..., 'namespace': }, 'filters': ['abs', 'attr', 'batch', 'capitalize', 'center', 'count', 'd', ..., 'urlencode', 'urlize', 'wordcount', 'wordwrap', 'xmlattr'], 'tests': ['!=', '<', '<=', '==', '>', '>=', 'callable', 'defined', ..., 'odd', 'sameas', 'sequence', 'string', 'undefined', 'upper']} .. versionadded:: 2.11.0 debugr)r?rcCs8|jdj}t}|jd|g|d}tj|g|dS)Nz name:debug_render)rB)r=rrBrZContextReferencerJr)rr?rBr"resultrrrrAszDebugExtension.parse)r"rcCs8|t|jjt|jjd}tj|dddS)N)r"filterstestsrT)ZdepthZcompact)Zget_allsortedr.rkeysrpprintZpformat)rr"rrrrrszDebugExtension._renderN) rrrrKr,rrrAr rrrrrrrnsrT)astr} babel_stylerccs x|tjD]}t|jtjr|jj|kr0qg}x>|jD]4}t|tjrft|j t rf| |j q<| dq>> from jinja2 import Environment >>> env = Environment() >>> node = env.parse('{{ (_("foo"), _(), ngettext("foo", "bar", 42)) }}') >>> list(extract_from_ast(node)) [(1, '_', 'foo'), (1, '_', ()), (1, 'ngettext', ('foo', 'bar', None))] >>> list(extract_from_ast(node, babel_style=False)) [(1, '_', ('foo',)), (1, 'ngettext', ('foo', 'bar'))] For every string found this function yields a ``(lineno, function, message)`` tuple, where: * ``lineno`` is the number of the line on which the string was found, * ``function`` is the name of the ``gettext`` function used (if the string was extracted from embedded Python code), and * ``message`` is the string, or a tuple of strings for functions with multiple string arguments. This extraction function operates on the AST and is because of that unable to extract any comments. For comment support you have to use the babel extraction interface or extract comments yourself. Ncss|]}|dk r|VqdS)Nr)rxrrr sz#extract_from_ast..rr)Zfind_allrrIr~rrr:rErrrrrFrGrHtuplelenrB)rr}rrZstringsargr%outrrrrs.+         rc@sfeZdZdZejejeeefejeddddZ eej edddZ eej ed d d Z dS) _CommentFinderzHelper class to find comments in a token stream. Can only find comments for gettext calls forwards. Once the comment from line 4 is found, a comment for line 1 will not return a usable value. N)tokens comment_tagsrcCs||_||_d|_d|_dS)Nr)rroffset last_lineno)rrrrrrr/sz_CommentFinder.__init__)rrc Cs~zpxjt|j|j|D]R\}}}|dkry|dd\}}Wntk rTwYnX||jkr|gSqWgS||_XdS)N)commentZ linecommentr)reversedrrsplit ValueErrorrrstrip)rrr% token_typeZ token_valueprefixrrrrfind_backwardss z_CommentFinder.find_backwards)rBrcCsd|jr|j|krgSx>t|j|jdD]&\}\}}}||kr*||j|Sq*W|t|jS)N)rr enumeraterrrr)rrBidxZ token_linenor%rrr find_commentss $z_CommentFinder.find_comments) rrrrKr0rrr rr/rSrrrrrrrs r)fileobjkeywordsroptionsrccsi}x4|dddD]}|}|s*qd|t|<qWt|krJd|t<dtjttftttddd}||d d }t |d t j |d t j |d t j |dt j|dt j|dt j|dpt j|dpt j||dt j||dt jt j||dt jt|ddd}||dr*d |jd<||dryes1trueon)getrlower)rr|rrrrgetbool?szbabel_extract..getboolsilentTZblock_start_stringZblock_end_stringZvariable_start_stringZvariable_end_stringZcomment_start_stringZcomment_end_stringZline_statement_prefixZline_comment_prefixZ trim_blocksZ lstrip_blocksZkeep_trailing_newliner)Z cache_sizeZ auto_reloadrzext.i18n.trimmedrjencodingzutf-8)F)$rrrr rir0MappingrrrrZBLOCK_START_STRINGZBLOCK_END_STRINGZVARIABLE_START_STRINGZVARIABLE_END_STRINGZCOMMENT_START_STRINGZCOMMENT_END_STRINGZLINE_STATEMENT_PREFIXZLINE_COMMENT_PREFIXZ TRIM_BLOCKSZ LSTRIP_BLOCKSZNEWLINE_SEQUENCEZKEEP_TRAILING_NEWLINErrrjreaddecoderAlistZlexr<rrrr)rrrrrZextension_namerrr.r9rrfinderrBrYrrrr babel_extract sR%                r)JrKrretypingr0rZ markupsaferrrrr.r exceptionsrrZruntimer r r Zutilsr r Z TYPE_CHECKINGZtyping_extensionsZteZlexerrrr?rZProtocolrr!rPrsr&rrrLcompilerr'r^rXrr_r rergrhrirrrrrrrrrrOrrZBinaryIOrrSrZi18nrZ loopcontrolsZwith_r]rrrrrsx               m &*(K    *