Upload files to "docs"

This commit is contained in:
Moto 2025-09-29 22:43:04 -05:00
parent 4587ab01b3
commit 2d543fe68c
5 changed files with 842 additions and 0 deletions

223
docs/api.md Normal file
View file

@ -0,0 +1,223 @@
# 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

161
docs/architecture.md Normal file
View file

@ -0,0 +1,161 @@
# Project Architecture
This document describes the architecture and structure of the GemReader application.
## Overview
GemReader is a terminal-based markdown viewer built with Go using the Bubble Tea framework for the terminal user interface. The application reads markdown files, renders them for terminal display, and provides navigation capabilities.
## Architecture Pattern
The application follows a modular architecture with clear separation of concerns:
- **Presentation Layer**: Bubble Tea-based TUI in the `tui` package
- **Business Logic**: Navigation and content handling in the `tui` package
- **Configuration**: Viper-based configuration loading in the `config` package
- **Entry Point**: Command-line interface in the `main` package
## Package Structure
### `cmd/gemreader/main.go`
The main entry point of the application that:
- Defines the command-line interface using Cobra
- Handles command-line argument validation
- Reads the markdown file specified by the user
- Loads application configuration
- Initializes and runs the TUI
### `internal/config/config.go`
Configuration management that:
- Defines the application configuration structure
- Loads configuration from config.toml using Viper
- Provides configuration data to other parts of the application
- Handles configuration loading errors gracefully
### `internal/tui/tui.go`
Terminal user interface implementation that:
- Implements the Bubble Tea model for TUI functionality
- Handles all user interactions and navigation
- Manages dual-pane interface (TOC and content)
- Renders content for terminal display using viewports
- Generates and manages table of contents from markdown headers
- Provides pane switching functionality
## Design Patterns
### Model-View-Update (MVU) Pattern
The TUI uses the Bubble Tea framework which implements the MVU pattern:
- **Model**: The state of the application (model struct)
- **Update**: Functions that modify the state based on messages (keyboard input, etc.)
- **View**: Function that renders the current state to the terminal
### Viewport Pattern
The TUI uses dual viewports for the split-screen interface:
- **TOC Viewport**: Dedicated scrolling region for table of contents
- **Content Viewport**: Dedicated scrolling region for markdown content
- Both viewports are managed by the Bubble Tea framework
### Dependency Management
The application uses Go modules for dependency management with the following key dependencies:
- `github.com/charmbracelet/bubbletea`: TUI framework
- `github.com/charmbracelet/lipgloss`: Styling library for terminal interfaces
- `github.com/charmbracelet/bubbles/viewport`: Viewport component for scrolling
- `github.com/spf13/cobra`: Command-line interface framework
- `github.com/spf13/viper`: Configuration management
- `github.com/MichaelMure/go-term-markdown`: Markdown rendering for terminals
## Data Flow
1. **Initialization**: `main.go` parses command-line arguments and loads configuration
2. **Content Loading**: Markdown file is read and rendered for terminal display
3. **Model Creation**: TUI model is created with content and configuration
4. **Event Loop**: Bubble Tea enters event loop handling user input
5. **State Updates**: User actions update the model state via the Update method
6. **Rendering**: Changes to model trigger View method to refresh display
## File Organization
```
gemreader/
├── cmd/
│ └── gemreader/
│ └── main.go # Application entry point
├── internal/
│ ├── config/
│ │ └── config.go # Configuration loading
│ └── tui/
│ └── tui.go # Terminal user interface
├── docs/ # Documentation files
│ ├── configuration.md
│ ├── navigation.md
│ ├── api.md
│ └── architecture.md
├── config.toml # Default configuration
├── sample.md # Sample markdown file
├── go.mod # Go module file
├── go.sum # Go module checksums
├── README.md # Main documentation file
└── CONTRIBUTING.md # Contribution guide
```
## Component Responsibilities
### Main Component
- Command-line argument parsing and validation
- File loading and error handling
- Configuration loading
- TUI initialization and execution
### Config Component
- Loading configuration from TOML file
- Providing configuration to other components
- Handling configuration errors gracefully
### TUI Component
- Managing application state
- Handling user input and navigation
- Rendering the dual-pane interface
- Managing pane switching between TOC and content
- Content display and positioning using viewports
- Generating and displaying table of contents
## Security Considerations
- The application only reads files specified by the user
- No network connections are made during normal operation
- Configuration loading is restricted to local files
- Input validation is handled by the underlying libraries
## Performance Characteristics
- Content is loaded entirely into memory at startup
- Navigation operations are performed in memory without file access
- Markdown rendering happens once at startup
- TOC generation happens once at startup
- Dual viewport system provides efficient scrolling in both panes
## Extensibility Points
The architecture supports extension through:
- Configuration options (new fields in Config struct)
- Enhanced dual-pane functionality
- Additional keyboard controls (in Update method)
- New content processing features (in TUI package)
- Enhanced viewport behaviors and styling
- Additional TOC features and navigation options

