
    CPc3                         d Z ddlZddlmZmZ ddlZddlmZmZm	Z	m
Z
mZmZ ddlmZ ddlmZ eeef         Z G d dej                  Zed	k    r e                                             dS dS )
a  Splits a text element into lines, words, chars.
Supports all text elements that Inkscape can create, such as normal text, shape-inside (SVG2),
flowroot (SVG1.2), inline-size, manual kerns, and nested tspans (with possibly different kerns)

The code is structured as followed. For each selected text element:
 - preprocess_text_element duplicates the element, converts flowroots to plain text elements,
   and simplifies manual kerning if requested (only for split_words and split_chars, for all,
   possibly nested, children) using simplify_nested_tspans.
 - if split lines: split_lines copies all top-level tspans from the previous step into their own
   text element, which is otherwise a duplicate of the original text element (thus preserving
   style and transforms), see append_splitted_element
 - if split words or chars: split_words_or_chars: the text is recursively processed. For each tspan,
   the content and tail is split (words: at spaces, chars: after each character) into their own
   tspan, again using append_splitted_element. The method keeps track of the horizontal and vertical
   coordinate, incrementing it with the number of characters and a multiple of font size.
    N)UnionCallable)TextElementFlowRootFlowParaTspan	RectangleShapeElement)
parse_unit)inkex_gettextc                        e Zd ZdZ fdZd Zd Zed             Zede	fd            Z
defdZdefd	ZddZdedefdZd Zd Zd ZdedefdZ xZS )	TextSplitzSplit text up.c                     t                                                       |  d| _        d| _        d| _        d| _        d| _        |  d| _        dS )zInitialize State machine         ?r   TN)super__init__
separationfs_multiplier	current_x	current_yprocess_kernscurrent_fontsize)self	__class__s    ,/usr/share/inkscape/extensions/text_split.pyr   zTextSplit.__init__4   sX    !"$( ! !#'#'(    c                     |                     dd           |                     dddg dd	           |                     d
dt          j        dd           |                     ddt          dd           d S )Nz--tabz'The selected UI tab when OK was pressed)helpz-tz--splittypeline)letterwordr    ztype of split)defaultchoicesr   z-pz
--preserveTzPreserve original)typer#   r   z-sz--separationr   zHThreshold for separating text with manual kerns in multiples offont-size)add_argumentinkexBooleanfloat)r   parss     r   add_argumentszTextSplit.add_arguments@   s    '(QRRR...  	 	
 	
 	
 	$ 	 	
 	
 	
 	 	 	
 	
 	
 	
 	
r   c                    | j         j        }| j         j        }| j        j                            t          t                    D ]}	 | j         j        | _        |dk    r| 	                    |          }nP|dk    r"| j
        | _        |                     |          }n(d| _        | j        | _        |                     |          }|                                                    |           |s)|'|                                                    |           # t           $ r}t#          j        |           Y d}~d}~ww xY wdS )zApplies the effectr    r"   r   N)options	splittypepreservesvg	selectionfilter_nonzeror   r   r   split_linesprocess_plain_wordsmodesplit_words_or_charsprocess_plain_chars	getparentremove	TypeErrorr'   errormsg)r   
split_typer/   elemnodeerrs         r   effectzTextSplit.effectY   sO    \+
<( H&55k8LL 	$ 	$D$"&,"9''++D11DD6)) $ 8DI44T::DD&'DO $ 8DI44T::D  ''--- 2D$4NN$$++D111 $ $ $s########$#	$ 	$s   CD
D> D99D>c                 <     |                                  d          S )zget the font size of an elementz	font-size)specified_styleelements    r   get_font_sizezTextSplit.get_font_sizet   s      )w&&((555r   rD   c                 *    |                                  S )z!get the line height of an element)get_line_height_uurC   s    r   get_line_heightzTextSplit.get_line_heighty   s     ))+++r   c                    t          |          D ]}t          |t                    st          t          t          t          t          t          j        d|	                    d          pd                                        }|j
        }|dvrHt          |          dk    r4|                     |          }| j        |z  }d}t          dt          t          |          t          |                              D ]}|t          |          dz
  k    s|t          |          dz
  k    rt          |          }|t          |          k    s%t          ||         ||dz
           z
            |k    rIt          t!          ||                             }	|||         |	_
        |                    |	           |}|                    d           d	|_
        |                     |           d	S )
zChecks all child tspans if they have manual kerns.
        If it does, try to find words (characters with a distance > separation * font-size).
        Then concatenate the words with spaces, set this string as a new text andz[,\s]x )NrK      r   r   )rJ   N)list
isinstancer   mapr)   filterlenregexsplitgettextrE   r   rangemaxabsstraddpopsimplify_child_tspans)
r   rD   childxvalscontentfsizer   current_word_startiwordspans
             r   r\   zTextSplit.simplify_child_tspans~   s    ']] 	. 	.EeU++ E6#u{8UYYs^^=Qr'R'RSSTT E jGj((SZZ1__**511!_u4
