+
     hLO  c                   sx   R t . ROt^ RIt^ RIt^ RIt^ RIHt ]t ! R R4      tR R lt	RR.]	n         ! R	 R
]4      t
 ! R R]4      t ! R R]4      tR tR t. R!O]n         ! R R]4      t ! R R4      t ! R R]4      t ! R R]4      t ! R R]4      t ! R R]4      t ! R R]4      t ! R R]4      tR# )"ah  

enchant.tokenize:    String tokenization functions for PyEnchant
================================================================

An important task in spellchecking is breaking up large bodies of
text into their constituent words, each of which is then checked
for correctness.  This package provides Python functions to split
strings into words according to the rules of a particular language.

Each tokenization function accepts a string as its only positional
argument, and returns an iterator that yields tuples of the following
form, one for each word found::

    (<word>,<pos>)

The meanings of these fields should be clear: <word> is the word
that was found and <pos> is the position within the text at which
the word began (zero indexed, of course).  The function will work
on any string-like object that supports array-slicing; in particular
character-array objects from the 'array' module may be used.

The iterator also provides the attribute 'offset' which gives the current
position of the tokenizer inside the string being split, and the method
'set_offset' for manually adjusting this position.  This can be used for
example if the string's contents have changed during the tokenization
process.

To obtain an appropriate tokenization function for the language
identified by <tag>, use the function 'get_tokenizer(tag)'::

    tknzr = get_tokenizer("en_US")
    for (word,pos) in tknzr("text to be tokenized goes here")
        do_something(word)

This library is designed to be easily extendible by third-party
authors.  To register a tokenization function for the language
<tag>, implement it as the function 'tokenize' within the
module enchant.tokenize.<tag>.  The 'get_tokenizer' function
will automatically detect it.  Note that the underscore must be
used as the tag component separator in this case, in order to
form a valid python module name. (e.g. "en_US" rather than "en-US")

Currently, a tokenizer has only been implemented for the English
language.  Based on the author's limited experience, this should
be at least partially suitable for other languages.

This module also provides various implementations of "Chunkers" and
"Filters".  These classes are designed to make it easy to work with
text in a variety of common formats, by detecting and excluding parts
of the text that don't need to be checked.

A Chunker is a class designed to break a body of text into large chunks
of checkable content; for example the HTMLChunker class extracts the
text content from all HTML tags but excludes the tags themselves.
A Filter is a class designed to skip individual words during the checking
process; for example the URLFilter class skips over any words that
have the format of a URL.

For example, to spellcheck an HTML document it is necessary to split the
text into chunks based on HTML tags, and to filter out common word forms
such as URLs and WikiWords.  This would look something like the following::

    tknzr = get_tokenizer("en_US",(HTMLChunker,),(URLFilter,WikiWordFilter)))

    text = "<html><body>the url is http://example.com</body></html>"
    for (word,pos) in tknzer(text):
        ...check each word and react accordingly...

	URLFilterWikiWordFilterN)TokenizerNotFoundErrorc                   sj   a  ] tR t^{t o RtR.tR tR tR tR t	RR lt
R tR	 t]! ]]4      tR
tV tR# )tokenizeaK  Base class for all tokenizer objects.

Each tokenizer must be an iterator and provide the 'offset'
attribute as described in the documentation for this module.

While tokenizers are in fact classes, they should be treated
like functions, and so are named using lower_case rather than
the CamelCase more traditional of class names.
Z	CamelCasec                s     Wn         ^ V n        R# )i    N)_text_offset)selftext   &&>/usr/lib/python3.14/site-packages/enchant/tokenize/__init__.py__init__Ztokenize.__init__   s    
    c                "    V P                  4       # Nnextr      &r	   __next__Ztokenize.__next__   s    yy{r   c                    \        4       hr   )ZNotImplementedErrorr   r   r	   r   Ztokenize.next   s    !##r   c                    V # r    r   r   r	   __iter__Ztokenize.__iter__   s    r   c                s    Wn         R # r   r   )r   offsetreplaced   &&&r	   
