
    PL
j(                        d Z ddlmZ ddlZddlmZ ddlmZ g dZ ej	        d          Z
dZd!dZd"dZd#dZd$dZd$dZd%d&dZd'dZd(dZd%d)d ZdS )*uN  CJK/wide-character-aware re-alignment of model-emitted markdown tables.

Models pad markdown tables assuming each character occupies one terminal
cell. CJK glyphs and most emoji render as two cells, so the model's
spacing collapses into drift the moment a table reaches a real terminal —
header pipes line up, every body row drifts right by N cells per CJK
char.

This module rebuilds row padding using ``wcwidth.wcswidth`` (display
columns), preserving the table's pipes and dashes so it still reads as a
plain-text table in ``strip`` / unrendered display modes. Standard Rich
markdown rendering already aligns CJK correctly inside a wide enough
panel; this helper is for the paths that print the model's text more or
less verbatim.

The helper is deliberately conservative:

* Only contiguous ``| ... |`` blocks with a divider line are rewritten.
* Anything that does not look like a table is passed through unchanged.
* Single-line / mid-stream fragments are left alone — callers buffer
  table rows and flush them once the block is complete.

There is a small, intentional caveat: ``wcwidth`` returns ``-1`` for some
emoji-with-variation-selector sequences (e.g. ``⚠️``); we clamp those to
0 so they do not corrupt the column width math. The 1-cell drift on
those specific glyphs is preferable to silently widening every table
that contains one.
    )annotationsN)Listwcswidth)is_table_dividerlooks_like_table_rowrealign_markdown_tablessplit_table_rowz^\s*:?-{3,}:?\s*$   sstrreturnintc                4    t          |           }|dk    r|ndS )a
  ``wcswidth`` clamped to a non-negative integer.

    ``wcswidth`` returns ``-1`` when it encounters a control char or an
    unknown sequence; treat those as zero-width rather than letting a
    negative number flow into ``max`` and break the column-width math.
    r   r   )r   ws     9/home/kuhnn/.hermes/hermes-agent/agent/markdown_tables.py_disp_widthr   1   s!     	AA111    targetc           	     N    | dt          d|t          |           z
            z  z   S )N r   )maxr   )r   r   s     r   _pad_to_widthr   =   s'    sSF[^^344444r   row	List[str]c                    |                                  }|                    d          r
|dd         }|                    d          r
|dd         }d |                    d          D             S )z<Split ``| a | b | c |`` into ``["a", "b", "c"]`` with trims.|   Nc                6    g | ]}|                                 S  )strip.0cs     r   
<listcomp>z#split_table_row.<locals>.<listcomp>I   s     ,,,!AGGII,,,r   )r"   
startswithendswithsplit)r   r   s     r   r
   r
   A   so     			A||C abbEzz# crcF,,qwws||,,,,r   boolc                x    t          |           }t          |          dk    ot          d |D                       S )z5True when ``row`` is a markdown table separator line.r   c              3  J   K   | ]}t                               |          V  d S N)_DIVIDER_CELL_REmatchr#   s     r   	<genexpr>z#is_table_divider.<locals>.<genexpr>P   s1      !K!K"2"8"8";";!K!K!K!K!K!Kr   )r
   lenall)r   cellss     r   r   r   L   s=     C  Eu::>Kc!K!KU!K!K!KKKKr   c                    d| vrdS |                                  }|sdS |                    d          rdS |                    d          dk    S )uN  True when ``row`` could plausibly be a markdown table row.

    Used by streaming callers to decide whether to buffer an in-flight
    line. We are intentionally permissive here — the realigner itself
    only rewrites blocks that are accompanied by a divider, so a false
    positive here at most delays the print of one line.
    r   FT   )r"   r'   count)r   strippeds     r   r   r   S   s`     #~~uyy{{H u 3 t>>#!##r   rowsList[List[str]]available_width