353
docs/building.md Normal file
View file

@ -0,0 +1,353 @@
# Building GemReader
This document provides detailed instructions on how to build the GemReader application for different platforms, with a focus on creating executable files (especially .exe files for Windows).
## Prerequisites
Before building GemReader, ensure you have the following installed:
- Go 1.24 or higher
- Git (for cloning the repository)
- A terminal/command prompt
- For Windows: A modern version of Windows that supports Go compilation
## Building for Windows (.exe)
### Basic Build
To build the application for Windows and create an .exe file, run the following command:
```bash
go build -o gemreader.exe cmd/gemreader/main.go
```
This will create a `gemreader.exe` file in your current directory.
### Cross-compilation from Other Platforms
If you're building from a non-Windows platform (Linux or macOS) and want to create a Windows executable, use these commands:
```bash
GOOS=windows GOARCH=amd64 go build -o gemreader.exe cmd/gemreader/main.go
```
### Advanced Build Options
#### Building with release flags (optimized)
For a more optimized build with smaller file size:
```bash
go build -ldflags "-s -w" -o gemreader.exe cmd/gemreader/main.go
```
- `-s`: Omit the symbol table and debug information
- `-w`: Omit the DWARF symbol table
#### Building with version information
To embed version information in the executable:
```bash
go build -ldflags "-X main.Version=1.0.0 -s -w" -o gemreader.exe cmd/gemreader/main.go
```
## Building for Other Platforms
This section covers building the application on Windows for other operating systems using Go's cross-compilation feature.
### From Windows to Linux
To build for Linux from a Windows machine, you have several options:
**Option 1: Using PowerShell (Recommended)**
```powershell
# For 64-bit Linux
$env:GOOS="linux"; $env:GOARCH="amd64"; go build -o gemreader-linux cmd/gemreader/main.go
# For 32-bit Linux
$env:GOOS="linux"; $env:GOARCH="386"; go build -o gemreader-linux-386 cmd/gemreader/main.go
# For ARM64 Linux
$env:GOOS="linux"; $env:GOARCH="arm64"; go build -o gemreader-linux-arm64 cmd/gemreader/main.go
```
**Option 2: Using Command Prompt (CMD)**
In Command Prompt, you need to set the environment variables persistently for the session:
```batch
go env -w GOOS=linux
go env -w GOARCH=amd64
go build -o gemreader-linux cmd/gemreader/main.go
# Reset to default after building
go env -w GOOS=windows
go env -w GOARCH=amd64
```
**Option 3: Temporary environment variables in PowerShell (One-liner)**
```powershell
$env:GOOS="linux"; $env:GOARCH="amd64"; go build -o gemreader-linux cmd/gemreader/main.go; $env:GOOS="windows"; $env:GOARCH="amd64"
```
### From Windows to macOS
To build for macOS from a Windows machine:
**Using PowerShell:**
```powershell
# For Intel-based Macs
$env:GOOS="darwin"; $env:GOARCH="amd64"; go build -o gemreader-mac cmd/gemreader/main.go
# For Apple Silicon Macs (M1/M2/M3)
$env:GOOS="darwin"; $env:GOARCH="arm64"; go build -o gemreader-mac-arm64 cmd/gemreader/main.go
```
**Using Command Prompt:**
```batch
go env -w GOOS=darwin
go env -w GOARCH=amd64
go build -o gemreader-mac cmd/gemreader/main.go
# Reset to default after building
go env -w GOOS=windows
go env -w GOARCH=amd64
```
### Using PowerShell
If you're using PowerShell instead of Command Prompt, the syntax is slightly different:
```powershell
# For Linux ARM64
$env:GOOS="linux"; $env:GOARCH="arm64"; go build -o gemreader-linux-arm64 cmd/gemreader/main.go
# For macOS
$env:GOOS="darwin"; $env:GOARCH="arm64"; go build -o gemreader-mac-arm64 cmd/gemreader/main.go
```
### Common GOOS and GOARCH Values
| GOOS | GOARCH | Platform |
| ------- | ------ | ---------------------------- |
| windows | amd64 | 64-bit Windows |
| windows | 386 | 32-bit Windows |
| windows | arm64 | 64-bit Windows on ARM |
| linux | amd64 | 64-bit Linux |
| linux | 386 | 32-bit Linux |
| linux | arm64 | 64-bit Linux on ARM |
| darwin | amd64 | 64-bit macOS (Intel) |
| darwin | arm64 | 64-bit macOS (Apple Silicon) |
### Building for Multiple Platforms
You can create a batch script to build for multiple platforms at once. Here's an example `build-all.bat`:
```batch
@echo off
echo Building GemReader for multiple platforms...
REM Create dist directory if it doesn't exist
if not exist dist mkdir dist
echo Building for Windows (64-bit)...
go env -w GOOS=windows
go env -w GOARCH=amd64
go build -ldflags "-s -w" -o dist/gemreader-windows-amd64.exe cmd/gemreader/main.go
echo Building for Linux (64-bit)...
go env -w GOOS=linux
go env -w GOARCH=amd64
go build -ldflags "-s -w" -o dist/gemreader-linux-amd64 cmd/gemreader/main.go
echo Building for macOS (Intel)...
go env -w GOOS=darwin
go env -w GOARCH=amd64
go build -ldflags "-s -w" -o dist/gemreader-darwin-amd64 cmd/gemreader/main.go
echo Building for macOS (Apple Silicon)...
go env -w GOOS=darwin
go env -w GOARCH=arm64
go build -ldflags "-s -w" -o dist/gemreader-darwin-arm64 cmd/gemreader/main.go
echo Resetting GOOS and GOARCH to default...
go env -w GOOS=windows
go env -w GOARCH=amd64
echo Build process completed!
pause
```
Alternatively, you can create a PowerShell script `build-all.ps1` for more reliable cross-platform building:
```powershell
Write-Host "Building GemReader for multiple platforms..."
# Create dist directory if it doesn't exist
if (!(Test-Path dist)) {
New-Item -ItemType Directory -Path dist
}
# Build for Windows
Write-Host "Building for Windows (64-bit)..."
$env:GOOS="windows"
$env:GOARCH="amd64"
go build -ldflags "-s -w" -o dist/gemreader-windows-amd64.exe cmd/gemreader/main.go
# Build for Linux
Write-Host "Building for Linux (64-bit)..."
$env:GOOS="linux"
$env:GOARCH="amd64"
go build -ldflags "-s -w" -o dist/gemreader-linux-amd64 cmd/gemreader/main.go
# Build for macOS Intel
Write-Host "Building for macOS (Intel)..."
$env:GOOS="darwin"
$env:GOARCH="amd64"
go build -ldflags "-s -w" -o dist/gemreader-darwin-amd64 cmd/gemreader/main.go
# Build for macOS Apple Silicon
Write-Host "Building for macOS (Apple Silicon)..."
$env:GOOS="darwin"
$env:GOARCH="arm64"
go build -ldflags "-s -w" -o dist/gemreader-darwin-arm64 cmd/gemreader/main.go
Write-Host "Build process completed!"
```
## Using Build Scripts
For more complex builds, you can create a build script. Here's an example `build.bat` for Windows:
```batch
@echo off
echo Building GemReader for Windows...
REM Build the application
go build -ldflags "-s -w" -o gemreader.exe cmd/gemreader/main.go
if %ERRORLEVEL% == 0 (
echo Build successful! gemreader.exe has been created.
) else (
echo Build failed!
exit /b %ERRORLEVEL%
)
```
And a `build.sh` script for Unix-like systems:
```bash
#!/bin/bash
echo "Building GemReader..."
# Build the application
go build -ldflags "-s -w" -o gemreader cmd/gemreader/main.go
if [ $? -eq 0 ]; then
echo "Build successful! gemreader has been created."
else
echo "Build failed!"
exit 1
fi
```
## Build Targets with Go Releaser (Alternative Approach)
If the project uses GoReleaser or similar tools, you can use:
```bash
# Install GoReleaser if not already installed
go install github.com/goreleaser/goreleaser@latest
# Build all targets defined in .goreleaser.yml
goreleaser build --single-target --snapshot
```
## Troubleshooting Build Issues
### Common Issues
#### Missing Dependencies
If you encounter dependency issues, run:
```bash
go mod tidy
```
This will ensure all dependencies are downloaded and the go.mod file is updated.
#### CGO Issues
If your build fails due to CGO issues (uncommon for this project), you can disable CGO:
```bash
CGO_ENABLED=0 go build -o gemreader.exe cmd/gemreader/main.go
```
#### Large Executable Size
If the resulting executable is too large, consider these options:
1. Use the `-ldflags "-s -w"` options as mentioned above
2. Use UPX to compress the executable (third-party tool):
```bash
upx --best gemreader.exe
```
### Checking Build Information
To verify your build information, you can use:
```bash
go version -m gemreader.exe
```
This will show build information about the executable.
## Production Builds
For production releases, consider using these flags to create a minimal executable:
```bash
go build \
-ldflags="-s -w -X main.Version=1.0.0" \
-o gemreader.exe \
cmd/gemreader/main.go
```
## Verifying the Build
After building, you can test your executable by running:
```bash
# On Windows
.\gemreader.exe sample.md
# Or with a different markdown file
.\gemreader.exe path\to\your\markdown\file.md
```
## Build Artifacts
The build process will create:
- `gemreader.exe` (or platform-specific executable)
- The executable is self-contained and doesn't require additional files to run
- Configuration files like `config.toml` and `sample.md` can be distributed separately if needed
## Creating an Installer (Optional)
For distribution purposes, you may want to create an installer for Windows using tools like:
- NSIS (Nullsoft Scriptable Install System)
- Inno Setup
- GoReleaser with nfpm for cross-platform packaging
This is outside the scope of this document but worth considering for production releases.

