FastHTML dual-column text segmentation & VAD alignment UI for transcript decomposition workflows with forced alignment-based text splitting for aligning text segments with VAD chunks.
Project description
cjm-transcript-segment-align
Install
pip install cjm_transcript_segment_align
Project Structure
nbs/
├── components/ (6)
│ ├── handlers.ipynb # Handler wrappers for cross-domain coordination (alignment status updates)
│ ├── helpers.ipynb # State extraction helpers for cross-domain coordination in Phase 2 combined step
│ ├── keyboard_config.ipynb # Shared keyboard navigation configuration for the combined Phase 2 step
│ ├── step_renderer.ipynb # Phase 2 combined step renderer: dual-column layout for Segment & Align
│ ├── sync_controls.ipynb # Synced navigation toggle for the combined Phase 2 dual-column step
│ └── toolbar_state.ipynb # Centralized client-side toolbar state restoration after HTMX settles
├── routes/ (3)
│ ├── chrome.ipynb # Shared chrome switching route handlers for the combined Phase 2 step
│ ├── forced_alignment.ipynb # Routes for toggling between NLTK and force-aligned pre-splits, plus rendering helpers for FA UI controls. Trigger and progress are handled by `cjm-fasthtml-job-monitor`.
│ └── init.ipynb # Consolidated router assembly for the segment-align step
├── services/ (1)
│ └── forced_alignment.ipynb # Forced alignment service for audio-informed text pre-splitting via forced alignment plugin
├── html_ids.ipynb # HTML ID constants for Phase 2 Shell: Dual-Column Layout shared chrome
└── models.ipynb # Data types and result containers for the segment-align integration surface
Total: 12 notebooks across 3 directories
Module Dependencies
graph LR
components_handlers[components.handlers<br/>handlers]
components_helpers[components.helpers<br/>helpers]
components_keyboard_config[components.keyboard_config<br/>keyboard_config]
components_step_renderer[components.step_renderer<br/>step_combined]
components_sync_controls[components.sync_controls<br/>sync_controls]
components_toolbar_state[components.toolbar_state<br/>toolbar_state]
html_ids[html_ids<br/>html_ids]
models[models<br/>models]
routes_chrome[routes.chrome<br/>chrome]
routes_forced_alignment[routes.forced_alignment<br/>forced_alignment]
routes_init[routes.init<br/>routes/init]
services_forced_alignment[services.forced_alignment<br/>forced_alignment]
components_handlers --> components_sync_controls
components_handlers --> components_keyboard_config
components_handlers --> components_step_renderer
components_handlers --> services_forced_alignment
components_handlers --> routes_forced_alignment
components_handlers --> html_ids
components_keyboard_config --> html_ids
components_keyboard_config --> components_sync_controls
components_step_renderer --> components_sync_controls
components_step_renderer --> components_keyboard_config
components_step_renderer --> html_ids
components_step_renderer --> components_helpers
components_step_renderer --> components_toolbar_state
components_toolbar_state --> components_sync_controls
routes_chrome --> components_sync_controls
routes_chrome --> components_step_renderer
routes_chrome --> components_handlers
routes_chrome --> html_ids
routes_forced_alignment --> components_sync_controls
routes_forced_alignment --> components_step_renderer
routes_forced_alignment --> html_ids
routes_init --> components_handlers
routes_init --> components_keyboard_config
routes_init --> models
routes_init --> routes_forced_alignment
routes_init --> services_forced_alignment
routes_init --> components_sync_controls
routes_init --> html_ids
routes_init --> routes_chrome
routes_init --> components_step_renderer
30 cross-module dependencies detected
CLI Reference
No CLI commands found in this project.
Module Overview
Detailed documentation for each module in the project:
chrome (chrome.ipynb)
Shared chrome switching route handlers for the combined Phase 2 step
Import
from cjm_transcript_segment_align.routes.chrome import (
DEBUG_SWITCH_CHROME,
init_chrome_router
)
Functions
async def _handle_switch_chrome(
state_store:SQLiteWorkflowStateStore, # State store instance
workflow_id:str, # Workflow identifier
request, # FastHTML request object
sess, # FastHTML session object
seg_urls:SegmentationUrls, # URL bundle for segmentation routes
align_urls:AlignmentUrls, # URL bundle for alignment routes
jm_trigger=None, # Pre-rendered job monitor trigger element
fa_toggle_url:str="", # URL for FA toggle route
fa_available:bool=False, # Whether FA plugin is available
) -> tuple: # OOB swaps for shared chrome containers
"""
Switch shared chrome content based on active column.
Client-side toolbar state restoration (sync button, auto-play toggle)
is handled by the centralized settle handler from toolbar_state.py.
Settings modals persist in the DOM — only the trigger buttons swap.
"""
def init_chrome_router(
state_store: SQLiteWorkflowStateStore, # State store instance
workflow_id: str, # Workflow identifier
seg_urls: SegmentationUrls, # URL bundle for segmentation routes
align_urls: AlignmentUrls, # URL bundle for alignment routes
prefix: str, # Route prefix (e.g., "/workflow/core/chrome")
jm_trigger = None, # Pre-rendered job monitor trigger element
fa_toggle_url: str = "", # URL for FA toggle route
fa_available: bool = False, # Whether FA plugin is available
) -> Tuple[APIRouter, Dict[str, Callable]]: # (router, route_dict)
"Initialize chrome switching routes."
Variables
DEBUG_SWITCH_CHROME = False
forced_alignment (forced_alignment.ipynb)
Routes for toggling between NLTK and force-aligned pre-splits, plus rendering helpers for FA UI controls. Trigger and progress are handled by
cjm-fasthtml-job-monitor.
Import
from cjm_transcript_segment_align.routes.forced_alignment import (
FA_SLOT_ID,
render_fa_toggle,
init_forced_alignment_routers
)
Functions
def render_fa_toggle(
active_presplit: str, # "nltk" or "forced_alignment"
toggle_url: str, # URL for toggle route
) -> Any: # Toggle button group
"Render the NLTK / Force Aligned toggle button group."
async def _handle_fa_toggle(
state_store: SQLiteWorkflowStateStore,
workflow_id: str,
request: Any,
sess: Any,
seg_urls: SegmentationUrls,
toggle_url: str,
) -> Any: # Targeted OOB updates (slots + stats + toolbar with toggle + alignment status + mini-stats)
"""
Toggle between NLTK and force-aligned pre-split snapshots.
Loads the selected pre-split snapshot as the current working state.
Pushes the previous working state to undo history (single history model).
"""
def init_forced_alignment_routers(
state_store: SQLiteWorkflowStateStore, # State store instance
workflow_id: str, # Workflow identifier
seg_urls: SegmentationUrls, # Segmentation URL bundle
prefix: str, # Route prefix (e.g., "/fa")
) -> Tuple[APIRouter, Dict[str, Callable]]: # (router, route_dict)
"""
Initialize forced alignment routes (toggle only).
Trigger and progress are handled by `cjm-fasthtml-job-monitor`.
This router provides the domain-specific toggle between NLTK/FA pre-splits.
"""
Variables
FA_SLOT_ID
forced_alignment (forced_alignment.ipynb)
Forced alignment service for audio-informed text pre-splitting via forced alignment plugin
Import
from cjm_transcript_segment_align.services.forced_alignment import (
map_fa_words_to_text,
assign_words_to_chunks,
build_segments_from_alignment,
ForcedAlignmentService
)
Functions
def _strip_punct(text: str) -> str
"Strip punctuation from text for comparison with FA output."
def map_fa_words_to_text(
text: str, # Original text with punctuation
fa_items: List[ForcedAlignItem], # FA word-level alignment results
) -> List[Tuple[int, int]]: # List of (start_char, end_char) spans into original text
"""
Map forced alignment words back to character spans in the original text.
Walks through the original text, matching each FA word (punctuation-stripped)
against original text tokens. Returns character offset pairs for each FA word.
"""
def assign_words_to_chunks(
fa_items: List[ForcedAlignItem], # FA word-level alignment results
vad_chunks: List[VADChunk], # VAD chunks with start/end times
) -> List[int]: # Chunk index for each FA word
"""
Assign each FA word to a VAD chunk based on timestamp overlap.
Words whose start_time falls within a chunk's [start, end] range are
assigned to that chunk. Words in silence gaps are assigned to the
nearest chunk by time proximity.
"""
def build_segments_from_alignment(
text: str, # Original text with punctuation
spans: List[Tuple[int, int]], # Character spans from map_fa_words_to_text
assignments: List[int], # Chunk index per word from assign_words_to_chunks
num_chunks: int, # Total number of VAD chunks
source_id: Optional[str] = None, # Source block ID for traceability
source_provider_id: Optional[str] = None, # Source provider identifier
) -> List[TextSegment]: # One segment per VAD chunk
"""
Build TextSegment list by grouping words by their assigned VAD chunk.
Each VAD chunk gets one TextSegment whose text is the joined original
(punctuated) words assigned to that chunk.
"""
Classes
class ForcedAlignmentService:
def __init__(
self,
plugin_manager: PluginManager, # Plugin manager for accessing forced alignment plugin
plugin_name: str = "cjm-transcription-plugin-qwen3-forced-aligner", # Name of the FA plugin
)
"Service for audio-informed text pre-splitting via forced alignment plugin."
def __init__(
self,
plugin_manager: PluginManager, # Plugin manager for accessing forced alignment plugin
plugin_name: str = "cjm-transcription-plugin-qwen3-forced-aligner", # Name of the FA plugin
)
"Initialize the forced alignment service."
def is_available(self) -> bool: # True if plugin is loaded and ready
"""Check if the forced alignment plugin is available."""
return self._manager.get_plugin(self._plugin_name) is not None
def ensure_loaded(
self,
config: Optional[Dict[str, Any]] = None, # Optional plugin configuration
) -> bool: # True if successfully loaded
"Check if the forced alignment plugin is available."
def ensure_loaded(
self,
config: Optional[Dict[str, Any]] = None, # Optional plugin configuration
) -> bool: # True if successfully loaded
"Ensure the forced alignment plugin is loaded."
async def align_and_split_async(
self,
audio_path: str, # Path to the audio file
text: str, # Original transcript text blob (with punctuation)
vad_chunks: List[VADChunk], # VAD chunks for this audio
source_id: Optional[str] = None, # Source block ID for traceability
source_provider_id: Optional[str] = None, # Source provider identifier
) -> List[TextSegment]: # One segment per VAD chunk
"Run forced alignment and split text into segments matching VAD chunks."
def align_and_split(
self,
audio_path: str, # Path to the audio file
text: str, # Original transcript text blob
vad_chunks: List[VADChunk], # VAD chunks for this audio
source_id: Optional[str] = None,
source_provider_id: Optional[str] = None,
) -> List[TextSegment]: # One segment per VAD chunk
"Run forced alignment and split text synchronously."
async def align_and_split_combined_async(
self,
source_blocks: List[Any], # SourceBlock objects with id, provider_id, text
audio_paths: List[str], # Audio file path per source block
vad_chunks_by_source: List[List[VADChunk]], # VAD chunks per source block
) -> List[TextSegment]: # Combined segments with global indexing
"Align and split multiple source blocks with their respective audio."
Variables
_PUNCT_RE
handlers (handlers.ipynb)
Handler wrappers for cross-domain coordination (alignment status updates)
Import
from cjm_transcript_segment_align.components.handlers import (
segments_match_presplit,
build_fa_extra_actions,
build_fa_job_args,
build_fa_on_complete,
create_seg_mutation_wrapper,
wrap_align_mutation_handler,
create_seg_init_chrome_wrapper,
create_align_init_chrome_wrapper,
create_seg_mutation_wrappers
)
Functions
def _find_session_id(args, kwargs):
"""Find session_id from args or kwargs."""
if 'sess' in kwargs
"Find session_id from args or kwargs."
def segments_match_presplit(
current_segments: list, # Current segment dicts
presplit: list, # Pre-split snapshot segment dicts
) -> bool: # Whether current segments match the pre-split
"Check if current segments match a pre-split snapshot by text content."
def build_fa_extra_actions(
seg_state: dict, # Segmentation step state dict
jm_trigger: Any = None, # Pre-rendered job monitor trigger element (or None)
fa_toggle_url: str = "", # URL for FA toggle route
fa_available: bool = False, # Whether FA plugin is available
) -> Any: # FA controls wrapped in slot div (or None)
"""
Build FA controls for the toolbar extra_actions slot.
Shows toggle when current segments match either pre-split snapshot.
Shows job monitor trigger when FA pre-split doesn't exist or current doesn't match either.
`jm_trigger` is the pre-rendered trigger element from `check_inflight_job` or `render_job_trigger`.
"""
def build_fa_job_args(
source_service: SourceService, # Source service for audio paths/text
) -> Callable: # fn(state_store, workflow_id, session_id) -> List[(args, kwargs)]
"""
Create the job_args_builder for FA job sequences.
Returns a function that extracts audio paths and text from workflow state,
producing one (args, kwargs) pair per selected source.
"""
def build_fa_on_complete(
source_service: SourceService, # Source service for source block metadata
seg_urls: SegmentationUrls, # Segmentation URL bundle
fa_toggle_url: str, # URL for FA toggle route
fa_available: bool, # Whether FA plugin is available
state_store: WorkflowStateStore, # State store
workflow_id: str, # Workflow ID
step_id: str = "segmentation", # Step ID for segmentation state
) -> Callable: # async fn(results, request, sess) -> List[FT]
"""
Create the on_complete callback for FA job sequences.
Converts per-source FA plugin results into TextSegments using VAD chunk
alignment, updates segmentation state (fa_presplit, segments, etc.),
and returns OOB card stack + toggle + alignment status updates.
"""
def create_seg_mutation_wrapper(
handler_result: Callable, # _handle_seg_*_result function
jm_trigger: Any = None, # Pre-rendered job monitor trigger element
fa_toggle_url: str = "", # URL for FA toggle route
fa_available: bool = False, # Whether FA plugin is available
clear_fa_presplit: bool = False, # Whether to clear fa_presplit after handler (for NLTK Split)
) -> Callable: # Wrapped handler that builds OOB with FA extra_actions + alignment status
"""
Create a wrapped mutation handler that uses SegMutationResult.
Calls the _result handler variant, builds targeted OOB response with FA
controls in toolbar, and appends alignment status + mini-stats OOB.
Computes nltk_split_disabled from state for toolbar rendering.
"""
def wrap_align_mutation_handler(
handler: Callable, # Handler function to wrap
) -> Callable: # Wrapped handler that appends alignment status OOB
"""
Wrap an alignment mutation handler to add alignment status OOB.
The handler is expected to take (state_store, workflow_id, ...) as first params.
"""
def create_seg_init_chrome_wrapper(
align_urls:AlignmentUrls, # URL bundle for alignment routes (for KB system)
switch_chrome_url:str, # URL for chrome switching (for KB system)
jm_trigger:Any=None, # Pre-rendered job monitor trigger element (optional)
fa_toggle_url:str="", # URL for forced alignment toggle (optional)
fa_available:bool=False, # Whether forced alignment plugin is available
) -> Callable: # Wrapped handler that builds KB system and shared chrome
"""
Create a wrapper for seg init that builds combined KB system and shared chrome.
Saves nltk_presplit snapshot at init time for match detection.
FA controls are rendered in the toolbar via extra_actions.
Settings modals are rendered in a persistent container (both seg + align).
"""
def create_align_init_chrome_wrapper(
should_play_fn:str="", # Consumer-defined play guard function name
) -> Callable: # Wrapped handler that adds alignment status
"""
Create a wrapper for align init that adds mini-stats and alignment status.
Returns a footer OOB (not a standalone alignment status badge) to avoid
a race condition: both seg and align init auto-trigger on load, and the
alignment status badge only exists inside the footer after seg init's
footer OOB is processed. Using a footer OOB is safe because the footer
container always exists in the DOM.
"""
def create_seg_mutation_wrappers(
jm_trigger: Any = None, # Pre-rendered job monitor trigger element
fa_toggle_url: str = "", # URL for FA toggle route
fa_available: bool = False, # Whether FA plugin is available
) -> dict: # Dict with keys: split, merge, undo, reset, ai_split
"""
Create wrapped mutation handlers with FA controls in toolbar.
Returns a dict of handler name -> wrapped handler function.
Called at setup time when job monitor trigger element and FA URLs are known.
The ai_split wrapper has clear_fa_presplit=True — clicking NLTK Split
discards the FA pre-split snapshot and replaces the toggle with the trigger button.
"""
helpers (helpers.ipynb)
State extraction helpers for cross-domain coordination in Phase 2 combined step
Import
from cjm_transcript_segment_align.components.helpers import (
SEG_DEFAULT_VISIBLE_COUNT,
SEG_DEFAULT_CARD_WIDTH,
ALIGN_DEFAULT_VISIBLE_COUNT,
ALIGN_DEFAULT_CARD_WIDTH,
check_alignment_ready,
extract_seg_state,
extract_alignment_state,
get_segment_count,
get_chunk_count
)
Functions
def check_alignment_ready(
segment_count:int, # Number of text segments
chunk_count:int, # Number of VAD chunks
) -> bool: # True if counts match for 1:1 alignment
"Check if segment and VAD chunk counts match for 1:1 alignment."
def extract_seg_state(
ctx:InteractionContext, # Interaction context with state
) -> Dict[str, Any]: # Extracted state values
"Extract segmentation state as explicit values for renderers."
def extract_alignment_state(
ctx:InteractionContext, # Interaction context with state
) -> Dict[str, Any]: # Extracted state values
"Extract alignment state as explicit values for renderers."
def get_segment_count(
ctx:InteractionContext, # Interaction context with state
) -> int: # Number of segments
"Get segment count from state without full extraction."
def get_chunk_count(
ctx:InteractionContext, # Interaction context with state
) -> int: # Number of VAD chunks
"Get VAD chunk count from state without full extraction."
Variables
SEG_DEFAULT_VISIBLE_COUNT = 3
SEG_DEFAULT_CARD_WIDTH = 80
ALIGN_DEFAULT_VISIBLE_COUNT = 5
ALIGN_DEFAULT_CARD_WIDTH = 40
html_ids (html_ids.ipynb)
HTML ID constants for Phase 2 Shell: Dual-Column Layout shared chrome
Import
from cjm_transcript_segment_align.html_ids import (
CombinedHtmlIds
)
Classes
class CombinedHtmlIds:
"HTML ID constants for Phase 2 Shell: Dual-Column Layout shared chrome."
def as_selector(
id_str:str # The HTML ID to convert
) -> str: # CSS selector with # prefix
"Convert an ID to a CSS selector format."
routes/init (init.ipynb)
Consolidated router assembly for the segment-align step
Import
from cjm_transcript_segment_align.routes.init import (
init_segment_align_routers
)
Functions
def _validate_alignment(
state:Dict[str, Any] # Workflow state dictionary
) -> bool: # True if segments and VAD chunks are 1:1 aligned
"Validate 1:1 alignment between segments and VAD chunks."
def init_segment_align_routers(
"""
Initialize all segment-align routers and return result bundle.
Internally creates services, initializes sub-library routers,
wires mutation wrappers, chrome switching, forced alignment,
and job monitor integration.
"""
keyboard_config (keyboard_config.ipynb)
Shared keyboard navigation configuration for the combined Phase 2 step
Import
from cjm_transcript_segment_align.components.keyboard_config import (
DEBUG_KB_SYSTEM,
ZONE_CHANGE_CALLBACK,
KB_SYSTEM_ID,
SWITCH_CHROME_BTN_ID,
build_combined_kb_system,
generate_zone_change_js
)
Functions
def build_combined_kb_system(
seg_urls:SegmentationUrls, # URL bundle for segmentation routes
align_urls:AlignmentUrls, # URL bundle for alignment routes
) -> Tuple[ZoneManager, Any]: # (keyboard manager, rendered keyboard system)
"Build combined keyboard system with segmentation and alignment zones."
def generate_zone_change_js(
switch_chrome_url:str="", # URL for chrome swap handler (empty = no swap)
) -> Script: # Script element with zone change callback and click handlers
"Generate JavaScript for zone change handling and column click handlers."
Variables
DEBUG_KB_SYSTEM = True
ZONE_CHANGE_CALLBACK = 'onCombinedZoneChange'
KB_SYSTEM_ID = 'sd-seg-align-kb'
SWITCH_CHROME_BTN_ID = 'sd-switch-chrome-btn'
models (models.ipynb)
Data types and result containers for the segment-align integration surface
Import
from cjm_transcript_segment_align.models import (
SegmentAlignUrls,
SegmentAlignResult
)
Classes
@dataclass
class SegmentAlignUrls:
"Combined URL bundle for host access."
seg: SegmentationUrls # Segmentation route URLs
align: AlignmentUrls # Alignment route URLs
switch_chrome: str = '' # Chrome switching URL
fa_toggle: str = '' # FA toggle URL (empty if FA unavailable)
@dataclass
class SegmentAlignResult:
"Everything the host needs from init_segment_align_routers()."
urls: SegmentAlignUrls # Combined URL bundle
render_step: Callable # fn(ctx: InteractionContext) -> FT
sse_headers: list = field(...) # Headers for app (SSE extension)
fa_available: bool = False # Whether forced alignment is available
validate_alignment: Callable # fn(state: dict) -> bool
step_combined (step_renderer.ipynb)
Phase 2 combined step renderer: dual-column layout for Segment & Align
Import
from cjm_transcript_segment_align.components.step_renderer import (
DEBUG_COMBINED_RENDER,
render_seg_mini_stats_badge,
render_align_mini_stats_badge,
render_alignment_status_text,
render_alignment_status,
render_footer_inner_content,
render_combined_step
)
Functions
def _render_column_header(
title:str, # Column title (e.g., "Text Decomposition")
stats_id:str, # HTML ID for the mini-stats badge area
header_id:str, # HTML ID for the column header container
initial_text:str="--", # Initial text for the mini-stats badge
) -> Any: # Column header component
"Render a column header with title and mini-stats badge."
def render_seg_mini_stats_badge(
segments:List[TextSegment], # Current segments
oob:bool=False, # Whether to render as OOB swap
) -> Any: # Mini-stats badge Span
"Render the segmentation mini-stats badge for the column header."
def render_align_mini_stats_badge(
chunks:List[VADChunk], # Current VAD chunks
oob:bool=False, # Whether to render as OOB swap
) -> Any: # Mini-stats badge Span
"Render the alignment mini-stats badge for the column header."
def render_alignment_status_text(
segment_count:int, # Number of text segments
chunk_count:int, # Number of VAD chunks
) -> str: # Status message text
"Generate alignment status message based on segment and VAD chunk counts."
def render_alignment_status(
segment_count:int, # Number of text segments
chunk_count:int, # Number of VAD chunks
oob:bool=False, # Whether to render as OOB swap
) -> Any: # Alignment status badge component
"Render the alignment status indicator badge."
def render_footer_inner_content(
seg_footer:Any, # Segmentation footer content (or None if not initialized)
align_footer:Any, # Alignment footer content (or None if not initialized)
segment_count:int, # Number of text segments
chunk_count:int, # Number of VAD chunks
) -> Any: # Styled wrapper div with both column footers and alignment status
"""
Render the footer inner content with both column footers always present.
Both footers remain in the DOM so their internal OOB targets (progress
indicators, source position) are always valid regardless of which column
is active. This enables cross-zone features like auto-play.
"""
def _placeholder(
text:str, # Placeholder message
) -> Any: # Styled placeholder paragraph
"Render a placeholder text element for uninitialized chrome containers."
def _render_shared_chrome(
seg_state:dict=None, # Extracted segmentation state (None = show placeholders)
align_state:dict=None, # Extracted alignment state (None = no VAD data yet)
urls:SegmentationUrls=None, # Segmentation URL bundle (required when seg_state provided)
extra_actions:tuple=(), # Extra toolbar elements (FA controls, sync toggle, etc.)
nltk_split_disabled:bool=False, # Whether NLTK Split button is disabled
) -> tuple: # (toolbar, footer, settings_modals_container)
"""
Render shared chrome containers, populated with segmentation content when initialized.
Takes extracted state dicts from `extract_seg_state()` and `extract_alignment_state()`
which contain deserialized TextSegment and VADChunk objects.
"""
def _render_seg_column(
is_active:bool=True, # Whether this column is initially active
column_body:Any=None, # Pre-rendered column body (None = not initialized)
mini_stats_text:str="--", # Mini-stats badge text
init_url:str="", # URL for auto-trigger initialization
) -> Any: # Left column component
"Render the left segmentation column."
def _render_alignment_column(
is_active:bool=False, # Whether this column is initially active
column_body:Any=None, # Pre-rendered column body (None = not initialized)
mini_stats_text:str="--", # Mini-stats badge text
init_url:str="", # URL for auto-trigger initialization
) -> Any: # Right column component
"Render the right alignment column."
def _render_keyboard_system_container(
kb_system:Any=None, # Rendered keyboard system (None = empty container)
oob:bool=False, # Whether to render as OOB swap
) -> Any: # Div with id=KEYBOARD_SYSTEM containing KB elements
"Render stable container for keyboard navigation system elements."
def render_combined_step(
ctx:InteractionContext, # Interaction context with state and data
seg_urls:SegmentationUrls=None, # URL bundle for segmentation routes
align_urls:AlignmentUrls=None, # URL bundle for alignment routes
switch_chrome_url:str="", # URL for chrome switching route
fa_available:bool=False, # Whether forced alignment plugin is available
jm_trigger:Any=None, # Pre-rendered job monitor trigger element (or None)
fa_toggle_url:str="", # URL for forced alignment toggle route
jm_overlay_el:Any=None, # Job monitor overlay element (or placeholder)
jm_modal_el:Any=None, # Job monitor modal element (or placeholder)
jm_kb_script_el:Any=None, # Job monitor keyboard script placeholder (for OOB pause/resume)
) -> Any: # FastHTML component with full dual-column layout
"""
Render Phase 2: Combined Segment & Align step with dual-column layout.
The dual-column container has position:relative for the job monitor overlay,
and a stable ID (CombinedHtmlIds.COLUMNS) for overlay targeting.
"""
Variables
_ALIGN_SYNC_CONFIG
DEBUG_COMBINED_RENDER = True
_FOOTER_INNER_CLS
_SEG_COLUMN_CLS
_ALIGNMENT_COLUMN_CLS
sync_controls (sync_controls.ipynb)
Synced navigation toggle for the combined Phase 2 dual-column step
Import
from cjm_transcript_segment_align.components.sync_controls import (
SYNC_TOGGLE_FN,
SYNC_KEY,
SYNC_BTN_ID,
SHOULD_PLAY_FN,
render_sync_toggle_button,
generate_sync_script,
generate_sync_key_toggle_js,
generate_should_play_js,
generate_sync_restore_js,
build_extra_actions
)
Functions
def render_sync_toggle_button() -> Any: # Sync toggle button element
"Render the synced navigation toggle button for the seg toolbar."
def generate_sync_script(
source_input_id:str, # Seg card stack's focused_index hidden input ID
target_nav_url:str, # Align card stack's nav_to_index URL
) -> Any: # Script element with sync JS
"Generate the sync JS Script element for the combined step."
def generate_sync_key_toggle_js() -> str: # JS defining window._segAlignSyncKeyToggle
"Generate JS for the S key sync toggle wrapper function."
def generate_should_play_js() -> str: # JS defining window.shouldAlignPlay
"""
Generate JS for the custom play guard function.
Returns true when audio should play:
- Zone is active (direct align navigation), OR
- Auto-navigate is on (auto-play through align stack), OR
- Sync is enabled (seg navigation driving align)
"""
def generate_sync_restore_js() -> str: # JS to restore sync button styling from client state
"""
Generate JS to sync the toolbar button styling with the client-side sync state.
After chrome switch re-renders the seg toolbar, the sync button starts
with btn-outline. This reads the JS state and restores btn-primary if
sync is enabled.
"""
def build_extra_actions(
fa_extra:Any=None, # FA controls element (from build_fa_extra_actions, or None)
) -> tuple: # Tuple of toolbar extra action elements
"""
Build the extra_actions tuple for the seg toolbar.
Combines FA controls (if available) with the sync toggle button.
Client-side state restoration (sync button styling) is handled by
the centralized toolbar restore settle handler in toolbar_state.py.
Returns a tuple compatible with render_toolbar(extra_actions=...).
"""
Variables
SYNC_TOGGLE_FN = 'toggleSegAlignSync'
SYNC_KEY = '_segAlignSync'
SYNC_BTN_ID = 'sd-sync-toggle-btn'
SHOULD_PLAY_FN = 'shouldAlignPlay'
toolbar_state (toolbar_state.ipynb)
Centralized client-side toolbar state restoration after HTMX settles
Import
from cjm_transcript_segment_align.components.toolbar_state import (
generate_toolbar_restore_js
)
Functions
def generate_toolbar_restore_js() -> Script: # Script element with settle handler
"""
Generate the centralized toolbar state restore settle handler.
Restores client-side state for all toolbar toggles/buttons after any
HTMX settle that re-renders the toolbar. Runs once per settle event.
"""
Variables
_TOOLBAR_RESTORE_KEY = '_sdToolbarRestoreHandler'
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cjm_transcript_segment_align-0.0.17.tar.gz.
File metadata
- Download URL: cjm_transcript_segment_align-0.0.17.tar.gz
- Upload date:
- Size: 57.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3a85361fad9e855891904b62c2a1e5cd64a020b67fdb007b23e5627f238266e4
|
|
| MD5 |
7e1cc88848f06df19cb13aca5fa082a4
|
|
| BLAKE2b-256 |
bcbc6d0904be05bf0e838dba84ab399afe9c911165196304c000bb681be3b6e2
|
File details
Details for the file cjm_transcript_segment_align-0.0.17-py3-none-any.whl.
File metadata
- Download URL: cjm_transcript_segment_align-0.0.17-py3-none-any.whl
- Upload date:
- Size: 52.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
48ed9b378cc1e578814f220af9266b3a2c4dfa963039d1261b68b32f5772e428
|
|
| MD5 |
6b9550ccc7925a97399bf3640d0623fc
|
|
| BLAKE2b-256 |
295ba4c8d950ab870706d621df71c63f0e49f6ef9ebac67560f8be0fc4a8946e
|