int | Nonec                    t          d  D                       fd D               fdt                    D             t                    dz  z   dz   }|%|t          |d          k    rt           |          S dfd} | d                   g}|                    dd                    d D                       z   dz               dd         D ] }|                     ||                     !|S )u  Render ``rows`` (header + body, divider implied) at uniform widths.

    If ``available_width`` is given and the rebuilt horizontal table
    would exceed it, fall back to a vertical key-value rendering so
    rows do not soft-wrap mid-cell — terminal soft-wrap destroys
    column alignment visually even when the underlying bytes are
    perfectly padded, which is exactly the "tables look broken"
    user report this code path is meant to address.
    c              3  4   K   | ]}t          |          V  d S r-   r1   )r$   rs     r   r0   z _render_block.<locals>.<genexpr>t   s(      %%1A%%%%%%r   c                B    g | ]}|d gt          |          z
  z  z   S ) r>   )r$   r?   ncolss     r   r&   z!_render_block.<locals>.<listcomp>u   s/    666AAA''666r   c                N    g | ] t          t          gfd D             R  !S )c              3  B   K   | ]}t          |                   V  d S r-   )r   )r$   r?   r%   s     r   r0   z+_render_block.<locals>.<listcomp>.<genexpr>x   s/      >>Ak!A$//>>>>>>r   )r   _MIN_COL_WIDTH)r$   r%   r8   s    @r   r&   z!_render_block.<locals>.<listcomp>w   sO        	N?>>>>>>>???  r   r   r   N   r3   r   r   r   c                l    dd                     fdt          |           D                       z   dz   S )Nz| z | c              3  J   K   | ]\  }}t          ||                   V  d S r-   )r   )r$   kr%   widthss      r   r0   z._render_block.<locals>._row.<locals>.<genexpr>   s5      RRAq&)44RRRRRRr   z |)join	enumerate)r3   rJ   s    r   _rowz_render_block.<locals>._row   sE    jjRRRR5AQAQRRRRRS	
r   r   r   c              3  &   K   | ]}d |dz   z  V  dS )-r5   Nr!   )r$   r   s     r   r0   z _render_block.<locals>.<genexpr>   s*      <<cQUm<<<<<<r   )r3   r   r   r   )r   rangesum_render_verticalappendrK   )r8   r:   horizontal_widthrM   outr?   rB   rJ   s   `     @@r   _render_blockrV   i   sV    %%%%%%%E6666666D   u  F 6{{QY.2"'7#or:R:R'R'Re_===
 
 
 
 
 
 4Q==/CJJsSXX<<V<<<<<<sBCCC!""X  

4477Jr   textwidthc                d   |dk    s| s| gS |                                  }|sdgS g }d}d}dd	}|D ]}t          |          }|sP||k    r|}|}nD |||          }	|                    |	d
d                    |	r|	d         nd}t          |          }c|dz   |z   |k    r|d|z   z  }|d|z   z  }|                    |           ||k    r|}|} |||          }	|                    |	d
d                    |	r|	d         nd}t          |          }|r|                    |           |pdgS )a  Soft-wrap ``text`` at word boundaries to fit ``width`` display cells.

    Falls back to hard-breaking the longest word if a single token is
    wider than ``width``.  Empty input yields a single empty string so
    the caller's row count stays predictable.
    r   rA   wordr   r   r   r   r   c                    g }d}d}| D ]B}t          |          pd}||z   |k    r|r|                    |           |}|}8||z  }||z  }C|r|                    |           |S )NrA   r   r   )r   rS   )rZ   r   rU   bufbwchcws          r   _hard_breakz#_wrap_to_width.<locals>._hard_break   s     	 	BR%ABBw{{s{

3r	b 	JJsOOO
r   Nr   r   r   )rZ   r   r   r   r   r   )r)   r   extendrS   )
rW   rX   wordslinescurrent	current_wr`   rZ   wwpiecess
             r   _wrap_to_widthrh      s    zzzvJJLLE tEGI   "  1 1 		U{{		$T511VCRC[)))(.6&**B'00	q=2&&sTz!GRIILL!!!U{{		$T511VCRC[)))(.6&**B'00		 W=RDr   rB   c                   | sg S | d         dg|t          | d                   z
  z  z   }| dd         }d t          |          D             }|r!t          dt          d|dz
                      nd	}d
