
    i7                        d Z ddlZddlmZ ddlmZmZ erddlmZ ddl	m
Z
 ddlmZ ddl	mZmZ d	d
defdZd	d
defdZd	d
dedefdZd	d
dee   defdZ	 	 d0dee   dz  dee   dz  deee   dz  ee   dz  f   fdZdedee   dee   dz  dee   dz  dd
defdZdedee   dz  dee   dz  deee   dz  ee   dz  f   fdZd1d	d
dee   dz  deeeef   fdZdee   dz  dededee   fdZd edefd!Zdedd
d"d
d#edef
d$Zd	d
d%d&d#edee   fd'Zd	d
d(ededz  fd)Z d	d
dedz  fd*Z!d2d+edee   d,edefd-Z"d3d	d
d#ed.efd/Z#y)4z,Base utilities for documentation generation.    N)Sequence)TYPE_CHECKINGAny)App)	HelpPanel)CommandSpec)
format_docformat_usageappr   returnc                 h    t        | j                  j                        dk(  }|ry| j                  duS )a|  Determine if usage should be shown for an app.

    Root apps always show usage (even without default_command, showing "app COMMAND").
    Subcommands only show usage if they have a default_command.
    This skips usage for command groups that can't be invoked directly.

    The determination is made by checking the app_stack depth:
    - Stack length of 1 means root app (just the initial frame)
    - Stack length > 1 means we're in a subcommand context (frames were pushed)

    Parameters
    ----------
    app : App
        The App instance to check.

    Returns
    -------
    bool
        True if usage should be shown.
       TN)len	app_stackstackdefault_command)r   is_roots     x/home/jay/workspace/.worktrees/task-2116-dev1/scripts/.codegraph-venv/lib/python3.12/site-packages/cyclopts/docs/base.pyshould_show_usager      s6    , #--%%&!+G ""$..    c                     | j                   duS )a  Determine if commands list should be shown for an app.

    Only show commands list for apps with a default_command.
    Command groups (apps without default_command) skip the list
    since their commands will be documented recursively anyway.

    Parameters
    ----------
    app : App
        The App instance to check.

    Returns
    -------
    bool
        True if commands list should be shown.
    N)r   )r   s    r   should_show_commands_listr   /   s    " d**r   namec                     t        | j                  j                  dd            }t        | j                  j                  dd            }||z  }||v S )a  Check if a flag name is a built-in help or version flag.

    Parameters
    ----------
    app : App
        The App instance to check against.
    name : str
        The flag name to check.

    Returns
    -------
    bool
        True if this is a built-in help or version flag.
    
help_flags )fallbackversion_flags)setr   resolve)r   r   r   r   builtin_flagss        r   _is_builtin_flagr"   C   sU     S]]**<"*EFJ--o-KLM.M=  r   namesc                 2     |syt         fd|D              S )a4  Check if all names in the sequence are builtin help or version flags.

    Parameters
    ----------
    app : App
        The App instance to check against.
    names : Sequence[str]
        Sequence of flag names to check.

    Returns
    -------
    bool
        True if all names are builtin flags.
    Fc              3   6   K   | ]  }t        |        y wN)r"   ).0r   r   s     r   	<genexpr>z'is_all_builtin_flags.<locals>.<genexpr>i   s     =tT*=s   )all)r   r#   s   ` r   is_all_builtin_flagsr*   X   s     =u===r   commands_filterexclude_commandsc                     d}| | D ch c]  }|j                  dd       }}d}|r|D ch c]  }|j                  dd       }}||fS c c}w c c}w )a  Normalize command filter lists by converting underscores to dashes.

    Parameters
    ----------
    commands_filter : list[str] | None
        List of commands to include.
    exclude_commands : list[str] | None
        List of commands to exclude.

    Returns
    -------
    tuple[set[str] | None, set[str] | None]
        Normalized include and exclude sets for O(1) lookup.
    N_-)replace)r+   r,   normalized_includecmdnormalized_excludes        r   normalize_command_filtersr4   l   so    $ "?NOckk#s3OO?OPckk#s3PP111 P Qs
   AAparent_pathnormalized_commands_filternormalized_exclude_commandssubappc                    |rdj                  || gz         n| }|r?| |v s||v ryt        t        |            D ]  }dj                  |d|dz          }||v s y |u| |v s||v ryt        t        |            D ]  }dj                  |d|dz          }||v s y t        |d      r)|j                  r|D ]  }|j                  |dz         s y yy)a3  Determine if a command should be included based on filters.

    Parameters
    ----------
    name : str
        The command name.
    parent_path : list[str]
        Path to parent commands.
    normalized_commands_filter : set[str] | None
        Set of commands to include (already normalized).
    normalized_exclude_commands : set[str] | None
        Set of commands to exclude (already normalized).
    subapp : App
        The subcommand App instance.

    Returns
    -------
    bool
        True if the command should be included, False otherwise.
    .FNr   T	_commands)joinranger   hasattrr;   