set_offsetZtokenize.set_offset   s    r   c                s    V P                   # r   r   r   r   r	   _get_offsetZtokenize._get_offset   s    ||r   c                f    R p\         P                  ! V\        ^R7       V P                  V4       R# zSchanging a tokenizers 'offset' attribute is deprecated; use the 'set_offset' methodZcategoryZ
stacklevelNwarningswarnDeprecationWarningr   r   r   msg   && r	   _set_offsetZtokenize._set_offset   s+    + 	 	c$61Er   )r   r   NF)__name__
__module____qualname____firstlineno____doc___DOC_ERRORSr
   r   r   r   r   r   r'   propertyr   __static_attributes____classdictcell____classdict__   @r	   r   r   {   sD      -K$  k;/Fr   r   c                sz   V f   Rp Ve[   VfW   \        V4      pV'       dD    \        V^ ,          \        4      pV'       d$   Rp\        P                  ! V\
        ^R7       TpRpV P                  RR4      p \        V 4      pVf:   V P                  R4      ^ ,          p\        V4      pVf   RV : R2p\        V4      h\        pVeB   \        V4      p\        \        V4      ^,
          R	R	4       F  p\        W,          V4      pK  	  Ve   V F  p	V	! V4      pK  	  \        Wu4      pV#   \         d     Li ; i)
a  Locate an appropriate tokenizer by language tag.

This requires importing the function 'tokenize' from an appropriate
module.  Modules tried are named after the language tag, tried in the
following order:

    * the entire tag (e.g. "en_AU.py")
    * the base country code of the tag (e.g. "en.py")

If the language tag is None, a default tokenizer (actually the English
one) is returned.  It's unicode aware and should work OK for most
latin-derived languages.

If a suitable function cannot be found, raises TokenizerNotFoundError.

If given and not None, 'chunkers' and 'filters' must be lists of chunker
classes and filter classes respectively.  These will be applied to the
tokenizer during creation.
NZenzLpassing 'filters' as a non-keyword argument to get_tokenizer() is deprecatedr   Z-Z_z!No tokenizer found for language 'Z'i)ZlistZ
issubclassFilterr!   r"   r#   Z	TypeErrorZreplace_try_tokenizersplitr   basic_tokenizeZrangelenwrap_tokenizer)
ZtagZchunkersZfiltersZchunkers_are_filtersr%   Ztk_funcZbase	tokenizerZiZfs
   &&&       r	   get_tokenizerr<      s9   ( { >$'1(1+v'F$ (;  MM#0BqQ&G#H
++c3
CS!Gyy~a  &?<?AC(-- I>s8}q("b1A&x{I>I 2A)I y2IK  s   D, ,D:9D:Zpyc                   s@   a a ] tR t^t oRt. tV 3R ltR tRtVt	V ;t
# )empty_tokenizez(Tokenizer class that yields no elements.c                s&   < \         SV `  R 4       R#  N)superr
   )r   	__class__s   &r	   r
   Zempty_tokenize.__init__   s    r   c                r   r   )StopIterationr   r   r	   r   Zempty_tokenize.next   s
    or   r   r)   r*   r+   r,   r-   r.   r
   r   r0   r1   Z__classcell__rA   r3      @@r	   r=   r=      s     2K r   r=   c                   s@   a a ] tR t^t oRt. tV 3R ltR tRtVt	V ;t
# )unit_tokenizez7Tokenizer class that yields the text as a single token.c                s4   < \         SV `  V4       R V n        R# )FN)r@   r
   _done)r   r   rA   s   &&r	   r
   Zunit_tokenize.__init__   s    
r   c                sd    V P                   '       d   \        4       hR V n         V P                  ^ 3# T)rG   rB   r   r   r   r	   r   Zunit_tokenize.next  s(    :::/!


