224 lines
5.3 KiB
Markdown
224 lines
5.3 KiB
Markdown
|
|
# 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
|