gdSc@sdZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddlm Z ddl m Z m Z ddlmZddlZddlmZddlZddlZddlmZddlmZdd lmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$dd l%m&Z&m'Z'm(Z(m)Z)dd l*m+Z+ej,d Z-ej,d Z.dZ/dZ0d(dZ1d)dZ2de3fdYZ4id*ddZ5dZ6dZ7dZ8ej,dZ9dZ:de;fdYZ<dZ=dZ>de3fd YZ?d!Z@d"ZAd#ZBd$d%ZCd&e;fd'YZDdS(+s sphinx.util ~~~~~~~~~~~ Utility functions for Sphinx. :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. iN(tpath(topentBOM_UTF8(tdeque(t relative_path(t PycodeError(tbytes( tSEPtos_patht relative_urit ensuredirtwalktmtimes_of_filestmovefiletcopyfilet copytimest make_filenamet ustrftime(tnested_parse_with_titlestsplit_explicit_titletexplicit_title_retcaption_ref_re(t patfilters\s+s(?P.+)://.*cCs$tjtjd|d|dS(Nt/s..i(t posixpathtnormpathtjoin(t basedocnametdocname((ssphinx/util/__init__.pyt docname_join1scCs@|jtjjt}t|tr<tjd|}n|S(s+normalize path separater and unicode stringtNFC( treplacetosRtsepRt isinstancetunicodet unicodedatat normalize(tfilepathtnewpath((ssphinx/util/__init__.pytpath_stabilize6sc #s6tjtj|}t|d}xt|dtD]\}}||tfdD}tfd|D}x`|D]X}g|D]}||ds|^q}g|D]}||ds|^q}qWtfd|D(xt|D]\} } | VqWq;WdS(s}Get all file names in a directory, recursively. Exclude files and dirs matching some matcher in *exclude_matchers*. it followlinksc3s'|]}ttj|VqdS(N(R(RR(t.0tdn(t relativeroot(ssphinx/util/__init__.pys Jsc3s'|]}ttj|VqdS(N(R(RR(R*tfn(R,(ssphinx/util/__init__.pys Lsc3s|]\}}|VqdS(N((R*tit_(tdirs(ssphinx/util/__init__.pys RsN(RRtabspathtlenR tTruet enumeratetsorted( tdirnametexclude_matcherstdirlentroottfilestqdirstqfilestmatchertentryR.tfilename((R0R,ssphinx/util/__init__.pytget_matching_files>s"    )-ccsPd|}x?t||D].}tj||s8qn|t| VqWdS(sGet all file names (without suffix) matching a suffix in a directory, recursively. Exclude files and dirs matching a pattern in *exclude_patterns*. t*N(R@tfnmatchR2(R6tsuffixR7t suffixpatternR?((ssphinx/util/__init__.pytget_matching_docsXs  tFilenameUniqDictcBs;eZdZdZdZdZdZdZRS(s A dictionary that automatically generates unique names for its keys, interpreted as filenames, and keeps track of a set of docnames they appear in. Used for images and downloadable files in the environment. cCst|_dS(N(tsett _existing(tself((ssphinx/util/__init__.pyt__init__kscCs||kr-||dj|||dStj|}tj|\}}d}x0||jkr|d7}d|||f}qZWt|g|f||<|jj||S(Niis%s%s%s(taddRtbasenametsplitextRHRG(RIRtnewfilet uniquenametbasetextR.((ssphinx/util/__init__.pytadd_filens   cCsTxM|jD]?\}\}}|j||s ||=|jj|q q WdS(N(titemstdiscardRH(RIRR?tdocstunique((ssphinx/util/__init__.pyt purge_doc|s  cCs|jS(N(RH(RI((ssphinx/util/__init__.pyt __getstate__scCs ||_dS(N(RH(RItstate((ssphinx/util/__init__.pyt __setstate__s(t__name__t __module__t__doc__RJRRRWRXRZ(((ssphinx/util/__init__.pyRFes     ic Cs|rHttj|jd|}x!|D]}||r+dSq+Wntj|rtj|tj|}|jjdr|jrt |ddd} t |d ddd} | j |jj | j || j | j qt||ntj|rtj|s5tj|nxtj|D]} | jd r`qEn|} tjtj|| rtj|| } nttj|| | ||d |d d |qEWndS( sCopy a HTML builder static_path entry from source to targetdir. Handles all possible cases of files, directories and subdirectories. tdummyNt_ttrtencodingsutf-8itwt.tleveliR7(RRRtsrcdirtisfileRLtlowertendswitht templatesRtwritet render_stringtreadtcloseRtisdirR tmkdirtlistdirt startswithtcopy_static_entry( tsourcet targetdirtbuildertcontextR7RdtrelpathR=ttargettfsrctfdstR>t newtarget((ssphinx/util/__init__.pyRrs4   "  sn# Sphinx version: %s # Python version: %s # Docutils version: %s %s # Jinja2 version: %s # Loaded extensions: c Csddl}tj}tjdd\}}tj|ttj |j t j t j t j fjd|dk rxO|jjD];\}}tj|d|t|ddfjdqWntj||jdtj||S( s;Save the current exception's traceback in a temporary file.iNs.logs sphinx-err-sutf-8s# %s from %s t__file__tunknown(tplatformt tracebackt format_excttempfiletmkstempR Rjt _DEBUG_HEADERtsphinxt __version__tpython_versiontdocutilst__version_details__tjinja2tencodetNonet _extensionst iteritemstgetattrRm(tappR~texctfdRtextnametextmod((ssphinx/util/__init__.pytsave_tracebacks         cCs!|tjkrIyt|WqItk rE}td||qIXntj|}t|dd}t|dd}|rt|ddry|j|}Wqtk r}td||qXn|dkr&|r&yd|j|fSWq&tk r"}td||q&Xn|dkrEtd|nt j t j |}|j }|j d s|j d r|d }t j| rt j|d r|d 7}qn1|j d p|j dstd|nt j|std|nd|fS(sTry to find the source code for a module. Can return ('file', 'filename') in which case the source is in the given file, or ('string', 'source') which which case the source is the string. serror importing %rR|t __loader__t get_filenameserror getting filename for %rtstringserror getting source for %rsno source found for module %rs.pyos.pyciRbs.pys.pywssource is not a .py file: %rssource file is not present: %rtfileN(tsystmodulest __import__t ExceptionRRRRt get_sourceRRR1RgRhRf(tmodnameterrtmodR?tloadert lfilename((ssphinx/util/__init__.pytget_module_sources>    #scoding[:=]\s*([-\w.]+)csfd}dfd}tj}|}|rd|jtrd|d}d}n|sn|S||}|r|S|}|s|S||}|r|S|S(s@Like tokenize.detect_encoding() from Py3k, but a bit simplified.cs$y SWntk rdSXdS(N(t StopIterationR((treadline(ssphinx/util/__init__.pyt read_or_stops  cSs^|d jjdd}|dks7|jdr;dS|d ksV|jd rZdS|S(s(Imitates get_normal_name in tokenizer.c.i R/t-sutf-8sutf-8-slatin-1s iso-8859-1s iso-latin-1slatin-1-s iso-8859-1-s iso-latin-1-(slatin-1s iso-8859-1s iso-latin-1(slatin-1-s iso-8859-1-s iso-latin-1-(RgRRq(torig_enctenc((ssphinx/util/__init__.pytget_normal_names csOy|jd}Wntk r'dSXtj|}|sAdS|dS(Ntasciii(tdecodetUnicodeDecodeErrorRt _coding_retfindall(tlinet line_stringtmatches(R(ssphinx/util/__init__.pyt find_cookies is utf-8-sig(RtgetdefaultencodingRqR(RRRtdefaulttfirstRatsecond((RRssphinx/util/__init__.pytdetect_encodings(        tTeecBs)eZdZdZdZdZRS(s2 File-like object writing to two streams. cCs||_||_dS(N(tstream1tstream2(RIRR((ssphinx/util/__init__.pyRJ,s cCs$|jj||jj|dS(N(RRjR(RIttext((ssphinx/util/__init__.pyRj0scCsHt|jdr"|jjnt|jdrD|jjndS(Ntflush(thasattrRRR(RI((ssphinx/util/__init__.pyR4s(R[R\R]RJRjR(((ssphinx/util/__init__.pyR(s  cCst}|jd}x|D]}y|jjd}t|dkrXtnt|dkr|jt|ddnf|ddkrdpt|dd}|ddkr|pt|d}|jt||Wqt k rtd|qXqW|S(s_Parse a line number spec (such as "1,2,4-6") and return a list of wanted line numbers. t,Riiitsinvalid line number spec: %r( tlisttsplittstripR2t ValueErrortappendtinttextendtxrangeR(tspecttotalRStpartstparttbegendtstarttend((ssphinx/util/__init__.pyt parselinenos;s   *& cCsdt|tr`y+|r*|j|}n|jd}Wq`tk r\|jd}q`Xn|S(s2Forcibly get a unicode string out of a bytestring.sutf-8tlatin1(R"RRt UnicodeError(RRa((ssphinx/util/__init__.pyt force_decodeQs tattrdictcBs#eZdZdZdZRS(cCs||S(N((RItkey((ssphinx/util/__init__.pyt __getattr__ascCs|||sst;icss|]}|rdVqdS(iN((R*R((ssphinx/util/__init__.pys tssinvalid %s index entry %r(tmapRtsumR(tnttypetvalueR((ssphinx/util/__init__.pyt split_intoqs"cCsg}y|dkrTytdd|}Wqtk rPtdd|}qXn|dkrutdd|}nc|dkrtdd|}nB|dkrtdd|}n!|dkrtdd|}nWntk rnX|S( Ntsingleiitpairttripleitseetseealso(RR(RRtresult((ssphinx/util/__init__.pytsplit_index_msgys$       icCs\tj\}}}g}tj|}||| 7}|tj||7}dj|S(s?Format an exception with traceback, but only the last x frames.R(Rtexc_infoRt format_tbtformat_exception_onlyR(RttypRttbtresttbres((ssphinx/util/__init__.pytformat_exception_cut_framess tPeekableIteratorcBs;eZdZdZdZdZdZdZRS(sm An iterator which wraps any iterable and makes it possible to peek to see what's the next item. cCst|_t||_dS(N(Rt remainingtitert _iterator(RItiterable((ssphinx/util/__init__.pyRJs cCs|S(N((RI((ssphinx/util/__init__.pyt__iter__scCs#|jr|jjS|jjS(s'Return the next item from the iterator.(RtpopleftRtnext(RI((ssphinx/util/__init__.pyRs  cCs|jj|dS(sjPush the `item` on the internal stack, it will be returned on the next :meth:`next` call. N(RR(RItitem((ssphinx/util/__init__.pytpushscCs|j}|j||S(s@Return the next item without changing the state of the iterator.(RR(RIR((ssphinx/util/__init__.pytpeeks  (R[R\R]RJRRRR(((ssphinx/util/__init__.pyRs     ((((ER]R treRtshutilRBRRRR$RtcodecsRRt collectionsRRtdocutils.utilsRRRt sphinx.errorsRtsphinx.util.pycompatRtsphinx.util.osutilRRR R R R R RRRRtsphinx.util.nodesRRRRtsphinx.util.matchingRtcompiletws_returl_reRR(R@REtdictRFRrRRRRRtobjectRRRRRRRRR(((ssphinx/util/__init__.pyt sX            L"    %)  ( 4