63
docs/configuration.md Normal file
View file

@ -0,0 +1,63 @@
# Configuration Guide
GemReader uses a TOML-based configuration file to customize the application behavior. The configuration file is named `config.toml` and should be placed in the same directory where you run the application.
## Default Configuration File
The default `config.toml` file looks like this:
```toml
title = "GemReader"
```
## Available Configuration Options
### title
- **Type**: String
- **Default**: "GemReader"
- **Description**: Sets the title displayed at the top of the application interface
### default_file
- **Type**: String
- **Default**: "" (empty)
- **Description**: Sets the default markdown file to open when no file is provided as a command-line argument
## Configuration Loading
The application attempts to load the configuration file when it starts. If the file is not found or contains errors, the application will continue to run with default settings.
The configuration is loaded using the [Viper](https://github.com/spf13/viper) library, which supports:
1. Loading from `config.toml` in the current directory
2. Environment variable overrides (with `GEMREADER_` prefix)
3. Default fallback values
## Example Advanced Configuration
While the current version only supports the title configuration, future versions may support additional options:
```toml
title = "My Markdown Viewer"
# These options are planned for future releases:
# theme = "dark" # Color theme (dark/light)
# toc_enabled = true # Whether to generate table of contents
# line_numbers = false # Show line numbers
# wrap_text = true # Wrap long lines
```
## Troubleshooting
### Configuration File Not Found
If the application starts but the custom title isn't displayed, ensure that:
1. The `config.toml` file exists in the current working directory
2. The file has the correct format and valid TOML syntax
3. The application has read permissions for the file
### Invalid Configuration
If the configuration file contains invalid TOML syntax, the application will log an error and use default values instead.

42
docs/index.md Normal file
View file

@ -0,0 +1,42 @@
# GemReader Documentation
Welcome to the GemReader documentation. This collection of documents provides comprehensive information about the application.
## Table of Contents
### Getting Started
- [README](../README.md) - Main project overview, installation, and usage
- [Configuration Guide](configuration.md) - How to configure the application
### User Guides
- [Navigation & Controls](navigation.md) - Detailed keyboard controls and navigation
### Development & Building
- [Building Guide](building.md) - Instructions for building the application for different platforms
### Technical Documentation
- [API Documentation](api.md) - Internal API and code structure
- [Architecture](architecture.md) - Project architecture and design patterns
### Contributing
- [Contribution Guide](../CONTRIBUTING.md) - How to contribute to the project
## Quick Links
- [Report an Issue](https://github.com/your-repo/gemreader/issues)
- [Source Code](https://github.com/your-repo/gemreader)
- [Go Documentation](https://pkg.go.dev/gemreader)
## Need Help?
If you can't find what you're looking for in these documents:
1. Check the [README](../README.md) for basic usage information
2. Review the [Navigation Guide](navigation.md) for help with controls
3. Look at the [Building Guide](building.md) for compilation instructions
4. Open an issue in the GitHub repository