%&"q#c'llCJJ"?"?@@ / /ACLL1,,,SZZ!^0C0CLLCLL((Ca5Q<0G,H,H:,U,U#(3u5G/H+I+I#J#J#J(/0B10D(E		(+++-.*		#!
&&u----1	. 	.r   c                 N   |}t          |t                    rt                      }|                    |           |j        |_        |j        |_        |                    d          d         }t          |t                    r`|                    |	                    d                    }|                    t          |	                    d                              }d}nAt          t          d                              |                                                    |D ]}t          |t                    rt!                      }|                    |           |j        |_        |j        |_        |j        |_        |                    d|           |r||                     |          dz  z  }d}n||                     |          z  }|                    dt-          |                     n;|                                }|                                                    |           |j                            d	d
           |j                            dd
           |D ]}|j                            dd
           | j        r|                     |           |S )aY  Processes a text element and returns an element containing tspans with x and y coordinate,
        possibly nested (for Inkscape-type kerning), so that the actual splitting can work as if the
        text was a simple text. Manual kerns (one x value per letter) are converted to spaces
        if requested (not necessary for "split characters")zsvg:flowRegionr   rJ   yTzIElement {} uses a flow region that is not a rectangle. First unflow text.g      ?Fzshape-insideN	direction)rN   r   r   addnextstyle	transformfindoner	   unittouurT   r)   r:   _formatget_idr   r   appendrU   setrE   rH   rY   	duplicater8   r[   r   r\   )	r   rD   
oldelementflowrefflowxflowyfirstr]   newchilds	            r   preprocess_text_elementz!TextSplit.preprocess_text_element   s    
gx(( %	3!mmGw'''&,GM * 4G (()9::1=G'9-- 
((S)9)9::((w{{3/?/?)@)@AA-  fW^^--..	   $ 2 2eX.. 2  %wwHNN8,,,$)JHM%*[HN).H&LLe,,, =!3!3E!:!:T!AA %!5!5e!<!<<LLc%jj111!2& !**,,G  ""))'222.$/// 	+t,,, 	/ 	/EKOOK.... 	0&&w///r   Nc                    t          |t                    r|                                | j        k    r| j                                        }|                    t                     |                    |           |                    d|                    d                     |                    d|                    d                     nt          t          | j                  t          | j                            }|                                |_        | j                                        j         |                                z  |_        t          t          | j                  t          | j                            }||_        |                    |           | j                            |           dS )ae  Creates a new text element, sibling to self.current_root, at (self.current_x,
        self.current_y) with content text.

        text: either a Tspan that should be moved to a new text element - in this case, text is
            a direct child of element; or a string
        prototype: if text is a string, style and transform will be taken from prototyperJ   re   )rJ   re   N)rN   r   r8   current_rootrq   
remove_allro   rp   rT   r   rY   r   r   rB   rh   ri   composed_transformrU   rZ   rg   )r   rU   	prototyper=   tsps        r   append_splitted_elementz!TextSplit.append_splitted_element   sl    dE"" 	t~~'7'74;L'L'L$..00DOOE"""KKHHS$((3--(((HHS$((3--((((T^!4!4DN8K8KLLLD #2244DJ
 ",,..88,,../DN #dn--T^1D1DEEECCHHHSMMM!!$'''''r   returnc                     d| _         |                     |          }|| _        t          |          D ]}|                     |           |S )Splits a text into its linesF)r   rx   rz   rM   r   )r   rD   preprocessedr]   s       r   r3   zTextSplit.split_lines   sY    "33G<<(,'' 	0 	0E((////r   c                     |dS |D ]N}|dk    r|                      ||           | xj        | j        t          |          dz   z  | j        z  z  c_        OdS )zAppends new text elements to as sibling root for each element of splitted, starting at
        self.current_x, self.current_y, incrementing those, with prototype element (that
        styles and transforms will be taken from)NrK   r   )r   r   r   rQ   r   )r   rD   splittedr"   s       r   process_plain_textzTextSplit.process_plain_text  sv     F 	 	Drzz,,T7;;;NN%TQ7$:LLNNN		 	r   c                 n    d| _         |+|                     ||                    d                     dS dS )z,Calls process_plain_text for splitting wordsg?N )r   r   rS   r   rD   rU   s      r   r4   zTextSplit.process_plain_words  s>     ##GTZZ__===== r   c                 @    d| _         |                     ||           dS )z1Calls process_plain_text for splitting charactersr   N)r   r   r   s      r   r7   zTextSplit.process_plain_chars  s&    !.....r   c                      d _                              |          }dt          f fd| _         |           |S )r   Tr   c                 d     fddD             }|d         |d         _         |d         |d         _                                       _                              j                  } D ]=}t          |t                    r |          }                     |j                  }>|S )Nc                     i | ]G}|                     |          -j                                                 |                    nd HS N)rT   rootrk   ).0rb   rD   s     r   
<dictcomp>zKTextSplit.split_words_or_chars.<locals>.process_element.<locals>.<dictcomp>   s`         ;;q>>- <((Q888  r   xyrJ   re   )	r   r   rE   r   r5   rU   rN   r   tail)rD   elem_coordsr   r=   process_elementr   s   `   r   r   z7TextSplit.split_words_or_chars.<locals>.process_element  s        	  K 3+!,S!13+!,S!1$($6$6w$?$?D!		'7<88I : :dE** 6 / 5 5I IIgty99		r   )r   rx   r)   rz   )r   rD   r   r   s   `  @r   r6   zTextSplit.split_words_or_chars  si    !33G<<	 	 	 	 	 	 	 	( )%%%r   r   )__name__
__module____qualname____doc__r   r+   r@   staticmethodrE   r
   rH   r   r\   rx   r   TextLiker3   r   r4   r7   r6   __classcell__)r   s   @r   r   r   1   s[       
) 
) 
) 
) 
)
 
 
2$ $ $6 6 6 \6 , , , , \,.[ . . . .<8{ 8 8 8 8t( ( ( (@	8 	 	 	 	 	  > > >/ / /
H         r   r   __main__)r   rerR   typingr   r   r'   r   r   r   r   r	   r
   inkex.unitsr   inkex.localizationr   rl   r   EffectExtensionr   r   run r   r   <module>r      s  * "     " " " " " " " "  Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q " " " " " " 1 1 1 1 1 1;&'D D D D D% D D DN zIKKOO r   