startswith)	r   r5   r6   r7   r8   	full_pathiparent_segment
filter_cmds	            r   should_include_commandrD      s   6 3>v-.4I"..)?Z2Zs;'( 	A XXk'AE&:;N!<<	
 "--->X1Xs;'( 	A XXk'AE&:;N!;;	
 6;'F,<,<8  
((S9  r   c                    d}|_g }|D ]R  }|j                  | dz         r3|t        |       dz   d }|j                  |j                  dd             J|| k(  sPd} n ||sg }d}|rqg }|D ]j  }|j                  | dz         r3|t        |       dz   d }|j                  |j                  dd             J|j                  |j                  dd             l ||fS )a  Adjust filter lists for subcommand context.

    Parameters
    ----------
    name : str
        The current command name.
    normalized_commands_filter : set[str] | None
        Set of commands to include (already normalized).
    normalized_exclude_commands : set[str] | None
        Set of commands to exclude (already normalized).

    Returns
    -------
    tuple[list[str] | None, list[str] | None]
        Adjusted commands_filter and exclude_commands lists (denormalized).
    Nr:   r   r/   r.   )r?   r   appendr0   )	r   r6   r7   sub_commands_filterrC   
sub_filtersub_exclude_commandsexclude_cmdsub_excludes	            r   adjust_filters_for_subcommandrL      s   * !- 4 	J$$TCZ0'D	A8
#**:+=+=c3+GHt#&*#	 *3F"$"!6 	KK%%dSj1)#d)a-/:$++K,?,?S,IJ$++K,?,?S,IJ	K  444r   command_chainc                 h    |s| j                   d   }|}|}n|d   }dj                  |      }|}|||fS )a8  Get app name, full command path, and title.

    Parameters
    ----------
    app : App
        The cyclopts App instance.
    command_chain : Optional[List[str]]
        Chain of parent commands leading to this app.

    Returns
    -------
    Tuple[str, str, str]
        (app_name, full_command, title)
    r    )r   r<   )r   rM   app_namefull_commandtitles        r   get_app_inforS      sH     88A; #xx.\5((r   command_namerP   c                     | r| |gz   S ||gS )a>  Build command chain for a subcommand.

    Parameters
    ----------
    command_chain : Optional[List[str]]
        Current command chain.
    command_name : str
        Name of the subcommand.
    app_name : str
        Name of the root app.

    Returns
    -------
    List[str]
        Updated command chain.
    r   )rM   rT   rP   s      r   build_command_chainrV     s    " ~--,''r   command_pathc                 t    | j                         j                  dd      }t        j                  dd|      }|S )af  Generate a URL-friendly anchor from a command path.

    Converts spaces to hyphens and lowercases the string to match
    how markdown/HTML processors generate anchors from headings.
    Strips leading dashes to match markdown processor behavior.

    Parameters
    ----------
    command_path : str
        Full command path (e.g., "myapp files cp").

    Returns
    -------
    str
        Anchor string (e.g., "myapp-files-cp").

    Examples
    --------
    >>> generate_anchor("myapp files cp")
    'myapp-files-cp'
    >>> generate_anchor("myapp --install-completion")
    'myapp-install-completion'
    rO   r/   z-+)lowerr0   resub)rW   anchors     r   generate_anchorr]   #  s6    0 !))#s3FVVE3'FMr   
parent_appinclude_hiddenc                 h    t        ||       ryt        |t        |            sy|s|j                  syy)a|  Check if a command should be skipped.

    Parameters
    ----------
    command_name : str
        Name of the command.
    subapp : App
        The subcommand App instance.
    parent_app : App
        The parent App instance.
    include_hidden : bool
        Whether to include hidden commands.

    Returns
    -------
    bool
        True if command should be skipped.
    TF)r"   
