# API Documentation This document provides detailed documentation for the GemReader application's internal APIs and code structure. ## Package Structure - `main` (cmd/gemreader/main.go): Application entry point and command-line interface - `config` (internal/config/config.go): Configuration loading and management - `tui` (internal/tui/tui.go): Terminal user interface implementation ## Main Package ### main.go #### Execute() function ```go func Execute() ``` - Initializes and executes the Cobra command - Handles command execution errors - Exits the application with appropriate error code if execution fails #### rootCmd variable ```go var rootCmd = &cobra.Command ``` - Main Cobra command for the application - Uses format: `gemreader [file]` - Allows 0 or 1 arguments (the markdown file to view) - Handles file reading and TUI initialization - If no file is provided, attempts to use the default file from config #### validateFilePath() function ```go func validateFilePath(inputPath string) (string, error) ``` - Validates file paths to prevent directory traversal attacks - Cleans and resolves absolute paths - Ensures the resolved path is within the current working directory - Returns error if path traversal is detected #### validateFile() function ```go func validateFile(filePath string) error ``` - Performs security checks on files before loading - Validates file size (max 10MB) - Ensures file is a supported type (.md, .markdown, .txt, or no extension) ## Config Package ### config.go #### Config struct ```go type Config struct { Title string `mapstructure:"title"` DefaultFile string `mapstructure:"default_file"` ShowTOC bool `mapstructure:"show_toc"` } ``` - Stores application configuration - Supports Title, DefaultFile, and ShowTOC fields - Tagged for Viper configuration mapping #### LoadConfig() function ```go func LoadConfig() (config Config, err error) ``` - Loads configuration from config.toml file - Searches for config file in current directory - Supports TOML format - Returns Config struct and error if any - Uses Viper for configuration management - Returns defaults if config file doesn't exist ## TUI Package ### tui.go #### model struct ```go type model struct { content string rawLines []string toc []tocEntry selectedTocIndex int tocViewport viewport.Model contentViewport viewport.Model activePane pane helpVisible bool config config.Config windowWidth int windowHeight int } ``` The model struct contains all state information for the TUI: - `content`: Original markdown content as string - `rawLines`: Original content split by newlines for TOC generation - `toc`: Table of contents entries - `selectedTocIndex`: Index of currently selected TOC entry - `tocViewport`: Bubble Tea viewport for TOC pane - `contentViewport`: Bubble Tea viewport for content pane - `activePane`: Currently active pane (TOC or content) - `helpVisible`: Whether help text is visible - `config`: Application configuration - `windowWidth`, `windowHeight`: Terminal dimensions #### pane type ```go type pane int const ( tocPane pane = iota contentPane ) ``` - Represents the two panes in the UI - `tocPane`: Left pane showing table of contents - `contentPane`: Right pane showing markdown content #### tocEntry struct ```go type tocEntry struct { level int text string line int } ``` - Represents a single entry in the table of contents - `level`: Header level (1 for #, 2 for ##, etc.) - `text`: Text content of the header - `line`: Line number in the original document #### NewModel() function ```go func NewModel(content string, cfg config.Config) model ``` - Creates a new TUI model with the given content and configuration - Splits content into lines for TOC generation - Generates table of contents from headers - Initializes viewport models - Sets up initial state with content pane as active #### generateTOC() function ```go func generateTOC(lines []string) []tocEntry ``` - Scans content lines for markdown headers - Creates tocEntry for each header found - Determines header level based on number of # characters - Returns list of all headers in document order #### (m model) Init() method ```go func (m model) Init() tea.Cmd ``` - Bubble Tea initialization method - Returns nil command (no initial command needed) #### (m model) Update() method ```go func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) ``` - Bubble Tea update method for handling messages and user input - Handles window resize events and recalculates pane dimensions - Processes keyboard input for navigation - Switches between TOC and content panes with Tab key - Handles TOC navigation and jumping to selected entries - Updates both viewport models - Supports all navigation commands #### (m model) View() method ```go func (m model) View() string ``` - Bubble Tea view method for rendering the UI - Applies styles to active and inactive panes - Renders both TOC and content panes side by side - Shows help text at the bottom if visible - Returns string representation of current UI state #### (m model) renderTOC() method ```go func (m model) renderTOC() string ``` - Renders the table of contents view - Shows headers with proper indentation based on level - Highlights the currently selected entry with '>' - Shows "No table of contents found." if no headers exist