Ar   )rG   rC   rD   rE   r	   rF   rF      s     AK r   rF   c                   s6   a  ] tR tRt o Rt. tRtRtR tRt	V t
R# )r8   i
  zTokenizer class that performs very basic word-finding.

This tokenizer does the most basic thing that could work - it splits
text into words based on whitespace boundaries, and removes basic
punctuation symbols from the start and end of each word.
c                s:   V P                   pV P                  p V\        V4      8  d    \        4       hV\        V4      8  d(   W,          P                  4       '       d   V^,          pK7  TpV\        V4      8  d(   W,          P                  4       '       g   V^,          pK7  TpW n        V\        V4      8  d#   W,          V P                  9   d   V^,          pK2  ^ V8  d*   W^,
          ,          V P
                  9   d   V^,          pK0  W48  g   K  WV V3# rH   )r   r   r9   Zisspacestrip_from_startstrip_from_endrB   )r   r   r   s_posZe_pos   &    r	   r   Zbasic_tokenize.next  s    zzT"$ o! 3t9$)=)=)?)?!E3t9$T\-A-A-C-C!E!L#d)#t7L7L(L
e)QY43F3F F
}5)511r   r   Nz"'`([z"'`]).!,?;:)r)   r*   r+   r,   r-   r.   rI   rJ   r   r0   r1   r2   r4   r	   r8   r8   
  s(      K $'N r   r8   c                s    RpRpW,           p  \        V \        4       / V4      p\        W24      #   \         d     R# i ; i)zZLook for a tokenizer in the named module.

Returns the function if found, None otherwise.
zenchant.tokenize.r   N)Z
__import__ZglobalsZgetattrZImportError)Zmod_nameZmod_baseZ	func_nameZmods   &   r	   r6   r6   2  sJ    
 #HI"H79b)<s&& s    / >>c                s(    \        V 4      pWn        V# )zWrap one tokenizer inside another.

This function takes two tokenizer functions 'tk1' and 'tk2',
and returns a new tokenizer function that passes the output
of tk1 through tk2 before yielding it to the calling code.
)r5   _split)Ztk1Ztk2Ztkwr&   r	   r:   r:   A  s     +CJJr   c                   s    ] tR tRtRtRtR# )ChunkeriS  zBase class for text chunking functions.

A chunker is designed to chunk text into large blocks of tokens.  It
has the same interface as a tokenizer but is for a different purpose.
r   N)r)   r*   r+   r,   r-   r0   r   r   r	   rN   rN   S  s     	r   rN   c                   sP   a  ] tR tRt o RtR tR tR tR t ! R R4      t	R	t
V tR
# )r5   i]  a  Base class for token filtering functions.

A filter is designed to wrap a tokenizer (or another filter) and do
two things:

  * skip over tokens
  * split tokens into sub-tokens

Subclasses have two basic options for customising their behaviour.  The
method _skip(word) may be overridden to return True for words that
should be skipped, and false otherwise.  The method _split(word) may
be overridden as tokenization function that will be applied to further
tokenize any words that aren't skipped.
c                s    Wn         R# )zFilter class constructor.N
_tokenizer)r   r;   r   r	   r
   ZFilter.__init__m  s    #r   c                sr    V P                   ! V/ VB pV P                  W0P                  V P                  4      # r   )rP   _TokenFilter_skiprM   )r   ZargsZkwdsZtkns   &*, r	   __call__ZFilter.__call__q  s0    oot,t,  jj$++>>r   c                s    R# )zFilter method for identifying skippable tokens.

If this method returns true, the given word will be skipped by
the filter.  This should be overridden in subclasses to produce the
desired functionality.  The default behaviour is not to skip any words.
Fr   r   wordr   r	   rR   ZFilter._skipu  s     r   c                s    \        V4      # )zFilter method for sub-tokenization of tokens.