isinstancetypeshow)rT   r8   r^   r_   s       r   should_skip_commandrd   A  s2    & 
L1fd:./&++r   panelr   c                     |r|j                   S |j                   D cg c]'  }|j                  rt        | |j                        r&|) c}S c c}w )aX  Filter help panel entries based on visibility settings.

    Parameters
    ----------
    app : App
        The App instance to check against.
    panel : HelpPanel
        The help panel to filter.
    include_hidden : bool
        Whether to include hidden entries.

    Returns
    -------
    List[Any]
        Filtered panel entries.
    )entriesr#   r*   )r   re   r_   es       r   filter_help_entriesri   `  s@    " }}}}]!QWW9McSTSZSZ9[A]]]s   'AAhelp_formatc                     t        | |      }|S )zExtract app description.

    Parameters
    ----------
    app : App
        The App instance.
    help_format : str
        Help format type.

    Returns
    -------
    Optional[Any]
        The extracted description object, or None.
    )r	   )r   rj   descriptions      r   extract_descriptionrm   w  s     S+.Kr   c                 j    | j                   | j                   r| j                   S dS t        | g       }|S )zExtract usage string.

    Parameters
    ----------
    app : App
        The App instance.

    Returns
    -------
    Optional[Any]
        The extracted usage object, or None.
    N)usager
   )r   ro   s     r   extract_usagerp     s4     yyIIsyy/4/b!ELr   
usage_textprefixc                    | syd| v r | j                  dd      j                         } |rdj                  |      nd}| j                  dd      }t	        |      dkD  r+|r)|r| d| d|d    n	| d|d    }|j                         S |r|r| d| n|}|j                         S |r| d|  n| }|j                         S )aE  Format usage line with proper command path.

    Parameters
    ----------
    usage_text : str
        Raw usage text.
    command_chain : List[str]
        Command chain for the app.
    prefix : str
        Optional prefix for the usage line (e.g., "$").

    Returns
    -------
    str
        Formatted usage line.
     zUsage:rO   Nr   )r0   stripr<   splitr   )rq   rM   rr   rQ   parts
usage_lines         r   format_usage_linery     s    " :''"5;;=
.;388M*LT1%E
5zA~->Dxqaaz:\NZ[\abc\d[eJf
  
39xq/|
  28xq-Z
r   resolve_lazyc              #     K   | j                   syt               }| j                   j                         D ]  \  }}t        | |      rt	        |t
              r!|j                  s|s2|j                  |       }n|}t	        |t        |             s\|s|j                  skt        |      }||v r{|j                  |       ||f  yw)a  Iterate through app commands, yielding valid resolved subapps.

    Automatically resolves CommandSpec instances to App instances.
    Each unique subapp is yielded only once (first occurrence wins).

    Parameters
    ----------
    app : App
        The App instance.
    include_hidden : bool
        Whether to include hidden commands.
    resolve_lazy : bool
        If ``True`` (default), resolve lazy commands (import their modules) to
        include them in the output. If ``False``, skip unresolved lazy commands.
        Set to ``True`` when generating static artifacts that need all commands,
        such as documentation or shell completion scripts.

    Yields
    ------
    Tuple[str, App]
        (command_name, resolved_subapp) for each valid command.
    N)r;   r   itemsr"   ra   r   is_resolvedr    rb   rc   idadd)r   r_   rz   seenr   app_or_specr8   app_ids           r   iterate_commandsr     s     . ==UD ]]002 kC&k;/**< ((-F F&$s),fkk FT>Fl/s   CC	)NNr&   )rt   )FT)$__doc__rZ   collections.abcr   typingr   r   cyclopts.corer   cyclopts.helpr   cyclopts.command_specr   r	   r
   boolr   r   strr"   r*   listtupler   r4   rD   rL   rS   rV   r]   rd   ri   rm   rp   ry   r   r   r   r   <module>r      s   2 	 $ %!' - 2/5 /T /@+5 +T +(!% !s !t !*>e >HSM >d >* )-)-2#Y%23i$&2 3s8d?CHtO+,2:5
5c5 !$C45 "%SD	5
 5 
5p-5
-5 #C4-5 "%SD-5 49tT#Y--.	-5`)e )DI,< )cSVX[mH\ )6(tCy4'7 (s (VY (^bcf^g (.# # <c 5 e ]a fj >^U ^; ^ ^QUVYQZ ^.U  t &u t (!# !d3i ! !VY !H3% 3 3T 3r   