|z  }d}t	          |          }	g }
t          |          D ]M\  }}|dk    r|
                    |           t          |          D ]}||         }|t          |          k     r||         nd}t	          |          }t          d||z
  dz
            }t          d||	z
            }|s|
                    | d           {t          ||          }|
                    | d|d                     t          |          dk    r]d                    |dd                   }t          ||          D ]/}|	                                r|
                    | |            0O|
S )u  Render a too-wide table as vertical ``Header: value`` rows.

    Mirrors Claude Code's narrow-terminal fallback in
    ``MarkdownTable.tsx``: each body row becomes a small block of
    ``Header: cell-value`` lines (continuation lines indented two
    spaces) separated by a thin ``─`` divider between rows.  Keeps
    every line narrower than ``available_width`` so the terminal does
    not soft-wrap mid-cell.
    r   rA   r   Nc                (    g | ]\  }}|pd |dz    S )zColumn r   r!   )r$   ihs      r   r&   z$_render_vertical.<locals>.<listcomp>   s.    DDDAa$$QU$$DDDr   rF   (   r5      u   ─z  
   :z: r   )
r1   rL   r   minr   rS   rP   rh   rK   r"   )r8   rB   r:   headersbodylabels	sep_width	separatorindentindent_wrU   rir   cilabelvaluelabel_wfirst_budgetcont_budgetwrapped	cont_textcls                         r   rR   rR      s      	1gDG 455G8DDD71C1CDDDF9HPBB! 344555bI	!IF6""HCT?? 4 4C66JJy!!!,, 	4 	4B2JE!CHH}}CGG"E!%((Gr?W#<q#@AALb/H"<==K 

e;;;'''$UL99GJJ%//71://0007||a  HHWQRR[11	(K@@ 4 4Bxxzz 4

f?b??333%	4& Jr   c                &   d| vr| S |                      d          }g }d}t          |          }||k     rH||         }d|v r|dz   |k     rt          ||dz                      rt          |          }g }|dz   }	|	|k     rd||	         v r||	                                         rrt          ||	                   r|	dz  }	E|                    t          ||	                              |	dz  }	|	|k     r$d||	         v r||	                                         rt          d |D                       s|r+|                    t          |g|z   |                     |	}.|                    |           |dz  }||k     Hd	                    |          S )a(  Rewrite every ``| ... |`` + divider block with wcwidth-aware padding.

    Lines that are not part of a recognised table are returned verbatim,
    so this is safe to apply to arbitrary assistant prose.

    If ``available_width`` is given (terminal cells available for the
    rendered table), tables wider than that are rendered as vertical
    key-value pairs instead of a horizontal pipe-bordered grid.  This
    avoids the terminal soft-wrapping mid-cell, which destroys column
    alignment visually even when the bytes are perfectly padded.
    r   
r   r   r5   c              3     K   | ]}|V  d S r-   r!   r#   s     r   r0   z*realign_markdown_tables.<locals>.<genexpr>.  s"      %%1%%%%%%r   )
r)   r1   r   r
   r"   rS   anyra   rV   rK   )
rW   r:   rc   rU   rk   nlineheaderrs   js
             r   r	   r	     s    $JJtEC	AE

A
a%%Qx 4KKA		 q1u..  %T**F$&DAAa%%C58OOa0@0@O#E!H-- FAOE!H55666Q a%%C58OOa0@0@O %%f%%%%%  

=&D/JJKKK

4	Q/ a%%2 99S>>r   )r   r   r   r   )r   r   r   r   r   r   )r   r   r   r   )r   r   r   r*   r-   )r8   r9   r:   r;   r   r   )rW   r   rX   r   r   r   )r8   r9   rB   r   r:   r   r   r   )rW   r   r:   r;   r   r   )__doc__
__future__r   retypingr   wcwidthr   __all__compiler.   rE   r   r   r
   r   r   rV   rh   rR   r	   r!   r   r   <module>r      sJ   : # " " " " " 				               2:233 	 	 	 	5 5 5 5- - - -L L L L$ $ $ $,% % % % %P? ? ? ?D1 1 1 1h. . . . . . .r   