This method must be a tokenization function that will split the
given word into sub-tokens according to the needs of the filter.
The default behaviour is not to split any words.
)rF   rT   r   r	   rM   ZFilter._split~  s     T""r   c                   sp   a  ] tR tRt o RtR.tR tR tR tR t	R t
R	 tR
 t]! ]]4      tRR ltRtV tR# )Filter._TokenFilteri  a  Private inner class implementing the tokenizer-wrapping logic.

This might seem convoluted, but we're trying to create something
akin to a meta-class - when Filter(tknzr) is called it must return
a *callable* that can then be applied to a particular string to
perform the tokenization.  Since we need to manage a lot of state
during tokenization, returning a class is the best option.
tknzrc                sd    W n         W0n        Wn        \        4       V n        R V n        ^ V n        R# r>   )rR   rM   rP   r=   _curtok_curword_curpos)r   r;   Zskipr7   s   &&&&r	   r
   ZFilter._TokenFilter.__init__  s)    JK'O)+DLDMDLr   c                r   r   r   r   r   r	   r   ZFilter._TokenFilter.__iter__  s    Kr   c                r   r   r   r   r   r	   r   ZFilter._TokenFilter.__next__  s    99;r   c                sp     \        V P                  4      w  rWV P                  ,           3#   \         d}    \        T P                  4      w  rT P                  T P                  T4      4      '       d   \        T P                  4      w  rK?  Yn        Y n        T P                  T4      T n         K  i ; irH   )	r   rX   rZ   rB   rP   rR   
_to_stringrY   rM   )r   rU   poss   &  r	   r   ZFilter._TokenFilter.next  s     	5"&t||"4KT "455$ 5"&t"7KT**T__T%:;;&*4??&;s$(M#&L#';;t#4DL5s   *. AB56;B54B5c                s    \        V4      \        P                  J dC   VP                  R 8X  d   VP                  4       # VP                  R8X  d   VP	                  4       # V# )ZuZc)ZtypearrayZtypecodeZ	tounicodeZtostringrT   r   r	   r[   ZFilter._TokenFilter._to_string  sH    DzU[[(==C'>>++]]c)==?*Kr   c                s.    V P                   P                  # r   )rP   r   r   r   r	   r   ZFilter._TokenFilter._get_offset  s    ??)))r   c                r   r   r    r$   r&   r	   r'   ZFilter._TokenFilter._set_offset  s+    /  MM#(:qIOOF#r   c                s   V P                   P                  pV P                   P                  WR 7       RpWP                  ,
          pW18  d   RpV^ 8  d   RpV\	        V P
                  4      8  d   RpV'       d&   V'       g   V P                  P                  V4       R# \        4       V n        RV n        ^ V n        R# ))r   TFr?   N)rP   r   r   rZ   r9   rY   rX   r=   )r   Zvalr   Z
old_offsetZkeep_curtokZcurtok_offsets   &&&   r	   r   ZFilter._TokenFilter.set_offset  s    //JOO&&s&> K,,.M#q #DMM 22#8''6-/ " r   )rZ   rX   rY   rR   rM   rP   Nr(   )r)   r*   r+   r,   r-   r.   r
   r   r   r   r[   r   r'   r/   r   r   r0   r1   r2   r4   r	   rQ   rV     sN     	 i				5		*	$ +{3	! 	!r   rQ   rO   N)r)   r*   r+   r,   r-   r
   rS   rR   rM   rQ   r0   r1   r2   r4   r	   r5   r5   ]  s*     $?#R! R!r   r5   c                   T   a  ] tR tRt o RtR.t]P                  ! R4      tR t	Rt
V tR# )r    i  zFilter skipping over URLs.
This filter skips any words matching the following regular expression:

       ^[a-zA-Z]+:\/\/[^\s].*

