{#-
Unified Parameter Table Macro

This macro creates consistent parameter/argument tables across all documentation types:
- Python function parameters
- CLI command options and arguments
- OpenAPI endpoint parameters
- Class method parameters

WHITESPACE CONTROL PATTERNS (CRITICAL FOR MARKDOWN TABLES):
================================================================

1. Row-building macros (build_table_row, build_attribute_row, build_returns_row):
   - Use `{%- macro ... -%}` and `{%- endmacro %}` to strip macro boundary whitespace
   - DO NOT use whitespace control on row content (`{{ }}` not `{{- -}}`)
   - This preserves spaces around pipes: `| `id` | - |` not `|`id`|-|`
   - Each macro outputs a complete single-line row

2. Helper macros (param_type, param_description, param_default, param_required):
   - Use whitespace control (`{%-` and `-%}`) throughout to prevent newlines
   - These are called WITHIN rows, so any newline breaks markdown table syntax
   - Output should be inline: `-` or `` `type` ``

3. Loops that generate rows:
   - Use normal `{% for %}` (not `{%- for -%}`) to preserve newlines BETWEEN rows
   - Each row macro call on its own line ensures proper separation
   - Blank line after separator row required for markdown table recognition

4. Result:
   - Each table row is a single line with proper spacing
   - Rows are separated by newlines
   - Markdown parsers correctly recognize table structure

WHY THIS MATTERS:
- Markdown tables require each row on a single line
- Jinja2's trim_blocks/lstrip_blocks removes newlines after tags
- We need explicit control: strip where we don't want newlines, preserve where we do
- Building rows as complete strings avoids template structure issues
-#}

{% from 'macros/safe_macros.md.jinja2' import safe_render, safe_var, safe_attr %}

{#- Main parameter table macro -#}
{% macro parameter_table(parameters, title="Parameters", show_types=true, show_defaults=true, show_required=false, table_style="list") %}
{% if parameters %}
{%- set param_list = parameters %}
{%- if parameters is mapping %}
{%- set param_list = parameters.values() | list %}
{%- endif %}
{% if param_list and param_list|length > 0 %}

{% if table_style == "dropdown" %}
{{ parameter_dropdown(param_list, title, show_types, show_defaults, show_required) }}
{% else %}
{{ parameter_list_table(param_list, title, show_types, show_defaults, show_required) }}
{% endif %}

{% endif %}
{% endif %}
{% endmacro %}

{#-
Helper: Build a single table row as a string

CRITICAL WHITESPACE PATTERNS FOR MARKDOWN TABLES:
- Macro definition uses `{%- macro ... -%}` to strip leading/trailing whitespace
- Macro end uses `{%- endmacro %}` to prevent trailing newline
- Row content uses NO whitespace control (`{{ }}` not `{{- -}}`) to preserve spaces around pipes
- Helper macros (param_type, param_description, etc.) use whitespace control internally
- Result: Each row is a single line with proper spacing: `| `id` | - | Description |`

Why this pattern:
- Markdown tables require each row on a single line
- Spaces around pipes are required for readability: `| cell |` not `|cell|`
- Jinja2's trim_blocks/lstrip_blocks removes newlines after tags, but we need to control them explicitly
- Building rows as complete strings avoids newline issues from template structure
-#}
{% macro build_table_row(param, show_types, show_defaults, show_required) -%}
| `{{ escape_table_cell(safe_attr(param, 'name', 'unknown')) }}`{% if show_types %} | {{ param_type(param) }}{% endif %}{% if show_defaults %} | {{ param_default(param) }}{% endif %}{% if show_required %} | {{ param_required(param) }}{% endif %} | {{ param_description(param) }} |
{%- endmacro %}

{#-
List table format (default)

CRITICAL: Newlines between rows, not within rows
- Loop uses normal `{% for %}` (not `{%- for -%}`) to preserve newlines between rows
- Each row macro call is on its own line to ensure proper separation
- Blank line after separator row is required for markdown table recognition
- Result: Each table row is on its own line, properly spaced
-#}
{% macro parameter_list_table(parameters, title, show_types, show_defaults, show_required) %}
**{{ title }}:**

| Name{% if show_types %} | Type{% endif %}{% if show_defaults %} | Default{% endif %}{% if show_required %} | Required{% endif %} | Description |
|:-----{% if show_types %}|:-----{% endif %}{% if show_defaults %}|:--------{% endif %}{% if show_required %}|:---------{% endif %}|:------------|
{% for param in parameters %}
{{ build_table_row(param, show_types, show_defaults, show_required) }}
{% endfor %}

{% endmacro %}

{#- Dropdown format for large parameter lists -#}
{% macro parameter_dropdown(parameters, title, show_types, show_defaults, show_required) %}
**{{ title }}**

::::{dropdown} {{ parameters|length }} {{ title.lower() }} (click to expand)
:open: false

{{ parameter_list_table(parameters, title, show_types, show_defaults, show_required) }}

::::
{% endmacro %}

{#- Helper macro to escape markdown table cell content -#}
{% macro escape_table_cell(text) %}
{%- if text -%}
{%- set cell_text = text|string|trim -%}
{%- set cell_text = cell_text|replace('|', '\\|') -%}
{%- set cell_text = cell_text|replace('\n', ' ') -%}
{%- set cell_text = cell_text|replace('\r', '') -%}
{%- set cell_text = cell_text|replace('\t', ' ') -%}
{%- set cell_text = cell_text|replace('  ', ' ') -%}
{{- cell_text -}}
{%- else -%}
-
{%- endif -%}
{% endmacro %}

{#-
Helper macros for parameter properties

CRITICAL: Use whitespace control (`{%-` and `-%}`) to prevent newlines
- These macros are called WITHIN table rows, so any newline breaks the row
- Whitespace control ensures output is inline: `-` or `` `type` ``
- Without this, conditional blocks would add newlines and break markdown table syntax
-#}
{% macro param_type(param) -%}
{%- set type_val = safe_attr(param, 'type', '') or safe_attr(param, 'annotation', '') -%}
{%- if type_val and type_val != 'None' and type_val|string|trim -%}
`{{- escape_table_cell(type_val) -}}`
{%- else -%}
-
{%- endif -%}
{%- endmacro %}

{% macro param_default(param) -%}
{%- set default_val = safe_attr(param, 'default', '') -%}
{%- if default_val -%}
{%- set default_str = default_val|string|trim -%}
{%- if default_str and default_str not in ['None', '', 'null'] and 'Sentinel' not in default_str -%}
`{{- escape_table_cell(default_val) -}}`
{%- else -%}
-
{%- endif -%}
{%- else -%}
-
{%- endif -%}
{%- endmacro %}

{% macro param_required(param) -%}
{%- set required = safe_attr(param, 'required', false) -%}
{%- if required -%}
✓
{%- else -%}
-
{%- endif -%}
{%- endmacro %}

{% macro param_description(param) -%}
{%- set desc = safe_attr(param, 'description', '') or safe_attr(param, 'docstring', '') -%}
{%- if desc and desc|string|trim -%}
{{- escape_table_cell(desc) -}}
{%- else -%}
*No description provided.*
{%- endif -%}
{%- endmacro %}

{#- Specialized parameter tables for different contexts -#}

{#- Python function parameters -#}
{% macro python_parameters(args, title="Parameters") %}
{{ parameter_table(args, title, show_types=true, show_defaults=true, show_required=false) }}
{% endmacro %}

{#- CLI command options -#}
{% macro cli_options(options, title="Options") %}
{{ parameter_table(options, title, show_types=true, show_defaults=true, show_required=true) }}
{% endmacro %}

{#- CLI command arguments -#}
{% macro cli_arguments(arguments, title="Arguments") %}
{{ parameter_table(arguments, title, show_types=true, show_defaults=false, show_required=true) }}
{% endmacro %}

{#- OpenAPI parameters (query, path, header) -#}
{% macro openapi_parameters(parameters, title="Parameters") %}
{{ parameter_table(parameters, title, show_types=true, show_defaults=true, show_required=true) }}
{% endmacro %}

{#-
Helper: Build a single attribute table row

Same whitespace pattern as build_table_row:
- `{%- macro ... -%}` and `{%- endmacro %}` to control macro boundaries
- NO whitespace control on row content to preserve spaces around pipes
- Helper macros handle their own whitespace control internally
-#}
{% macro build_attribute_row(attr) -%}
| `{{ escape_table_cell(safe_attr(attr, 'name', 'unknown')) }}` | {{ param_type(attr) }} | {{ param_description(attr) }} |
{%- endmacro %}

{#- Class attributes table -#}
{% macro attribute_table(attributes, title="Attributes") %}
{% if attributes and attributes|length > 0 %}
**{{ title }}:**

| Name | Type | Description |
|:-----|:-----|:------------|
{% for attr in attributes %}
{{ build_attribute_row(attr) }}
{% endfor %}

{% endif %}
{% endmacro %}

{#-
Helper: Build a single returns table row

Same whitespace pattern as other row-building macros:
- Control whitespace at macro boundaries, not in content
- Preserve spaces around pipes for proper markdown formatting
-#}
{% macro build_returns_row(return_item) -%}
| {{ param_type(return_item) }} | {{ param_description(return_item) }} |
{%- endmacro %}

{#- Returns/Response table -#}
{% macro returns_table(returns_info, title="Returns") %}
{% if returns_info %}
**{{ title }}:**

| Type | Description |
|:-----|:------------|
{% if returns_info is iterable and returns_info is not string %}
{% for return_item in returns_info %}
{{ build_returns_row(return_item) }}
{% endfor %}
{% else %}
{{ build_returns_row(returns_info) }}
{% endif %}

{% endif %}
{% endmacro %}