That is, any words that are URLs.
zAz^[a-zA-Z]+:\/\/[^\s].*c                L    V P                   P                  V4      '       d   R # R# TF_patternZmatchrT   r   r	   rR   ZURLFilter._skip      ==t$$r   r   Nr)   r*   r+   r,   r-   r.   recompilerc   rR   r0   r1   r2   r4   r	   r    r      s,      &Kzz34H r   c                   N   a  ] tR tRt o Rt]P                  ! R4      tR tRt	V t
R# )r   i  zFilter skipping over WikiWords.
This filter skips any words matching the following regular expression:

       ^([A-Z]\w+[A-Z]+\w+)

That is, any words that are WikiWords.
z^([A-Z]\w+[A-Z]+\w+)c                r`   ra   rb   rT   r   r	   rR   ZWikiWordFilter._skip  rd   r   r   Nr)   r*   r+   r,   r-   rf   rg   rc   rR   r0   r1   r2   r4   r	   r   r     s%      zz12H r   c                   rh   )EmailFilteri   zFilter skipping over email addresses.
This filter skips any words matching the following regular expression:

       ^.+@[^\.].*\.[a-z]{2,}$

That is, any words that resemble email addresses.
z^.+@[^\.].*\.[a-z]{2,}$c                r`   ra   rb   rT   r   r	   rR   ZEmailFilter._skip
  rd   r   r   Nri   r2   r4   r	   rj   rj      s%      zz45H r   rj   c                   r^   )MentionFilteri  zFilter skipping over @mention.
This filter skips any words matching the following regular expression:

       (\A|\s)@(\w+)

That is, any words that are @mention.
r_   z(\A|\s)@(\w+)c                r`   ra   rb   rT   r   r	   rR   ZMentionFilter._skip  rd   r   r   Nre   r2   r4   r	   rk   rk     ,      &Kzz*+H r   rk   c                   r^   )HashtagFilteri!  zFilter skipping over #hashtag.
This filter skips any words matching the following regular expression:

       (\A|\s)#(\w+)

That is, any words that are #hashtag.
r_   z(\A|\s)#(\w+)c                r`   ra   rb   rT   r   r	   rR   ZHashtagFilter._skip,  rd   r   r   Nre   r2   r4   r	   rm   rm   !  rl   r   rm   c                   s0   a  ] tR tRt o RtR tR tRtV tR# )HTMLChunkeri2  zChunker for breaking up HTML documents into chunks of checkable text.

The operation of this chunker is very simple - anything between a "<"
and a ">" will be ignored.  Later versions may improve the algorithm
slightly.
c                s   V P                   pV P                  p V\        V4      8  d    \        4       hW,          R8X  d_   TpV P                  W4      '       d=   W,          R8w  d&   V^,          pV\        V4      8X  g   K(  V^,           pMV^,          pM	V^,           pTpV\        V4      8  d   W,          R8w  d   V^,          pK(  W n        WB8  g   K  WV V3# )TZ<Z>)r   r   r9   _is_tagr   rB   )r   r   r   Z	maybe_tagrK   rL   r	   r   ZHTMLChunker.next:  s    zzT", o) |s""	<<--,#-!!SY.%.]F!!&]FE3t9$)<!!L~6*E22r   c                s    V^,           \        V4      8  d<   W^,           ,          P                  4       '       d   R# W^,           ,          R8X  d   R# R# )i   TZ/F)r9   Zisalpha)r   r   r   r   r	   ro   ZHTMLChunker._is_tagW  s@    A:D	!QJ''))QJ3&r   r   N)	r)   r*   r+   r,   r-   r   ro   r0   r1   r2   r4   r	   rn   rn   2  s     : r   rn   )	r\   r\   rW   r    r   tknsrW   r\   rp   )NNN)tkrq   rq   rq   )r-   r.   rf   r!   r]   Zenchant.errorsr   ZErrorr   r<   r=   rF   r8   r6   r:   rN   r5   r    r   rj   rk   rm   rn   r   r   r	   <module>rr      s   <EL
 
   1 	(0 (0VBJ "4L 	X 	H  %X %P 6 	h 	|! |!D "V  &  F "F "+' +r   