v0.2.1 release
This commit is contained in:
228
.github/workflows/release.yml
vendored
Normal file
228
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,228 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build-and-release:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Extract version from tag or FlexLove.lua
|
||||
id: version
|
||||
run: |
|
||||
if [[ "$GITHUB_REF" == refs/tags/v* ]]; then
|
||||
VERSION=${GITHUB_REF#refs/tags/v}
|
||||
echo "Triggered by tag: $GITHUB_REF_NAME"
|
||||
else
|
||||
VERSION=$(grep -m 1 "_VERSION" FlexLove.lua | sed -E 's/.*"([^"]+)".*/\1/')
|
||||
echo "Triggered manually, using FlexLove.lua version"
|
||||
fi
|
||||
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
echo "tag=v${VERSION}" >> $GITHUB_OUTPUT
|
||||
|
||||
FLEX_VERSION=$(grep -m 1 "_VERSION" FlexLove.lua | sed -E 's/.*"([^"]+)".*/\1/')
|
||||
echo "FlexLove.lua version: $FLEX_VERSION"
|
||||
echo "Release version: $VERSION"
|
||||
|
||||
if [ "$FLEX_VERSION" != "$VERSION" ]; then
|
||||
echo "⚠️ Warning: Version mismatch detected"
|
||||
echo " FlexLove.lua: $FLEX_VERSION"
|
||||
echo " Release version: $VERSION"
|
||||
echo " Using: $VERSION"
|
||||
else
|
||||
echo "✓ Version check passed"
|
||||
fi
|
||||
|
||||
- name: Install lua-language-server
|
||||
run: |
|
||||
LLS_VERSION="3.7.4"
|
||||
wget -q "https://github.com/LuaLS/lua-language-server/releases/download/${LLS_VERSION}/lua-language-server-${LLS_VERSION}-linux-x64.tar.gz"
|
||||
mkdir -p ~/.local/bin/lua-language-server
|
||||
tar -xzf "lua-language-server-${LLS_VERSION}-linux-x64.tar.gz" -C ~/.local/bin/lua-language-server
|
||||
echo "$HOME/.local/bin/lua-language-server/bin" >> $GITHUB_PATH
|
||||
rm "lua-language-server-${LLS_VERSION}-linux-x64.tar.gz"
|
||||
|
||||
- name: Verify lua-language-server installation
|
||||
run: |
|
||||
lua-language-server --version
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '18'
|
||||
cache: 'npm'
|
||||
cache-dependency-path: docs/package.json
|
||||
|
||||
- name: Install Node.js dependencies
|
||||
working-directory: docs
|
||||
run: npm ci
|
||||
|
||||
- name: Make scripts executable
|
||||
run: |
|
||||
chmod +x scripts/generate_docs.sh
|
||||
chmod +x scripts/create-release.sh
|
||||
chmod +x scripts/archive-docs.sh
|
||||
|
||||
- name: Archive previous documentation version
|
||||
run: |
|
||||
if [ -f "docs/api.html" ]; then
|
||||
OLD_VERSION=$(grep -o 'FlexLöve v[0-9.]*' docs/api.html | head -1 | sed 's/FlexLöve v//')
|
||||
if [ -n "$OLD_VERSION" ]; then
|
||||
echo "Found previous version: v${OLD_VERSION}"
|
||||
mkdir -p "docs/versions/v${OLD_VERSION}"
|
||||
cp docs/api.html "docs/versions/v${OLD_VERSION}/api.html"
|
||||
echo "✓ Archived previous documentation to docs/versions/v${OLD_VERSION}/"
|
||||
else
|
||||
echo "No previous version found, skipping archival"
|
||||
fi
|
||||
else
|
||||
echo "No existing documentation to archive"
|
||||
fi
|
||||
|
||||
- name: Generate documentation
|
||||
run: |
|
||||
./scripts/generate_docs.sh
|
||||
# Verify api.html was created
|
||||
if [ ! -f "docs/api.html" ]; then
|
||||
echo "Error: docs/api.html was not generated"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ Documentation generated successfully"
|
||||
|
||||
- name: Commit archived documentation
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git add docs/versions/ docs/api.html docs/doc.json docs/doc.md
|
||||
git commit -m "Archive previous documentation and generate v${{ steps.version.outputs.version }} docs [skip ci]" || echo "No changes to commit"
|
||||
git push origin HEAD:main || echo "Nothing to push"
|
||||
|
||||
- name: Create release package
|
||||
run: |
|
||||
# Run release script non-interactively (auto-confirm overwrite)
|
||||
echo "y" | ./scripts/create-release.sh || ./scripts/create-release.sh
|
||||
# Verify files were created
|
||||
VERSION="${{ steps.version.outputs.version }}"
|
||||
if [ ! -f "releases/flexlove-v${VERSION}.zip" ]; then
|
||||
echo "Error: Release zip was not created"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -f "releases/flexlove-v${VERSION}.zip.sha256" ]; then
|
||||
echo "Error: Checksum file was not created"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ Release package created successfully"
|
||||
|
||||
- name: Upload release artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: release-assets
|
||||
path: |
|
||||
releases/flexlove-v${{ steps.version.outputs.version }}.zip
|
||||
releases/flexlove-v${{ steps.version.outputs.version }}.zip.sha256
|
||||
docs/api.html
|
||||
retention-days: 90
|
||||
|
||||
- name: Download release artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: release-assets
|
||||
path: ./
|
||||
|
||||
- name: Extract checksum for release notes
|
||||
id: checksum
|
||||
run: |
|
||||
VERSION="${{ steps.version.outputs.version }}"
|
||||
CHECKSUM=$(cat "releases/flexlove-v${VERSION}.zip.sha256" | cut -d ' ' -f 1)
|
||||
echo "checksum=$CHECKSUM" >> $GITHUB_OUTPUT
|
||||
echo "Checksum: $CHECKSUM"
|
||||
|
||||
- name: Check if pre-release
|
||||
id: prerelease
|
||||
run: |
|
||||
VERSION="${{ steps.version.outputs.version }}"
|
||||
if [[ "$VERSION" =~ (alpha|beta|rc|dev) ]]; then
|
||||
echo "is_prerelease=true" >> $GITHUB_OUTPUT
|
||||
echo "This is a pre-release version"
|
||||
else
|
||||
echo "is_prerelease=false" >> $GITHUB_OUTPUT
|
||||
echo "This is a stable release"
|
||||
fi
|
||||
|
||||
- name: Generate release notes
|
||||
id: release_notes
|
||||
run: |
|
||||
VERSION="${{ steps.version.outputs.version }}"
|
||||
CHECKSUM="${{ steps.checksum.outputs.checksum }}"
|
||||
cat > release_notes.md << 'EOF'
|
||||
## Installation
|
||||
|
||||
Download `flexlove-v${{ steps.version.outputs.version }}.zip` and extract to your LÖVE2D project:
|
||||
|
||||
```bash
|
||||
unzip flexlove-v${{ steps.version.outputs.version }}.zip
|
||||
cp -r flexlove/modules ./
|
||||
cp flexlove/FlexLove.lua ./
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
Verify the download integrity using SHA256:
|
||||
|
||||
```bash
|
||||
shasum -a 256 -c flexlove-v${{ steps.version.outputs.version }}.zip.sha256
|
||||
```
|
||||
|
||||
**SHA256 Checksum:**
|
||||
```
|
||||
${{ steps.checksum.outputs.checksum }}
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
📚 [View Documentation](https://github.com/${{ github.repository }}/tree/main/docs)
|
||||
|
||||
## What's Included
|
||||
|
||||
- `FlexLove.lua` - Main library file
|
||||
- `modules/` - All required module files (27 files)
|
||||
- `LICENSE` - MIT License
|
||||
- `README.txt` - Installation instructions
|
||||
|
||||
## Requirements
|
||||
|
||||
- LÖVE2D 11.0 or higher
|
||||
|
||||
---
|
||||
|
||||
_For examples and full source code, visit the [repository](https://github.com/${{ github.repository }})._
|
||||
EOF
|
||||
cat release_notes.md
|
||||
|
||||
- name: Create GitHub Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
tag_name: v${{ steps.version.outputs.version }}
|
||||
name: FlexLöve v${{ steps.version.outputs.version }}
|
||||
body_path: release_notes.md
|
||||
files: |
|
||||
releases/flexlove-v${{ steps.version.outputs.version }}.zip
|
||||
releases/flexlove-v${{ steps.version.outputs.version }}.zip.sha256
|
||||
prerelease: ${{ steps.prerelease.outputs.is_prerelease }}
|
||||
draft: false
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -8,3 +8,7 @@ themes/space/
|
||||
tasks
|
||||
testoutput
|
||||
luacov.*
|
||||
docs/doc.json
|
||||
docs/doc.md
|
||||
docs/node_modules
|
||||
releases/
|
||||
|
||||
@@ -63,8 +63,8 @@ Units.initialize(Context)
|
||||
Units.initializeErrorHandler(ErrorHandler)
|
||||
|
||||
-- Add version and metadata
|
||||
flexlove._VERSION = "0.2.0"
|
||||
flexlove._DESCRIPTION = "UI Library for LÖVE Framework based on flexbox"
|
||||
flexlove._VERSION = "0.2.1"
|
||||
flexlove._DESCRIPTION = "0I Library for LÖVE Framework based on flexbox"
|
||||
flexlove._URL = "https://github.com/mikefreno/FlexLove"
|
||||
flexlove._LICENSE = [[
|
||||
MIT License
|
||||
|
||||
21
README.md
21
README.md
@@ -1,4 +1,4 @@
|
||||
# FlexLöve v0.2.0
|
||||
# FlexLöve v0.2.1
|
||||
|
||||
**A comprehensive UI library providing flexbox/grid layouts, theming, animations, and event handling for LÖVE2D games.**
|
||||
|
||||
@@ -67,6 +67,25 @@ function love.draw()
|
||||
end
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
📚 **[View Full API Documentation](https://mikefreno.github.io/FlexLove/api.html)**
|
||||
|
||||
Complete API reference with all classes, methods, and properties is available on GitHub Pages. The documentation includes:
|
||||
|
||||
- Searchable sidebar navigation
|
||||
- Syntax-highlighted code examples
|
||||
- Version selector (access docs for previous versions)
|
||||
- Detailed parameter and return value descriptions
|
||||
|
||||
### Documentation Versions
|
||||
|
||||
Access documentation for specific versions:
|
||||
- **Latest:** [https://mikefreno.github.io/FlexLove/api.html](https://mikefreno.github.io/FlexLove/api.html)
|
||||
- **Specific version:** `https://mikefreno.github.io/FlexLove/versions/v0.2.0/api.html`
|
||||
|
||||
Use the version dropdown in the documentation header to switch between versions.
|
||||
|
||||
## API Conventions
|
||||
|
||||
### Method Patterns
|
||||
|
||||
209
RELEASE.md
Normal file
209
RELEASE.md
Normal file
@@ -0,0 +1,209 @@
|
||||
# FlexLöve Release Process
|
||||
|
||||
This document describes how to create and publish a new release of FlexLöve.
|
||||
|
||||
## Automated Release (Recommended)
|
||||
|
||||
The easiest way to create a release is using the automated script:
|
||||
|
||||
```bash
|
||||
./scripts/make-tag.sh
|
||||
```
|
||||
|
||||
This interactive script will:
|
||||
1. Show your current version
|
||||
2. Ask you to select: Major / Minor / Patch / Custom version bump
|
||||
3. Calculate the new version (resetting lower components to 0)
|
||||
4. Update `FlexLove.lua` with the new version
|
||||
5. Update `README.md` first line with the new version
|
||||
6. Create a git commit: `v{version} release`
|
||||
7. Create a git tag: `v{version}`
|
||||
8. Prompt you to push the changes
|
||||
|
||||
After pushing the tag, GitHub Actions automatically:
|
||||
- Archives previous documentation
|
||||
- Generates new documentation
|
||||
- Creates release package with SHA256 checksums
|
||||
- Publishes GitHub release with download assets
|
||||
|
||||
### Example Usage
|
||||
|
||||
```bash
|
||||
$ ./scripts/make-tag.sh
|
||||
|
||||
═══════════════════════════════════════
|
||||
FlexLöve Version Bump & Tag Tool
|
||||
═══════════════════════════════════════
|
||||
|
||||
Current version: v0.2.0
|
||||
|
||||
Select version bump type:
|
||||
1) Major (breaking changes) 0.2.0 → 1.0.0
|
||||
2) Minor (new features) 0.2.0 → 0.3.0
|
||||
3) Patch (bug fixes) 0.2.0 → 0.2.1
|
||||
4) Custom version
|
||||
5) Cancel
|
||||
|
||||
Enter choice (1-5): 2
|
||||
|
||||
New version: v0.3.0
|
||||
|
||||
This will:
|
||||
1. Update FlexLove.lua → flexlove._VERSION = "0.3.0"
|
||||
2. Update README.md → first line version
|
||||
3. Stage changes for commit
|
||||
4. Create git tag v0.3.0
|
||||
|
||||
Proceed? (y/n) y
|
||||
|
||||
✓ Version bump complete!
|
||||
|
||||
Next steps:
|
||||
1. Push commit and tag:
|
||||
git push && git push origin v0.3.0
|
||||
|
||||
2. GitHub Actions will automatically:
|
||||
• Archive previous documentation
|
||||
• Generate new documentation
|
||||
• Create release package with checksums
|
||||
• Publish GitHub release
|
||||
```
|
||||
|
||||
## Manual Release Workflow
|
||||
|
||||
If you need more control, follow these steps:
|
||||
|
||||
### 1. Update Version
|
||||
|
||||
Edit `FlexLove.lua` and update the version:
|
||||
|
||||
```lua
|
||||
flexlove._VERSION = "0.3.0" -- Update this line
|
||||
```
|
||||
|
||||
Also update `README.md` first line:
|
||||
```markdown
|
||||
# FlexLöve v0.3.0
|
||||
```
|
||||
|
||||
### 2. Commit and Tag
|
||||
|
||||
```bash
|
||||
git add FlexLove.lua README.md
|
||||
git commit -m "v0.3.0 release"
|
||||
git tag -a v0.3.0 -m "Release version 0.3.0"
|
||||
git push && git push origin v0.3.0
|
||||
```
|
||||
|
||||
### 3. GitHub Actions Takes Over
|
||||
|
||||
Once you push the tag, the automated workflow handles everything else.
|
||||
|
||||
## Local Release Package (Optional)
|
||||
|
||||
To create a local release package without GitHub Actions:
|
||||
|
||||
```bash
|
||||
./scripts/create-release.sh
|
||||
```
|
||||
|
||||
Output files:
|
||||
- `releases/flexlove-v{version}.zip`
|
||||
- `releases/flexlove-v{version}.zip.sha256`
|
||||
|
||||
### Verify Local Package
|
||||
|
||||
```bash
|
||||
cd releases
|
||||
shasum -a 256 -c flexlove-v0.3.0.zip.sha256
|
||||
# Expected: flexlove-v0.3.0.zip: OK
|
||||
```
|
||||
|
||||
## Release Checklist
|
||||
|
||||
- [ ] Version updated in `FlexLove.lua`
|
||||
- [ ] Documentation regenerated (`./scripts/generate_docs.sh`)
|
||||
- [ ] Changes committed and pushed
|
||||
- [ ] Release package created (`./scripts/create-release.sh`)
|
||||
- [ ] Checksum verified (`shasum -a 256 -c *.sha256`)
|
||||
- [ ] Release package tested
|
||||
- [ ] Git tag created and pushed
|
||||
- [ ] GitHub release published with zip and checksum files
|
||||
|
||||
## Versioning
|
||||
|
||||
FlexLöve follows [Semantic Versioning](https://semver.org/):
|
||||
|
||||
- **MAJOR** version: Incompatible API changes
|
||||
- **MINOR** version: New functionality (backwards-compatible)
|
||||
- **PATCH** version: Bug fixes (backwards-compatible)
|
||||
|
||||
Example: `0.2.0` → `0.2.1` (bug fix) or `0.3.0` (new feature)
|
||||
|
||||
## What Gets Released
|
||||
|
||||
The release package includes **only** the files needed to use FlexLöve:
|
||||
|
||||
✅ **Included:**
|
||||
- `FlexLove.lua` - Main library
|
||||
- `modules/` - All module files
|
||||
- `LICENSE` - License terms
|
||||
- `README.txt` - Installation instructions
|
||||
|
||||
❌ **Not included:**
|
||||
- `docs/` - Documentation (hosted on GitHub Pages)
|
||||
- `examples/` - Example code (available in repository)
|
||||
- `testing/` - Test suite
|
||||
- `themes/` - Theme examples
|
||||
- Development tools
|
||||
|
||||
Users who want examples, documentation source, or development tools should clone the full repository.
|
||||
|
||||
## Checksum Verification
|
||||
|
||||
Every release includes a SHA256 checksum file for security verification.
|
||||
|
||||
### For Developers (Creating Release)
|
||||
|
||||
The checksum is automatically generated when running `./scripts/create-release.sh`:
|
||||
|
||||
```bash
|
||||
./scripts/create-release.sh
|
||||
# Creates:
|
||||
# - releases/flexlove-v0.3.0.zip
|
||||
# - releases/flexlove-v0.3.0.zip.sha256
|
||||
|
||||
# Verify before publishing
|
||||
cd releases
|
||||
shasum -a 256 -c flexlove-v0.3.0.zip.sha256
|
||||
# Output: flexlove-v0.3.0.zip: OK
|
||||
```
|
||||
|
||||
### For End Users (Downloading Release)
|
||||
|
||||
After downloading a release from GitHub:
|
||||
|
||||
```bash
|
||||
# Download both files:
|
||||
# - flexlove-v0.3.0.zip
|
||||
# - flexlove-v0.3.0.zip.sha256
|
||||
|
||||
# Verify integrity
|
||||
shasum -a 256 -c flexlove-v0.3.0.zip.sha256
|
||||
|
||||
# If OK, safe to use
|
||||
unzip flexlove-v0.3.0.zip
|
||||
```
|
||||
|
||||
**macOS/Linux:** Use `shasum -a 256 -c`
|
||||
**Windows:** Use `certutil -hashfile flexlove-v0.3.0.zip SHA256` and compare manually
|
||||
|
||||
## Automated Releases (Future)
|
||||
|
||||
Consider adding GitHub Actions workflow to automate:
|
||||
- Version extraction
|
||||
- Release package creation
|
||||
- Documentation deployment
|
||||
- GitHub release creation
|
||||
|
||||
See `.github/workflows/release.yml` (to be created)
|
||||
0
docs/.nojekyll
Normal file
0
docs/.nojekyll
Normal file
@@ -4,23 +4,28 @@ This directory contains auto-generated API documentation from LuaLS annotations.
|
||||
|
||||
## Files
|
||||
|
||||
- **api.html** - Beautiful, searchable API documentation (2.2MB)
|
||||
- **index.html** - GitHub Pages landing page
|
||||
- **doc.md** - Markdown API reference (47,000+ lines)
|
||||
- **doc.json** - JSON API reference for tooling (11MB)
|
||||
- **build-docs.js** - Node.js script to convert markdown to HTML
|
||||
- **package.json** - Node.js dependencies for HTML generation
|
||||
- **.nojekyll** - Tells GitHub Pages to bypass Jekyll processing
|
||||
- **doc.md** - Raw markdown (gitignored, 960KB)
|
||||
- **doc.json** - Raw JSON (gitignored, 11MB)
|
||||
|
||||
## Regenerating Documentation
|
||||
|
||||
To regenerate the documentation after making changes:
|
||||
|
||||
```bash
|
||||
./generate_docs.sh
|
||||
./scripts/generate_docs.sh
|
||||
```
|
||||
|
||||
Or manually:
|
||||
|
||||
```bash
|
||||
lua-language-server --doc=. --doc_out_path=./docs
|
||||
```
|
||||
This will:
|
||||
1. Extract version from `FlexLove.lua` (single source of truth)
|
||||
2. Generate markdown from LuaLS annotations
|
||||
3. Convert to beautiful, searchable HTML with syntax highlighting
|
||||
4. Create navigation sidebar with search functionality
|
||||
5. Display version in page titles and headers
|
||||
|
||||
## Viewing Locally
|
||||
|
||||
@@ -66,4 +71,66 @@ The documentation is generated from LuaLS (Lua Language Server) annotations usin
|
||||
|
||||
## Requirements
|
||||
|
||||
- lua-language-server (install via `brew install lua-language-server` on macOS)
|
||||
- **lua-language-server** - For generating markdown from annotations
|
||||
- macOS: `brew install lua-language-server`
|
||||
- Linux: See https://github.com/LuaLS/lua-language-server
|
||||
|
||||
- **Node.js** - For converting markdown to beautiful HTML
|
||||
- macOS: `brew install node`
|
||||
- Linux: Use your package manager or https://nodejs.org
|
||||
|
||||
## Features
|
||||
|
||||
The generated HTML documentation includes:
|
||||
- 🔍 **Live search** - Find classes and methods instantly
|
||||
- 📱 **Responsive design** - Works on all devices
|
||||
- 🌙 **Dark theme** - Easy on the eyes
|
||||
- 🎨 **Syntax highlighting** - Code examples are beautifully formatted
|
||||
- 🗂️ **Collapsible navigation** - Organized class/method structure
|
||||
- ⚡ **Fast** - Single-page application, no page reloads
|
||||
- 🎯 **Filtered** - Only user-facing classes, no internal implementation
|
||||
- 🏷️ **Versioned** - Auto-displays version from `FlexLove.lua`
|
||||
|
||||
## Customizing Documentation
|
||||
|
||||
Edit `doc-filter.js` to control which classes appear in the documentation:
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
// Whitelist mode: Only these classes will be included
|
||||
include: [
|
||||
'Animation',
|
||||
'Color',
|
||||
'Element',
|
||||
'Theme',
|
||||
// ... add more
|
||||
],
|
||||
|
||||
// Blacklist mode: These classes will be excluded
|
||||
exclude: [
|
||||
'Context',
|
||||
'Performance',
|
||||
// ... add more
|
||||
],
|
||||
|
||||
// Which mode to use
|
||||
mode: 'whitelist' // or 'blacklist'
|
||||
};
|
||||
```
|
||||
|
||||
**Current filter:** Whitelist mode with 20 classes (down from 33)
|
||||
|
||||
## Version Management
|
||||
|
||||
The documentation automatically pulls the version from `FlexLove.lua`:
|
||||
|
||||
```lua
|
||||
flexlove._VERSION = "0.2.0" -- Single source of truth
|
||||
```
|
||||
|
||||
To update the version:
|
||||
1. Change `_VERSION` in `FlexLove.lua`
|
||||
2. Run `./scripts/generate_docs.sh`
|
||||
3. Version appears in page titles, sidebar, and footer
|
||||
|
||||
See `VERSIONING.md` for detailed version management workflow.
|
||||
|
||||
80
docs/VERSIONING.md
Normal file
80
docs/VERSIONING.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# Version Management for FlexLöve Documentation
|
||||
|
||||
The documentation automatically pulls the version from `FlexLove.lua` and displays it throughout the docs.
|
||||
|
||||
## How It Works
|
||||
|
||||
1. **Version Source**: `FlexLove.lua` contains the authoritative version:
|
||||
```lua
|
||||
flexlove._VERSION = "0.2.0"
|
||||
```
|
||||
|
||||
2. **Automatic Detection**: The build script reads this value and injects it into:
|
||||
- Page title: `FlexLöve v0.2.0 - API Reference`
|
||||
- Sidebar header: `FlexLöve v0.2.0`
|
||||
- Landing page: `FlexLöve v0.2.0`
|
||||
|
||||
3. **Single Source of Truth**: Update the version in ONE place (`FlexLove.lua`) and docs auto-update
|
||||
|
||||
## Updating the Version
|
||||
|
||||
### Option 1: Manual Update
|
||||
Edit `FlexLove.lua`:
|
||||
```lua
|
||||
flexlove._VERSION = "0.3.0" -- Change here
|
||||
```
|
||||
|
||||
Then regenerate docs:
|
||||
```bash
|
||||
./scripts/generate_docs.sh
|
||||
```
|
||||
|
||||
### Option 2: Script-Based (Recommended for Releases)
|
||||
Create a release script that:
|
||||
1. Updates version in `FlexLove.lua`
|
||||
2. Regenerates documentation
|
||||
3. Commits changes
|
||||
4. Tags release
|
||||
|
||||
Example `release.sh`:
|
||||
```bash
|
||||
#!/bin/bash
|
||||
NEW_VERSION=$1
|
||||
|
||||
if [ -z "$NEW_VERSION" ]; then
|
||||
echo "Usage: ./release.sh <version>"
|
||||
echo "Example: ./release.sh 0.3.0"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Update version in FlexLove.lua
|
||||
sed -i '' "s/flexlove._VERSION = \".*\"/flexlove._VERSION = \"$NEW_VERSION\"/" FlexLove.lua
|
||||
|
||||
# Regenerate docs
|
||||
./scripts/generate_docs.sh
|
||||
|
||||
# Commit and tag
|
||||
git add FlexLove.lua docs/
|
||||
git commit -m "Release v$NEW_VERSION"
|
||||
git tag "v$NEW_VERSION"
|
||||
|
||||
echo "✓ Released v$NEW_VERSION"
|
||||
echo "Don't forget to: git push && git push --tags"
|
||||
```
|
||||
|
||||
## Version Display Locations
|
||||
|
||||
- **API Reference** (`api.html`):
|
||||
- Browser tab title
|
||||
- Sidebar header (smaller, grayed out)
|
||||
|
||||
- **Landing Page** (`index.html`):
|
||||
- Footer: "FlexLöve v0.2.0 | MIT License"
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
Consider adding:
|
||||
- **CHANGELOG.md** - Track changes between versions
|
||||
- **Version dropdown** - View docs for older versions
|
||||
- **GitHub Releases link** - Link to release notes
|
||||
- **Breaking changes banner** - Warn users about API changes
|
||||
153
docs/WORKFLOW.md
Normal file
153
docs/WORKFLOW.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# Documentation Workflow
|
||||
|
||||
## Overview
|
||||
|
||||
FlexLöve's documentation system automatically manages versioning and archival. When you generate new documentation, the previous version is automatically archived.
|
||||
|
||||
## How It Works
|
||||
|
||||
### 1. Manual Documentation Updates (No Version Change)
|
||||
|
||||
When you update annotations without bumping the version:
|
||||
|
||||
```bash
|
||||
./scripts/generate_docs.sh
|
||||
```
|
||||
|
||||
**What happens:**
|
||||
- Script detects current version (e.g., v0.2.0) from `docs/api.html`
|
||||
- Compares with `FlexLove.lua` version
|
||||
- If versions match: **Overwrites** `docs/api.html` (same version)
|
||||
- Previous archived version remains unchanged
|
||||
|
||||
**Use case:** You added better documentation, fixed typos, or improved examples without releasing a new version.
|
||||
|
||||
### 2. Version Bump (New Release)
|
||||
|
||||
When you bump the version in `FlexLove.lua`:
|
||||
|
||||
```bash
|
||||
# 1. Update version in FlexLove.lua
|
||||
# flexlove._VERSION = "0.3.0"
|
||||
|
||||
# 2. Generate documentation
|
||||
./scripts/generate_docs.sh
|
||||
```
|
||||
|
||||
**What happens:**
|
||||
- Script detects old version (v0.2.0) from `docs/api.html`
|
||||
- Compares with new version (v0.3.0) from `FlexLove.lua`
|
||||
- **Archives** old `docs/api.html` → `docs/versions/v0.2.0/api.html`
|
||||
- Generates new `docs/api.html` for v0.3.0
|
||||
|
||||
### 3. Automated Release (via GitHub Actions)
|
||||
|
||||
When you push a git tag:
|
||||
|
||||
```bash
|
||||
git tag v0.3.0
|
||||
git push origin v0.3.0
|
||||
```
|
||||
|
||||
**What happens:**
|
||||
1. GitHub Actions workflow triggers
|
||||
2. Archives previous documentation version
|
||||
3. Generates new documentation for v0.3.0
|
||||
4. Commits both archived and new docs to repository
|
||||
5. Creates release package with checksums
|
||||
6. Creates GitHub release with assets
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
docs/
|
||||
├── api.html # Always the LATEST version
|
||||
├── index.html # Landing page
|
||||
└── versions/
|
||||
├── v0.1.0/
|
||||
│ └── api.html # Documentation for v0.1.0
|
||||
├── v0.2.0/
|
||||
│ └── api.html # Documentation for v0.2.0
|
||||
└── v0.3.0/
|
||||
└── api.html # Documentation for v0.3.0
|
||||
```
|
||||
|
||||
## Version Detection
|
||||
|
||||
The system automatically detects versions by:
|
||||
1. **Current docs version**: Reads from `docs/api.html` header (`FlexLöve v0.2.0`)
|
||||
2. **Code version**: Reads from `FlexLove.lua` (`flexlove._VERSION = "0.2.0"`)
|
||||
|
||||
### Behavior Matrix
|
||||
|
||||
| Old Version | New Version | Action |
|
||||
|-------------|-------------|--------|
|
||||
| v0.2.0 | v0.2.0 | Overwrite current (same version update) |
|
||||
| v0.2.0 | v0.3.0 | Archive v0.2.0, generate v0.3.0 |
|
||||
| None | v0.2.0 | Generate v0.2.0 (first time) |
|
||||
|
||||
## Examples
|
||||
|
||||
### Scenario 1: Fix Documentation Typo
|
||||
|
||||
```bash
|
||||
# Fix typo in annotations
|
||||
# Version still 0.2.0 in FlexLove.lua
|
||||
|
||||
./scripts/generate_docs.sh
|
||||
# Output: "Same version (v0.2.0), will overwrite current documentation"
|
||||
# Result: docs/api.html updated, no archival
|
||||
```
|
||||
|
||||
### Scenario 2: Release New Version
|
||||
|
||||
```bash
|
||||
# Update FlexLove.lua
|
||||
# flexlove._VERSION = "0.3.0"
|
||||
|
||||
./scripts/generate_docs.sh
|
||||
# Output: "Found previous version v0.2.0, archiving before generating new docs..."
|
||||
# Output: "✓ Archived previous documentation to docs/versions/v0.2.0/"
|
||||
# Result:
|
||||
# - docs/versions/v0.2.0/api.html (archived)
|
||||
# - docs/api.html (new v0.3.0)
|
||||
```
|
||||
|
||||
### Scenario 3: Automated Release
|
||||
|
||||
```bash
|
||||
# Tag and push
|
||||
git tag v0.3.0
|
||||
git push origin v0.3.0
|
||||
|
||||
# GitHub Actions will:
|
||||
# 1. Archive v0.2.0 automatically
|
||||
# 2. Generate v0.3.0 docs
|
||||
# 3. Commit both to repository
|
||||
# 4. Create GitHub release
|
||||
```
|
||||
|
||||
## Benefits
|
||||
|
||||
✅ **No manual archival needed** - Automatically handled
|
||||
✅ **Safe overwrites** - Same version updates won't create duplicate archives
|
||||
✅ **Version history preserved** - All previous versions accessible
|
||||
✅ **Seamless workflow** - Just run `./scripts/generate_docs.sh`
|
||||
✅ **Automated releases** - Tag and forget
|
||||
|
||||
## Version Dropdown
|
||||
|
||||
Users can access any version via the dropdown in the documentation header:
|
||||
- Current version shows "(Latest)" badge
|
||||
- Previous versions listed chronologically
|
||||
- Click to navigate to archived documentation
|
||||
|
||||
## Manual Archival (If Needed)
|
||||
|
||||
If you ever need to manually archive a version:
|
||||
|
||||
```bash
|
||||
./scripts/archive-docs.sh
|
||||
```
|
||||
|
||||
This creates `docs/versions/v{version}/api.html` based on the current `FlexLove.lua` version.
|
||||
3803
docs/api.html
Normal file
3803
docs/api.html
Normal file
File diff suppressed because it is too large
Load Diff
683
docs/build-docs.js
Normal file
683
docs/build-docs.js
Normal file
@@ -0,0 +1,683 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const MarkdownIt = require('markdown-it');
|
||||
const anchor = require('markdown-it-anchor');
|
||||
const hljs = require('highlight.js');
|
||||
const filter = require('./doc-filter');
|
||||
|
||||
// Extract version from FlexLove.lua
|
||||
function getVersion() {
|
||||
try {
|
||||
const flexlovePath = path.join(__dirname, '..', 'FlexLove.lua');
|
||||
const content = fs.readFileSync(flexlovePath, 'utf8');
|
||||
const match = content.match(/flexlove\._VERSION\s*=\s*["']([^"']+)["']/);
|
||||
return match ? match[1] : 'unknown';
|
||||
} catch (e) {
|
||||
return 'unknown';
|
||||
}
|
||||
}
|
||||
|
||||
const VERSION = getVersion();
|
||||
console.log(`Building docs for FlexLöve v${VERSION}`);
|
||||
|
||||
const md = new MarkdownIt({
|
||||
html: true,
|
||||
linkify: true,
|
||||
typographer: true,
|
||||
highlight: function (str, lang) {
|
||||
if (lang && hljs.getLanguage(lang)) {
|
||||
try {
|
||||
return hljs.highlight(str, { language: lang }).value;
|
||||
} catch (__) {}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
}).use(anchor, {
|
||||
permalink: anchor.permalink.headerLink()
|
||||
});
|
||||
|
||||
// Read the markdown file
|
||||
let markdownContent = fs.readFileSync(path.join(__dirname, 'doc.md'), 'utf8');
|
||||
|
||||
// Filter content based on doc-filter.js configuration
|
||||
function filterMarkdown(content) {
|
||||
const lines = content.split('\n');
|
||||
const filtered = [];
|
||||
let currentClass = null;
|
||||
let skipUntilNextClass = false;
|
||||
let classContent = [];
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
const h1Match = line.match(/^# (.+)$/);
|
||||
|
||||
if (h1Match) {
|
||||
// New class found - decide if we should keep previous class
|
||||
if (currentClass && !skipUntilNextClass) {
|
||||
filtered.push(...classContent);
|
||||
}
|
||||
|
||||
currentClass = h1Match[1];
|
||||
classContent = [line];
|
||||
|
||||
// Check if this class should be included
|
||||
if (filter.mode === 'whitelist') {
|
||||
skipUntilNextClass = !filter.include.includes(currentClass);
|
||||
} else {
|
||||
skipUntilNextClass = filter.exclude.includes(currentClass);
|
||||
}
|
||||
} else {
|
||||
classContent.push(line);
|
||||
}
|
||||
}
|
||||
|
||||
// Don't forget the last class
|
||||
if (currentClass && !skipUntilNextClass) {
|
||||
filtered.push(...classContent);
|
||||
}
|
||||
|
||||
return filtered.join('\n');
|
||||
}
|
||||
|
||||
markdownContent = filterMarkdown(markdownContent);
|
||||
|
||||
// Sort properties: public first, then internal (prefixed with _)
|
||||
function sortAndInjectWarning(content) {
|
||||
const lines = content.split('\n');
|
||||
const result = [];
|
||||
let i = 0;
|
||||
|
||||
while (i < lines.length) {
|
||||
const line = lines[i];
|
||||
|
||||
// Check if this is a class heading (h1)
|
||||
if (line.match(/^# .+$/)) {
|
||||
// Found a class, collect all its properties/methods
|
||||
result.push(line);
|
||||
i++;
|
||||
|
||||
const properties = [];
|
||||
let currentProperty = null;
|
||||
|
||||
// Collect all properties until next class or end of file
|
||||
while (i < lines.length && !lines[i].match(/^# .+$/)) {
|
||||
const propLine = lines[i];
|
||||
const h2Match = propLine.match(/^## (.+)$/);
|
||||
|
||||
if (h2Match) {
|
||||
// Save previous property if exists
|
||||
if (currentProperty) {
|
||||
properties.push(currentProperty);
|
||||
}
|
||||
// Start new property
|
||||
currentProperty = {
|
||||
name: h2Match[1],
|
||||
lines: [propLine],
|
||||
isInternal: h2Match[1].startsWith('_')
|
||||
};
|
||||
} else if (currentProperty) {
|
||||
// Add line to current property
|
||||
currentProperty.lines.push(propLine);
|
||||
} else {
|
||||
// Line before any property (e.g., class description)
|
||||
result.push(propLine);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
// Save last property
|
||||
if (currentProperty) {
|
||||
properties.push(currentProperty);
|
||||
}
|
||||
|
||||
// Sort: public first, then internal
|
||||
const publicProps = properties.filter(p => !p.isInternal);
|
||||
const internalProps = properties.filter(p => p.isInternal);
|
||||
|
||||
// Add public properties
|
||||
publicProps.forEach(prop => {
|
||||
result.push(...prop.lines);
|
||||
});
|
||||
|
||||
// Add warning and internal properties if any exist
|
||||
if (internalProps.length > 0) {
|
||||
result.push('');
|
||||
result.push('---');
|
||||
result.push('');
|
||||
result.push('## ⚠️ Internal Properties');
|
||||
result.push('');
|
||||
result.push('> **Warning:** The following properties are internal implementation details and should not be accessed directly. They are prefixed with `_` to indicate they are private. Accessing these properties may break in future versions without notice.');
|
||||
result.push('');
|
||||
result.push('---');
|
||||
result.push('');
|
||||
|
||||
internalProps.forEach(prop => {
|
||||
result.push(...prop.lines);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
result.push(line);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return result.join('\n');
|
||||
}
|
||||
|
||||
markdownContent = sortAndInjectWarning(markdownContent);
|
||||
|
||||
// Parse markdown structure to build navigation
|
||||
const lines = markdownContent.split('\n');
|
||||
const navigation = [];
|
||||
let currentClass = null;
|
||||
|
||||
lines.forEach(line => {
|
||||
const h1Match = line.match(/^# (.+)$/);
|
||||
const h2Match = line.match(/^## (.+)$/);
|
||||
|
||||
if (h1Match) {
|
||||
currentClass = {
|
||||
name: h1Match[1],
|
||||
id: h1Match[1].toLowerCase().replace(/[^a-z0-9]+/g, '-'),
|
||||
members: []
|
||||
};
|
||||
navigation.push(currentClass);
|
||||
} else if (h2Match && currentClass) {
|
||||
currentClass.members.push({
|
||||
name: h2Match[1],
|
||||
id: h2Match[1].toLowerCase().replace(/[^a-z0-9]+/g, '-')
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Scan for available documentation versions
|
||||
function getAvailableVersions() {
|
||||
const versionsDir = path.join(__dirname, 'versions');
|
||||
const versions = [];
|
||||
|
||||
try {
|
||||
if (fs.existsSync(versionsDir)) {
|
||||
const entries = fs.readdirSync(versionsDir, { withFileTypes: true });
|
||||
for (const entry of entries) {
|
||||
if (entry.isDirectory() && entry.name.startsWith('v')) {
|
||||
const apiPath = path.join(versionsDir, entry.name, 'api.html');
|
||||
if (fs.existsSync(apiPath)) {
|
||||
versions.push(entry.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Warning: Could not scan versions directory:', e.message);
|
||||
}
|
||||
|
||||
// Sort versions (newest first)
|
||||
versions.sort((a, b) => {
|
||||
const parseVersion = (v) => {
|
||||
const parts = v.substring(1).split('.').map(Number);
|
||||
return parts[0] * 10000 + parts[1] * 100 + parts[2];
|
||||
};
|
||||
return parseVersion(b) - parseVersion(a);
|
||||
});
|
||||
|
||||
return versions;
|
||||
}
|
||||
|
||||
const availableVersions = getAvailableVersions();
|
||||
console.log(`Found ${availableVersions.length} archived version(s):`, availableVersions.join(', '));
|
||||
|
||||
// Convert markdown to HTML
|
||||
const htmlContent = md.render(markdownContent);
|
||||
|
||||
// Create HTML template
|
||||
const template = `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>FlexLöve v${VERSION} - API Reference</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css">
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif;
|
||||
background-color: #0d1117;
|
||||
color: #c9d1d9;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 280px;
|
||||
background-color: #161b22;
|
||||
border-right: 1px solid #30363d;
|
||||
position: fixed;
|
||||
height: 100vh;
|
||||
overflow-y: auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.sidebar-header {
|
||||
padding-bottom: 15px;
|
||||
border-bottom: 1px solid #30363d;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.sidebar-header h2 {
|
||||
color: #58a6ff;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.sidebar-header a {
|
||||
color: #8b949e;
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
display: block;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.sidebar-header a:hover {
|
||||
color: #58a6ff;
|
||||
}
|
||||
|
||||
#search {
|
||||
width: 100%;
|
||||
padding: 8px 12px;
|
||||
background-color: #0d1117;
|
||||
border: 1px solid #30363d;
|
||||
border-radius: 6px;
|
||||
color: #c9d1d9;
|
||||
font-size: 14px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
#search:focus {
|
||||
outline: none;
|
||||
border-color: #58a6ff;
|
||||
}
|
||||
|
||||
.nav-section {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.nav-class {
|
||||
color: #c9d1d9;
|
||||
font-weight: 600;
|
||||
padding: 8px 12px;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
transition: background-color 0.2s;
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.nav-class:hover {
|
||||
background-color: #21262d;
|
||||
}
|
||||
|
||||
.nav-members {
|
||||
display: none;
|
||||
padding-left: 20px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.nav-members.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.nav-member {
|
||||
color: #8b949e;
|
||||
padding: 4px 12px;
|
||||
font-size: 0.9rem;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
transition: background-color 0.2s;
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.nav-member:hover {
|
||||
background-color: #21262d;
|
||||
color: #c9d1d9;
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-left: 280px;
|
||||
flex: 1;
|
||||
padding: 40px 60px;
|
||||
max-width: 1200px;
|
||||
}
|
||||
|
||||
.content h1 {
|
||||
color: #58a6ff;
|
||||
font-size: 2rem;
|
||||
margin: 2rem 0 1rem 0;
|
||||
padding-bottom: 0.5rem;
|
||||
border-bottom: 1px solid #30363d;
|
||||
}
|
||||
|
||||
.content h1:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.content h2 {
|
||||
color: #79c0ff;
|
||||
font-size: 1.5rem;
|
||||
margin: 1.5rem 0 0.8rem 0;
|
||||
font-family: 'Courier New', monospace;
|
||||
}
|
||||
|
||||
.content h3 {
|
||||
color: #c9d1d9;
|
||||
font-size: 1.2rem;
|
||||
margin: 1.2rem 0 0.6rem 0;
|
||||
}
|
||||
|
||||
.content p {
|
||||
margin: 0.8rem 0;
|
||||
color: #c9d1d9;
|
||||
}
|
||||
|
||||
.content code {
|
||||
background-color: #161b22;
|
||||
padding: 0.2em 0.4em;
|
||||
border-radius: 3px;
|
||||
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.content pre {
|
||||
background-color: #161b22;
|
||||
padding: 16px;
|
||||
border-radius: 6px;
|
||||
overflow-x: auto;
|
||||
margin: 1rem 0;
|
||||
border: 1px solid #30363d;
|
||||
}
|
||||
|
||||
.content pre code {
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.content a {
|
||||
color: #58a6ff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.content a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.content ul, .content ol {
|
||||
margin: 0.8rem 0;
|
||||
padding-left: 2rem;
|
||||
}
|
||||
|
||||
.content li {
|
||||
margin: 0.4rem 0;
|
||||
}
|
||||
|
||||
.content table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.content th, .content td {
|
||||
border: 1px solid #30363d;
|
||||
padding: 8px 12px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.content th {
|
||||
background-color: #161b22;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.content blockquote {
|
||||
background-color: #1c2128;
|
||||
border-left: 4px solid #f85149;
|
||||
padding: 12px 16px;
|
||||
margin: 1rem 0;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.content blockquote p {
|
||||
margin: 0.4rem 0;
|
||||
}
|
||||
|
||||
.content blockquote strong {
|
||||
color: #f85149;
|
||||
}
|
||||
|
||||
.content hr {
|
||||
border: none;
|
||||
border-top: 1px solid #30363d;
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
.version-selector {
|
||||
margin-top: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.version-selector select {
|
||||
width: 100%;
|
||||
padding: 8px 12px;
|
||||
background-color: #0d1117;
|
||||
border: 1px solid #30363d;
|
||||
border-radius: 6px;
|
||||
color: #c9d1d9;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
appearance: none;
|
||||
background-image: url('data:image/svg+xml;utf8,<svg fill="%238b949e" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M4.427 7.427l3.396 3.396a.25.25 0 00.354 0l3.396-3.396A.25.25 0 0011.396 7H4.604a.25.25 0 00-.177.427z"/></svg>');
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 8px center;
|
||||
background-size: 12px;
|
||||
padding-right: 32px;
|
||||
}
|
||||
|
||||
.version-selector select:hover {
|
||||
background-color: #161b22;
|
||||
border-color: #58a6ff;
|
||||
}
|
||||
|
||||
.version-selector select:focus {
|
||||
outline: none;
|
||||
border-color: #58a6ff;
|
||||
}
|
||||
|
||||
.version-badge {
|
||||
display: inline-block;
|
||||
background-color: #238636;
|
||||
color: #fff;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
font-size: 10px;
|
||||
margin-left: 6px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.back-to-top {
|
||||
position: fixed;
|
||||
bottom: 30px;
|
||||
right: 30px;
|
||||
background-color: #21262d;
|
||||
border: 1px solid #30363d;
|
||||
border-radius: 6px;
|
||||
padding: 10px 15px;
|
||||
color: #c9d1d9;
|
||||
text-decoration: none;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
|
||||
.back-to-top.visible {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.back-to-top:hover {
|
||||
background-color: #30363d;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.sidebar {
|
||||
transform: translateX(-100%);
|
||||
transition: transform 0.3s;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.sidebar.mobile-open {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-left: 0;
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<nav class="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<h2>FlexLöve <span style="font-size: 0.6em; color: #8b949e;">v${VERSION}</span></h2>
|
||||
<a href="index.html">← Back to Home</a>
|
||||
${availableVersions.length > 0 ? `
|
||||
<div class="version-selector">
|
||||
<select id="version-dropdown" onchange="window.versionNavigate(this.value)">
|
||||
<option value="">📚 Switch Version</option>
|
||||
<option value="current">v${VERSION} (Latest)</option>
|
||||
${availableVersions.map(v => `<option value="${v}">` + v + '</option>').join('\n ')}
|
||||
</select>
|
||||
</div>
|
||||
` : ''}
|
||||
</div>
|
||||
|
||||
<input type="text" id="search" placeholder="Search API...">
|
||||
|
||||
<div id="nav-content">
|
||||
${navigation.map(cls => `
|
||||
<div class="nav-section" data-class="${cls.name.toLowerCase()}">
|
||||
<a href="#${cls.id}" class="nav-class">${cls.name}</a>
|
||||
<div class="nav-members">
|
||||
${cls.members.map(member => ` <a href="#${member.id}" class="nav-member">${member.name}</a>`).join('\n')}
|
||||
</div>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="content">
|
||||
${htmlContent}
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<a href="#" class="back-to-top" id="backToTop">↑ Top</a>
|
||||
|
||||
<script>
|
||||
// Search functionality
|
||||
const searchInput = document.getElementById('search');
|
||||
const navSections = document.querySelectorAll('.nav-section');
|
||||
|
||||
searchInput.addEventListener('input', (e) => {
|
||||
const query = e.target.value.toLowerCase();
|
||||
|
||||
navSections.forEach(section => {
|
||||
const className = section.querySelector('.nav-class').textContent.toLowerCase();
|
||||
const members = section.querySelectorAll('.nav-member');
|
||||
let hasMatch = className.includes(query);
|
||||
|
||||
members.forEach(member => {
|
||||
const memberName = member.textContent.toLowerCase();
|
||||
if (memberName.includes(query)) {
|
||||
member.style.display = 'block';
|
||||
hasMatch = true;
|
||||
} else {
|
||||
member.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
section.style.display = hasMatch ? 'block' : 'none';
|
||||
if (hasMatch && query) {
|
||||
section.querySelector('.nav-members').classList.add('active');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Expand/collapse navigation
|
||||
document.querySelectorAll('.nav-class').forEach(navClass => {
|
||||
navClass.addEventListener('click', (e) => {
|
||||
const members = navClass.nextElementSibling;
|
||||
members.classList.toggle('active');
|
||||
});
|
||||
});
|
||||
|
||||
// Back to top button
|
||||
const backToTop = document.getElementById('backToTop');
|
||||
|
||||
window.addEventListener('scroll', () => {
|
||||
if (window.scrollY > 300) {
|
||||
backToTop.classList.add('visible');
|
||||
} else {
|
||||
backToTop.classList.remove('visible');
|
||||
}
|
||||
});
|
||||
|
||||
backToTop.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
});
|
||||
|
||||
// Auto-expand current section
|
||||
const currentHash = window.location.hash;
|
||||
if (currentHash) {
|
||||
const section = document.querySelector(\`[href="\${currentHash}"]\`)?.closest('.nav-section');
|
||||
if (section) {
|
||||
section.querySelector('.nav-members').classList.add('active');
|
||||
}
|
||||
}
|
||||
|
||||
// Version navigation
|
||||
window.versionNavigate = function(value) {
|
||||
if (!value) return;
|
||||
|
||||
if (value === 'current') {
|
||||
// Navigate to current/latest version (root api.html)
|
||||
const currentPath = window.location.pathname;
|
||||
if (currentPath.includes('/versions/')) {
|
||||
// We're in a versioned doc, go back to root
|
||||
window.location.href = '../../api.html';
|
||||
}
|
||||
// Already on current, do nothing
|
||||
} else {
|
||||
// Navigate to specific version
|
||||
const currentPath = window.location.pathname;
|
||||
if (currentPath.includes('/versions/')) {
|
||||
// We're in a versioned doc, navigate to sibling version
|
||||
window.location.href = \`../\${value}/api.html\`;
|
||||
} else {
|
||||
// We're in root, navigate to versions subdirectory
|
||||
window.location.href = \`versions/\${value}/api.html\`;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>`;
|
||||
|
||||
// Write the HTML file
|
||||
fs.writeFileSync(path.join(__dirname, 'api.html'), template, 'utf8');
|
||||
console.log('✓ Generated api.html');
|
||||
47
docs/doc-filter.js
Normal file
47
docs/doc-filter.js
Normal file
@@ -0,0 +1,47 @@
|
||||
// Classes to INCLUDE in documentation (whitelist approach)
|
||||
// Only these classes and their related types will appear in the docs
|
||||
module.exports = {
|
||||
// Main user-facing classes
|
||||
include: [
|
||||
"Animation",
|
||||
"AnimationProps",
|
||||
//"Border",
|
||||
"Color",
|
||||
"Element",
|
||||
"ElementProps",
|
||||
"EventHandler",
|
||||
"FlexLove",
|
||||
"FontFamily",
|
||||
"InputEvent",
|
||||
//"InputEventProps",
|
||||
//"LayoutEngine",
|
||||
//"LayoutEngineProps",
|
||||
"Theme",
|
||||
"ThemeComponent",
|
||||
"ThemeDefinition",
|
||||
"TextEditor",
|
||||
"TextEditorConfig",
|
||||
"TransformProps",
|
||||
"TransitionProps",
|
||||
],
|
||||
|
||||
// Alternative: exclude specific classes (blacklist)
|
||||
exclude: [
|
||||
"Context",
|
||||
"Performance",
|
||||
"Trace",
|
||||
"Proto",
|
||||
"LuaLS",
|
||||
"ImageCache",
|
||||
"ImageRenderer",
|
||||
"Renderer",
|
||||
"StateManager",
|
||||
"ScrollManager",
|
||||
"ErrorCodes",
|
||||
"ThemeManager",
|
||||
"ThemeRegion",
|
||||
],
|
||||
|
||||
// Which mode to use: 'whitelist' or 'blacklist'
|
||||
mode: "whitelist",
|
||||
};
|
||||
@@ -430,10 +430,10 @@
|
||||
16
|
||||
],
|
||||
"type": "doc.type.table",
|
||||
"view": "{ width: number?, height: number?, opacity: number? }"
|
||||
"view": "{ width: number, height: number, opacity: number }"
|
||||
}
|
||||
],
|
||||
"view": "{ width: number?, height: number?, opacity: number? }"
|
||||
"view": "{ width: number, height: number, opacity: number }"
|
||||
},
|
||||
"file": "modules/Animation.lua",
|
||||
"finish": [
|
||||
@@ -446,7 +446,7 @@
|
||||
10
|
||||
],
|
||||
"type": "doc.field",
|
||||
"view": "{ width: number?, height: number?, opacity: number? }",
|
||||
"view": "{ width: number, height: number, opacity: number }",
|
||||
"visible": "public"
|
||||
},
|
||||
{
|
||||
@@ -736,10 +736,10 @@
|
||||
16
|
||||
],
|
||||
"type": "doc.type.table",
|
||||
"view": "{ width: number?, height: number?, opacity: number? }"
|
||||
"view": "{ width: number, height: number, opacity: number }"
|
||||
}
|
||||
],
|
||||
"view": "{ width: number?, height: number?, opacity: number? }"
|
||||
"view": "{ width: number, height: number, opacity: number }"
|
||||
},
|
||||
"file": "modules/Animation.lua",
|
||||
"finish": [
|
||||
@@ -752,7 +752,7 @@
|
||||
10
|
||||
],
|
||||
"type": "doc.field",
|
||||
"view": "{ width: number?, height: number?, opacity: number? }",
|
||||
"view": "{ width: number, height: number, opacity: number }",
|
||||
"visible": "public"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -49,7 +49,7 @@ function Animation.fade(duration: number, fromOpacity: number, toOpacity: number
|
||||
|
||||
|
||||
```lua
|
||||
{ width: number?, height: number?, opacity: number? }
|
||||
{ width: number, height: number, opacity: number }
|
||||
```
|
||||
|
||||
## interpolate
|
||||
@@ -86,7 +86,7 @@ function Animation.scale(duration: number, fromScale: table, toScale: table)
|
||||
|
||||
|
||||
```lua
|
||||
{ width: number?, height: number?, opacity: number? }
|
||||
{ width: number, height: number, opacity: number }
|
||||
```
|
||||
|
||||
## transform
|
||||
|
||||
1075
docs/examples.html
Normal file
1075
docs/examples.html
Normal file
File diff suppressed because it is too large
Load Diff
446
docs/index.html
446
docs/index.html
@@ -1,152 +1,237 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>FlexLöve Documentation</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/github-markdown-css@5/github-markdown.min.css">
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/github-markdown-css@5/github-markdown.min.css"
|
||||
/>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif;
|
||||
background-color: #0d1117;
|
||||
color: #c9d1d9;
|
||||
}
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
}
|
||||
.header {
|
||||
text-align: center;
|
||||
padding: 3rem 0;
|
||||
border-bottom: 1px solid #30363d;
|
||||
}
|
||||
.header h1 {
|
||||
font-size: 3rem;
|
||||
margin: 0;
|
||||
background: linear-gradient(45deg, #58a6ff, #79c0ff);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
.header p {
|
||||
font-size: 1.2rem;
|
||||
color: #8b949e;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
.nav {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
margin: 2rem 0;
|
||||
}
|
||||
.nav a {
|
||||
padding: 0.75rem 1.5rem;
|
||||
background-color: #21262d;
|
||||
color: #c9d1d9;
|
||||
text-decoration: none;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #30363d;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.nav a:hover {
|
||||
background-color: #30363d;
|
||||
border-color: #58a6ff;
|
||||
}
|
||||
.markdown-body {
|
||||
background-color: #0d1117;
|
||||
padding: 2rem;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.section {
|
||||
margin: 3rem 0;
|
||||
}
|
||||
.features {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 2rem;
|
||||
margin: 3rem 0;
|
||||
}
|
||||
.feature-card {
|
||||
background-color: #161b22;
|
||||
padding: 2rem;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #30363d;
|
||||
}
|
||||
.feature-card h3 {
|
||||
color: #58a6ff;
|
||||
margin-top: 0;
|
||||
}
|
||||
code {
|
||||
background-color: #161b22;
|
||||
padding: 0.2rem 0.4rem;
|
||||
border-radius: 3px;
|
||||
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
|
||||
}
|
||||
pre {
|
||||
background-color: #161b22;
|
||||
padding: 1rem;
|
||||
border-radius: 6px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
.footer {
|
||||
text-align: center;
|
||||
padding: 3rem 0;
|
||||
border-top: 1px solid #30363d;
|
||||
margin-top: 4rem;
|
||||
color: #8b949e;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans",
|
||||
Helvetica, Arial, sans-serif;
|
||||
background-color: #0d1117;
|
||||
color: #c9d1d9;
|
||||
}
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
}
|
||||
.header {
|
||||
text-align: center;
|
||||
padding: 3rem 0;
|
||||
border-bottom: 1px solid #30363d;
|
||||
}
|
||||
.header h1 {
|
||||
font-size: 3rem;
|
||||
margin: 0;
|
||||
background: linear-gradient(45deg, #58a6ff, #79c0ff);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
.header p {
|
||||
font-size: 1.2rem;
|
||||
color: #8b949e;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
.nav {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
margin: 2rem 0;
|
||||
}
|
||||
.nav a {
|
||||
padding: 0.75rem 1.5rem;
|
||||
background-color: #21262d;
|
||||
color: #c9d1d9;
|
||||
text-decoration: none;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #30363d;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.nav a:hover {
|
||||
background-color: #30363d;
|
||||
border-color: #58a6ff;
|
||||
}
|
||||
.markdown-body {
|
||||
background-color: #0d1117;
|
||||
padding: 2rem;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.section {
|
||||
margin: 3rem 0;
|
||||
}
|
||||
.features {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 2rem;
|
||||
margin: 3rem 0;
|
||||
}
|
||||
.feature-card {
|
||||
background-color: #161b22;
|
||||
padding: 2rem;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #30363d;
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
color: inherit;
|
||||
}
|
||||
.feature-card:hover {
|
||||
background-color: #1c2128;
|
||||
border-color: #58a6ff;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(88, 166, 255, 0.15);
|
||||
}
|
||||
.feature-card h3 {
|
||||
color: #58a6ff;
|
||||
margin-top: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.feature-card h3::after {
|
||||
content: "→";
|
||||
font-size: 1.5rem;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
.feature-card:hover h3::after {
|
||||
opacity: 1;
|
||||
}
|
||||
.feature-card p {
|
||||
color: #8b949e;
|
||||
margin: 0.5rem 0 0 0;
|
||||
}
|
||||
code {
|
||||
background-color: #161b22;
|
||||
padding: 0.2rem 0.4rem;
|
||||
border-radius: 3px;
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo,
|
||||
monospace;
|
||||
}
|
||||
pre {
|
||||
background-color: #161b22;
|
||||
padding: 1rem;
|
||||
border-radius: 6px;
|
||||
overflow-x: auto;
|
||||
position: relative;
|
||||
}
|
||||
.copy-button {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
background-color: #21262d;
|
||||
color: #8b949e;
|
||||
border: 1px solid #30363d;
|
||||
border-radius: 6px;
|
||||
padding: 6px 12px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
transition: all 0.2s;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||
}
|
||||
pre:hover .copy-button {
|
||||
opacity: 1;
|
||||
}
|
||||
.copy-button:hover {
|
||||
background-color: #30363d;
|
||||
border-color: #58a6ff;
|
||||
color: #c9d1d9;
|
||||
}
|
||||
.copy-button:active {
|
||||
background-color: #238636;
|
||||
border-color: #238636;
|
||||
color: #ffffff;
|
||||
}
|
||||
.copy-button.copied {
|
||||
background-color: #238636;
|
||||
border-color: #238636;
|
||||
color: #ffffff;
|
||||
}
|
||||
.footer {
|
||||
text-align: center;
|
||||
padding: 3rem 0;
|
||||
border-top: 1px solid #30363d;
|
||||
margin-top: 4rem;
|
||||
color: #8b949e;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>FlexLöve</h1>
|
||||
<p>A comprehensive UI library for LÖVE Framework based on flexbox</p>
|
||||
</div>
|
||||
<div class="header">
|
||||
<h1>FlexLöve</h1>
|
||||
<p>A comprehensive UI library for LÖVE Framework based on flexbox</p>
|
||||
</div>
|
||||
|
||||
<div class="nav">
|
||||
<a href="https://github.com/mikefreno/FlexLove">GitHub</a>
|
||||
<a href="#getting-started">Getting Started</a>
|
||||
<a href="doc.md">API Reference (Markdown)</a>
|
||||
<a href="doc.json">API Reference (JSON)</a>
|
||||
</div>
|
||||
<div class="nav">
|
||||
<a href="https://github.com/mikefreno/FlexLove">GitHub</a>
|
||||
<a href="#getting-started">Getting Started</a>
|
||||
<a href="examples.html">Examples</a>
|
||||
<a href="api.html">API Reference</a>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<div class="features">
|
||||
<div class="feature-card">
|
||||
<h3>🎨 Flexbox & Grid Layouts</h3>
|
||||
<p>Modern CSS-like layout system with full flexbox and grid support for building responsive UIs.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<h3>🎭 Theme System</h3>
|
||||
<p>9-patch NinePatch theming with state support (normal, hover, pressed, disabled).</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<h3>✨ Animations</h3>
|
||||
<p>Built-in animation support for smooth transitions and effects with easing functions.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<h3>📱 Responsive Design</h3>
|
||||
<p>Viewport units (vw, vh, %) for automatic resizing and responsive layouts.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<h3>⚡ Immediate Mode</h3>
|
||||
<p>Optional immediate mode support alongside traditional retained mode rendering.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<h3>🎯 Event System</h3>
|
||||
<p>Rich event handling with callbacks, focus management, and input fields.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h2 style="text-align: center; margin-bottom: 2rem">✨ Features</h2>
|
||||
<div class="features">
|
||||
<a href="examples.html#layout" class="feature-card">
|
||||
<h3>🎨 Flexbox & Grid Layouts</h3>
|
||||
<p>
|
||||
Modern CSS-like layout system with full flexbox and grid support
|
||||
for building responsive UIs.
|
||||
</p>
|
||||
</a>
|
||||
<a href="examples.html#theme" class="feature-card">
|
||||
<h3>🎭 Theme System</h3>
|
||||
<p>
|
||||
9-patch NinePatch theming with state support (normal, hover,
|
||||
pressed, disabled).
|
||||
</p>
|
||||
</a>
|
||||
<a href="examples.html#state" class="feature-card">
|
||||
<h3>✨ State Management</h3>
|
||||
<p>
|
||||
Interactive components with state tracking, counters, toggles, and
|
||||
dynamic updates.
|
||||
</p>
|
||||
</a>
|
||||
<a href="examples.html#scroll" class="feature-card">
|
||||
<h3>📜 Scrollable Content</h3>
|
||||
<p>
|
||||
Smooth scrolling containers with backdrop blur effects and
|
||||
overflow handling for long content lists.
|
||||
</p>
|
||||
</a>
|
||||
<a href="examples.html#slider" class="feature-card">
|
||||
<h3>🎚️ Sliders & Controls</h3>
|
||||
<p>
|
||||
Draggable sliders with value tracking, perfect for settings menus
|
||||
and adjustable parameters.
|
||||
</p>
|
||||
</a>
|
||||
<a href="examples.html#input" class="feature-card">
|
||||
<h3>⌨️ Input & Events</h3>
|
||||
<p>
|
||||
Rich event handling with mouse, keyboard, and touch support. Focus
|
||||
management and input fields.
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section markdown-body" id="getting-started">
|
||||
<h2>Quick Start</h2>
|
||||
<pre><code class="language-lua">local FlexLove = require("FlexLove")
|
||||
<div class="section" id="getting-started">
|
||||
<h2>Quick Start</h2>
|
||||
<pre><code class="language-lua">local FlexLove = require("FlexLove")
|
||||
|
||||
-- Initialize with base scaling and theme
|
||||
FlexLove.init({
|
||||
@@ -174,29 +259,70 @@ end
|
||||
function love.draw()
|
||||
FlexLove.draw()
|
||||
end</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>Documentation</h2>
|
||||
<p>The API reference is available in two formats:</p>
|
||||
<ul>
|
||||
<li><a href="doc.md">Markdown format</a> - Easy to read in browser or convert to HTML</li>
|
||||
<li><a href="doc.json">JSON format</a> - For programmatic access and tooling</li>
|
||||
</ul>
|
||||
<p>These docs are auto-generated from LuaLS annotations using the Lua Language Server.</p>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>Installation</h2>
|
||||
<p>Add the <code>modules</code> directory and <code>FlexLove.lua</code> into your LÖVE project.</p>
|
||||
<pre><code>git clone https://github.com/mikefreno/FlexLove.git
|
||||
<div class="section">
|
||||
<h2>Installation</h2>
|
||||
<p>
|
||||
Add the <code>modules</code> directory and
|
||||
<code>FlexLove.lua</code> into your LÖVE project.
|
||||
</p>
|
||||
<pre><code>git clone https://github.com/mikefreno/FlexLove.git
|
||||
cp -r FlexLove/modules your-project/
|
||||
cp FlexLove/FlexLove.lua your-project/</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<p>FlexLöve v0.2.0 | MIT License | <a href="https://github.com/mikefreno/FlexLove" style="color: #58a6ff;">GitHub Repository</a></p>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<p>
|
||||
FlexLöve v0.2.0 | MIT License |
|
||||
<a href="https://github.com/mikefreno/FlexLove" style="color: #58a6ff"
|
||||
>GitHub Repository</a
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
hljs.highlightAll();
|
||||
|
||||
document.querySelectorAll('a[href^="#"]').forEach((anchor) => {
|
||||
anchor.addEventListener("click", function (e) {
|
||||
e.preventDefault();
|
||||
const target = document.querySelector(this.getAttribute("href"));
|
||||
if (target) {
|
||||
target.scrollIntoView({ behavior: "smooth", block: "start" });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Add copy buttons to code blocks
|
||||
document.querySelectorAll("pre code").forEach((codeBlock) => {
|
||||
const pre = codeBlock.parentElement;
|
||||
const button = document.createElement("button");
|
||||
button.className = "copy-button";
|
||||
button.textContent = "Copy";
|
||||
button.title = "Copy to clipboard";
|
||||
|
||||
button.addEventListener("click", async () => {
|
||||
const code = codeBlock.textContent;
|
||||
try {
|
||||
await navigator.clipboard.writeText(code);
|
||||
button.textContent = "Copied!";
|
||||
button.classList.add("copied");
|
||||
setTimeout(() => {
|
||||
button.textContent = "Copy";
|
||||
button.classList.remove("copied");
|
||||
}, 2000);
|
||||
} catch (err) {
|
||||
console.error("Failed to copy:", err);
|
||||
button.textContent = "Failed";
|
||||
setTimeout(() => {
|
||||
button.textContent = "Copy";
|
||||
}, 2000);
|
||||
}
|
||||
});
|
||||
|
||||
pre.appendChild(button);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
125
docs/package-lock.json
generated
Normal file
125
docs/package-lock.json
generated
Normal file
@@ -0,0 +1,125 @@
|
||||
{
|
||||
"name": "flexlove-docs",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "flexlove-docs",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"highlight.js": "^11.9.0",
|
||||
"markdown-it": "^14.0.0",
|
||||
"markdown-it-anchor": "^9.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/linkify-it": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
|
||||
"integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/markdown-it": {
|
||||
"version": "14.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
|
||||
"integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/linkify-it": "^5",
|
||||
"@types/mdurl": "^2"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/mdurl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
|
||||
"integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||
"license": "Python-2.0"
|
||||
},
|
||||
"node_modules/entities": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
||||
"license": "BSD-2-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/highlight.js": {
|
||||
"version": "11.11.1",
|
||||
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz",
|
||||
"integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/linkify-it": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
|
||||
"integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"uc.micro": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/markdown-it": {
|
||||
"version": "14.1.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
|
||||
"integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1",
|
||||
"entities": "^4.4.0",
|
||||
"linkify-it": "^5.0.0",
|
||||
"mdurl": "^2.0.0",
|
||||
"punycode.js": "^2.3.1",
|
||||
"uc.micro": "^2.1.0"
|
||||
},
|
||||
"bin": {
|
||||
"markdown-it": "bin/markdown-it.mjs"
|
||||
}
|
||||
},
|
||||
"node_modules/markdown-it-anchor": {
|
||||
"version": "9.2.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-9.2.0.tgz",
|
||||
"integrity": "sha512-sa2ErMQ6kKOA4l31gLGYliFQrMKkqSO0ZJgGhDHKijPf0pNFM9vghjAh3gn26pS4JDRs7Iwa9S36gxm3vgZTzg==",
|
||||
"license": "Unlicense",
|
||||
"peerDependencies": {
|
||||
"@types/markdown-it": "*",
|
||||
"markdown-it": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/mdurl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
|
||||
"integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/punycode.js": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
|
||||
"integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/uc.micro": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
|
||||
"integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
}
|
||||
13
docs/package.json
Normal file
13
docs/package.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "flexlove-docs",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "node update-version.js && node build-docs.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"markdown-it": "^14.0.0",
|
||||
"markdown-it-anchor": "^9.0.0",
|
||||
"highlight.js": "^11.9.0"
|
||||
}
|
||||
}
|
||||
34
docs/update-version.js
Normal file
34
docs/update-version.js
Normal file
@@ -0,0 +1,34 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// Extract version from FlexLove.lua
|
||||
function getVersion() {
|
||||
try {
|
||||
const flexlovePath = path.join(__dirname, '..', 'FlexLove.lua');
|
||||
const content = fs.readFileSync(flexlovePath, 'utf8');
|
||||
const match = content.match(/flexlove\._VERSION\s*=\s*["']([^"']+)["']/);
|
||||
return match ? match[1] : 'unknown';
|
||||
} catch (e) {
|
||||
return 'unknown';
|
||||
}
|
||||
}
|
||||
|
||||
// Update index.html with current version
|
||||
function updateIndexVersion() {
|
||||
const version = getVersion();
|
||||
const indexPath = path.join(__dirname, 'index.html');
|
||||
let content = fs.readFileSync(indexPath, 'utf8');
|
||||
|
||||
// Update version in multiple places
|
||||
content = content.replace(
|
||||
/FlexLöve v[\d.]+/g,
|
||||
`FlexLöve v${version}`
|
||||
);
|
||||
|
||||
fs.writeFileSync(indexPath, content, 'utf8');
|
||||
console.log(`✓ Updated index.html to version ${version}`);
|
||||
}
|
||||
|
||||
const version = getVersion();
|
||||
console.log(`Current version: ${version}`);
|
||||
updateIndexVersion();
|
||||
86
docs/versions/README.md
Normal file
86
docs/versions/README.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# FlexLöve Documentation Versions
|
||||
|
||||
This directory stores versioned snapshots of the FlexLöve API documentation.
|
||||
|
||||
## Purpose
|
||||
|
||||
Each time a new version of FlexLöve is released, the documentation is archived here so users can reference docs for specific versions they're using.
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
docs/
|
||||
├── api.html # Latest/current version documentation
|
||||
├── index.html # Landing page with version selector
|
||||
└── versions/
|
||||
├── v0.2.0/
|
||||
│ └── api.html # Documentation for v0.2.0
|
||||
├── v0.3.0/
|
||||
│ └── api.html # Documentation for v0.3.0
|
||||
└── v1.0.0/
|
||||
└── api.html # Documentation for v1.0.0
|
||||
```
|
||||
|
||||
## Naming Convention
|
||||
|
||||
- Version directories follow the pattern: `v{major}.{minor}.{patch}`
|
||||
- Examples: `v0.2.0`, `v1.0.0`, `v2.1.3`
|
||||
- Each directory contains `api.html` (the full API documentation for that version)
|
||||
|
||||
## Access
|
||||
|
||||
### Via GitHub Pages
|
||||
|
||||
Once deployed, versions are accessible at:
|
||||
- Latest: `https://{user}.github.io/{repo}/api.html`
|
||||
- Specific version: `https://{user}.github.io/{repo}/versions/v0.2.0/api.html`
|
||||
|
||||
### Via Repository
|
||||
|
||||
Browse directly in the repository:
|
||||
- `docs/api.html` - Always shows latest
|
||||
- `docs/versions/v0.2.0/api.html` - Specific version
|
||||
|
||||
## Automation
|
||||
|
||||
Documentation versions are automatically archived when:
|
||||
1. A new git tag is pushed (e.g., `git push origin v0.3.0`)
|
||||
2. GitHub Actions workflow runs
|
||||
3. Documentation is generated and archived
|
||||
4. Version is committed back to the repository
|
||||
|
||||
See `.github/workflows/release.yml` for implementation details.
|
||||
|
||||
## Manual Archival
|
||||
|
||||
To manually archive a version:
|
||||
|
||||
```bash
|
||||
# Generate docs for current version
|
||||
./scripts/generate_docs.sh
|
||||
|
||||
# Create version directory
|
||||
VERSION="0.2.0"
|
||||
mkdir -p "docs/versions/v${VERSION}"
|
||||
|
||||
# Copy documentation
|
||||
cp docs/api.html "docs/versions/v${VERSION}/api.html"
|
||||
|
||||
# Commit
|
||||
git add docs/versions/
|
||||
git commit -m "Archive documentation for v${VERSION}"
|
||||
git push
|
||||
```
|
||||
|
||||
## Storage Considerations
|
||||
|
||||
- Each `api.html` file is approximately 200-300KB
|
||||
- Storing 10-20 versions = 2-6MB total
|
||||
- GitHub has a 1GB repository soft limit (we're well within it)
|
||||
- Old versions are kept indefinitely for reference
|
||||
|
||||
## Version Dropdown
|
||||
|
||||
The main documentation pages (`api.html` and `index.html`) include a version dropdown that automatically detects and lists all available versions from this directory.
|
||||
|
||||
Users can switch between versions without leaving the documentation.
|
||||
3732
docs/versions/v0.2.0/api.html
Normal file
3732
docs/versions/v0.2.0/api.html
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,40 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# FlexLöve Documentation Generator
|
||||
# This script generates HTML documentation from LuaLS annotations
|
||||
|
||||
echo "Generating FlexLöve documentation..."
|
||||
|
||||
# Get the directory where this script is located
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
# Check if lua-language-server is installed
|
||||
if ! command -v lua-language-server &> /dev/null; then
|
||||
echo "Error: lua-language-server not found. Please install it first."
|
||||
echo " macOS: brew install lua-language-server"
|
||||
echo " Linux: See https://github.com/LuaLS/lua-language-server"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create docs directory if it doesn't exist
|
||||
mkdir -p docs
|
||||
|
||||
# Generate documentation using lua-language-server
|
||||
echo "Running lua-language-server documentation export..."
|
||||
lua-language-server \
|
||||
--doc="$SCRIPT_DIR" \
|
||||
--doc_out_path="$SCRIPT_DIR/docs"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✓ Documentation generated successfully!"
|
||||
echo " - docs/doc.md (Markdown format)"
|
||||
echo " - docs/doc.json (JSON format)"
|
||||
echo " - docs/index.html (GitHub Pages)"
|
||||
echo ""
|
||||
echo "To view locally, open: file://$SCRIPT_DIR/docs/index.html"
|
||||
echo "To publish, commit the docs/ directory and enable GitHub Pages."
|
||||
else
|
||||
echo "✗ Documentation generation failed"
|
||||
exit 1
|
||||
fi
|
||||
58
scripts/archive-docs.sh
Executable file
58
scripts/archive-docs.sh
Executable file
@@ -0,0 +1,58 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${BLUE}FlexLöve Documentation Archival${NC}"
|
||||
echo ""
|
||||
|
||||
VERSION=$(grep -m 1 "_VERSION" FlexLove.lua | sed -E 's/.*"([^"]+)".*/\1/')
|
||||
if [ -z "$VERSION" ]; then
|
||||
echo -e "${RED}Error: Could not extract version from FlexLove.lua${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}Version detected: ${VERSION}${NC}"
|
||||
|
||||
if [ ! -f "docs/api.html" ]; then
|
||||
echo -e "${RED}Error: docs/api.html not found${NC}"
|
||||
echo "Please run ./scripts/generate_docs.sh first"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VERSION_DIR="docs/versions/v${VERSION}"
|
||||
if [ -d "$VERSION_DIR" ]; then
|
||||
echo -e "${YELLOW}Warning: $VERSION_DIR already exists${NC}"
|
||||
read -p "Overwrite? (y/n) " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo -e "${RED}Aborted${NC}"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}Creating version directory...${NC}"
|
||||
mkdir -p "$VERSION_DIR"
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}Archiving documentation...${NC}"
|
||||
cp docs/api.html "$VERSION_DIR/api.html"
|
||||
|
||||
if [ ! -f "$VERSION_DIR/api.html" ]; then
|
||||
echo -e "${RED}Error: Failed to copy documentation${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
FILE_SIZE=$(du -h "$VERSION_DIR/api.html" | cut -f1)
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}✓ Documentation archived successfully!${NC}"
|
||||
echo ""
|
||||
echo -e " ${BLUE}Version:${NC} v${VERSION}"
|
||||
echo -e " ${BLUE}Location:${NC} $VERSION_DIR/api.html"
|
||||
echo -e " ${BLUE}Size:${NC} $FILE_SIZE"
|
||||
echo ""
|
||||
99
scripts/create-release.sh
Executable file
99
scripts/create-release.sh
Executable file
@@ -0,0 +1,99 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${BLUE}FlexLöve Release Builder${NC}"
|
||||
echo ""
|
||||
|
||||
VERSION=$(grep -m 1 "_VERSION" FlexLove.lua | sed -E 's/.*"([^"]+)".*/\1/')
|
||||
if [ -z "$VERSION" ]; then
|
||||
echo -e "${RED}Error: Could not extract version from FlexLove.lua${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}Version detected: ${VERSION}${NC}"
|
||||
|
||||
# Create releases directory if it doesn't exist
|
||||
RELEASE_DIR="releases"
|
||||
if [ ! -d "$RELEASE_DIR" ]; then
|
||||
echo -e "${YELLOW}Creating releases directory...${NC}"
|
||||
mkdir -p "$RELEASE_DIR"
|
||||
fi
|
||||
|
||||
OUTPUT_FILE="${RELEASE_DIR}/flexlove-v${VERSION}.zip"
|
||||
|
||||
CHECKSUM_FILE="${OUTPUT_FILE}.sha256"
|
||||
if [ -f "$OUTPUT_FILE" ] || [ -f "$CHECKSUM_FILE" ]; then
|
||||
echo -e "${YELLOW}Warning: Release files already exist - overwriting${NC}"
|
||||
[ -f "$OUTPUT_FILE" ] && echo " - $OUTPUT_FILE" && rm "$OUTPUT_FILE"
|
||||
[ -f "$CHECKSUM_FILE" ] && echo " - $CHECKSUM_FILE" && rm "$CHECKSUM_FILE"
|
||||
fi
|
||||
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
BUILD_DIR="${TEMP_DIR}/flexlove"
|
||||
|
||||
echo -e "${YELLOW}Creating release package...${NC}"
|
||||
|
||||
mkdir -p "$BUILD_DIR"
|
||||
|
||||
echo " → Copying FlexLove.lua"
|
||||
cp FlexLove.lua "$BUILD_DIR/"
|
||||
|
||||
echo " → Copying modules/"
|
||||
cp -r modules "$BUILD_DIR/"
|
||||
|
||||
echo " → Copying LICENSE"
|
||||
cp LICENSE "$BUILD_DIR/"
|
||||
|
||||
echo " → Creating README.md"
|
||||
cp README.md "$BUILD_DIR/"
|
||||
|
||||
echo -e "${YELLOW}Creating zip archive...${NC}"
|
||||
|
||||
ABS_OUTPUT_FILE="$(cd "$(dirname "$OUTPUT_FILE")" && pwd)/$(basename "$OUTPUT_FILE")"
|
||||
|
||||
cd "$TEMP_DIR"
|
||||
zip -r -q "flexlove-v${VERSION}.zip" flexlove/
|
||||
|
||||
mv "flexlove-v${VERSION}.zip" "$ABS_OUTPUT_FILE"
|
||||
cd - > /dev/null
|
||||
|
||||
echo -e "${YELLOW}Generating SHA256 checksum...${NC}"
|
||||
CHECKSUM_FILE="${OUTPUT_FILE}.sha256"
|
||||
cd "$RELEASE_DIR"
|
||||
shasum -a 256 "flexlove-v${VERSION}.zip" > "flexlove-v${VERSION}.zip.sha256"
|
||||
cd - > /dev/null
|
||||
|
||||
CHECKSUM=$(cat "$CHECKSUM_FILE" | cut -d ' ' -f 1)
|
||||
|
||||
echo -e "${YELLOW}Cleaning up...${NC}"
|
||||
rm -rf "$TEMP_DIR"
|
||||
|
||||
FILE_SIZE=$(du -h "$OUTPUT_FILE" | cut -f1)
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}✓ Release created successfully!${NC}"
|
||||
echo ""
|
||||
echo -e " ${BLUE}File:${NC} $OUTPUT_FILE"
|
||||
echo -e " ${BLUE}Size:${NC} $FILE_SIZE"
|
||||
echo -e " ${BLUE}Version:${NC} $VERSION"
|
||||
echo -e " ${BLUE}SHA256:${NC} $CHECKSUM"
|
||||
echo ""
|
||||
echo -e "Contents:"
|
||||
echo " - FlexLove.lua"
|
||||
echo " - modules/ (27 files)"
|
||||
echo " - LICENSE"
|
||||
echo " - README.txt"
|
||||
echo ""
|
||||
echo -e "Files created:"
|
||||
echo " - $OUTPUT_FILE"
|
||||
echo " - $CHECKSUM_FILE"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Verify checksum:${NC}"
|
||||
echo " cd releases && shasum -a 256 -c flexlove-v${VERSION}.zip.sha256"
|
||||
72
scripts/generate_docs.sh
Executable file
72
scripts/generate_docs.sh
Executable file
@@ -0,0 +1,72 @@
|
||||
#!/bin/bash
|
||||
|
||||
YELLOW='\033[1;33m'
|
||||
GREEN='\033[0;32m'
|
||||
NC='\033[0m'
|
||||
|
||||
echo "Generating FlexLöve documentation..."
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
PROJECT_ROOT="$( cd "$SCRIPT_DIR/.." && pwd )"
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
if [ -f "docs/api.html" ]; then
|
||||
echo -e "${YELLOW}Checking for previous documentation version...${NC}"
|
||||
OLD_VERSION=$(grep -o 'FlexLöve v[0-9.]*' docs/api.html | head -1 | sed 's/FlexLöve v//')
|
||||
CURRENT_VERSION=$(grep -m 1 "_VERSION" FlexLove.lua | sed -E 's/.*"([^"]+)".*/\1/')
|
||||
|
||||
if [ -n "$OLD_VERSION" ] && [ "$OLD_VERSION" != "$CURRENT_VERSION" ]; then
|
||||
echo -e "${YELLOW}Found previous version v${OLD_VERSION}, archiving before generating new docs...${NC}"
|
||||
mkdir -p "docs/versions/v${OLD_VERSION}"
|
||||
cp docs/api.html "docs/versions/v${OLD_VERSION}/api.html"
|
||||
echo -e "${GREEN}✓ Archived previous documentation to docs/versions/v${OLD_VERSION}/${NC}"
|
||||
elif [ -n "$OLD_VERSION" ] && [ "$OLD_VERSION" = "$CURRENT_VERSION" ]; then
|
||||
echo -e "${YELLOW}Same version (v${OLD_VERSION}), will overwrite current documentation${NC}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! command -v lua-language-server &> /dev/null; then
|
||||
echo "Error: lua-language-server not found. Please install it first."
|
||||
echo " macOS: brew install lua-language-server"
|
||||
echo " Linux: See https://github.com/LuaLS/lua-language-server"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p docs
|
||||
|
||||
echo "Running lua-language-server documentation export..."
|
||||
lua-language-server \
|
||||
--doc="$PROJECT_ROOT" \
|
||||
--doc_out_path="$PROJECT_ROOT/docs"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✓ Markdown documentation generated"
|
||||
|
||||
echo "Building beautiful HTML documentation..."
|
||||
cd "$PROJECT_ROOT/docs"
|
||||
|
||||
if [ ! -d "node_modules" ]; then
|
||||
echo "Installing Node.js dependencies..."
|
||||
npm install --silent
|
||||
fi
|
||||
|
||||
npm run build --silent
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo -e "${GREEN}✓ HTML documentation built successfully!${NC}"
|
||||
echo ""
|
||||
echo "Generated files:"
|
||||
echo " - docs/api.html (Beautiful, searchable API reference)"
|
||||
echo " - docs/index.html (Landing page)"
|
||||
echo " - docs/doc.md (Raw markdown)"
|
||||
if [ -n "$OLD_VERSION" ] && [ "$OLD_VERSION" != "$CURRENT_VERSION" ]; then
|
||||
echo " - docs/versions/v${OLD_VERSION}/api.html (Previous version archived)"
|
||||
fi
|
||||
else
|
||||
echo "✗ HTML build failed, but markdown docs are available"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "✗ Documentation generation failed"
|
||||
exit 1
|
||||
fi
|
||||
177
scripts/make-tag.sh
Executable file
177
scripts/make-tag.sh
Executable file
@@ -0,0 +1,177 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${BLUE}═══════════════════════════════════════${NC}"
|
||||
echo -e "${BLUE} FlexLöve Version Bump & Tag Tool ${NC}"
|
||||
echo -e "${BLUE}═══════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
PROJECT_ROOT="$( cd "$SCRIPT_DIR/.." && pwd )"
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
if [ ! -d .git ] && [ ! -f .git ]; then
|
||||
echo -e "${RED}Error: Not in a git repository${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! git diff-index --quiet HEAD --; then
|
||||
echo -e "${YELLOW}Warning: You have uncommitted changes${NC}"
|
||||
git status --short
|
||||
echo ""
|
||||
read -p "Continue anyway? (y/n) " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo -e "${RED}Aborted${NC}"
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
CURRENT_VERSION=$(grep -m 1 "_VERSION" FlexLove.lua | sed -E 's/.*"([^"]+)".*/\1/')
|
||||
if [ -z "$CURRENT_VERSION" ]; then
|
||||
echo -e "${RED}Error: Could not extract version from FlexLove.lua${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${CYAN}Current version:${NC} ${GREEN}v${CURRENT_VERSION}${NC}"
|
||||
echo ""
|
||||
|
||||
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"
|
||||
|
||||
MAJOR=$(echo "$MAJOR" | sed 's/[^0-9].*//')
|
||||
MINOR=$(echo "$MINOR" | sed 's/[^0-9].*//')
|
||||
PATCH=$(echo "$PATCH" | sed 's/[^0-9].*//')
|
||||
|
||||
echo -e "${CYAN}Select version bump type:${NC}"
|
||||
echo " 1) Major (breaking changes) ${MAJOR}.${MINOR}.${PATCH} → $((MAJOR+1)).0.0"
|
||||
echo " 2) Minor (new features) ${MAJOR}.${MINOR}.${PATCH} → ${MAJOR}.$((MINOR+1)).0"
|
||||
echo " 3) Patch (bug fixes) ${MAJOR}.${MINOR}.${PATCH} → ${MAJOR}.${MINOR}.$((PATCH+1))"
|
||||
echo " 4) Custom version"
|
||||
echo " 5) Cancel"
|
||||
echo ""
|
||||
read -p "Enter choice (1-5): " -n 1 -r CHOICE
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
case $CHOICE in
|
||||
1)
|
||||
NEW_MAJOR=$((MAJOR+1))
|
||||
NEW_MINOR=0
|
||||
NEW_PATCH=0
|
||||
BUMP_TYPE="major"
|
||||
;;
|
||||
2)
|
||||
NEW_MAJOR=$MAJOR
|
||||
NEW_MINOR=$((MINOR+1))
|
||||
NEW_PATCH=0
|
||||
BUMP_TYPE="minor"
|
||||
;;
|
||||
3)
|
||||
NEW_MAJOR=$MAJOR
|
||||
NEW_MINOR=$MINOR
|
||||
NEW_PATCH=$((PATCH+1))
|
||||
BUMP_TYPE="patch"
|
||||
;;
|
||||
4)
|
||||
read -p "Enter custom version (e.g., 1.0.0-beta): " CUSTOM_VERSION
|
||||
NEW_VERSION="$CUSTOM_VERSION"
|
||||
BUMP_TYPE="custom"
|
||||
;;
|
||||
5)
|
||||
echo -e "${RED}Cancelled${NC}"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo -e "${RED}Invalid choice${NC}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Construct new version (unless custom)
|
||||
if [ "$BUMP_TYPE" != "custom" ]; then
|
||||
NEW_VERSION="${NEW_MAJOR}.${NEW_MINOR}.${NEW_PATCH}"
|
||||
fi
|
||||
|
||||
echo -e "${CYAN}New version:${NC} ${GREEN}v${NEW_VERSION}${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}This will:${NC}"
|
||||
echo " 1. Update FlexLove.lua → flexlove._VERSION = \"${NEW_VERSION}\""
|
||||
echo " 2. Update README.md → first line version"
|
||||
echo " 3. Stage changes for commit"
|
||||
echo " 4. Create git tag v${NEW_VERSION}"
|
||||
echo ""
|
||||
read -p "Proceed? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo -e "${RED}Aborted${NC}"
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo -e "${CYAN}[1/4]${NC} Updating FlexLove.lua..."
|
||||
sed -i.bak "s/flexlove\._VERSION = \".*\"/flexlove._VERSION = \"${NEW_VERSION}\"/" FlexLove.lua
|
||||
rm -f FlexLove.lua.bak
|
||||
echo -e "${GREEN}✓ FlexLove.lua updated${NC}"
|
||||
|
||||
echo -e "${CYAN}[2/4]${NC} Updating README.md..."
|
||||
FIRST_LINE=$(head -1 README.md)
|
||||
if [[ "$FIRST_LINE" =~ ^#.*FlexLöve.*v[0-9]+\.[0-9]+\.[0-9]+ ]]; then
|
||||
sed -i.bak -E "1s/v[0-9]+\.[0-9]+\.[0-9]+/v${NEW_VERSION}/" README.md
|
||||
rm -f README.md.bak
|
||||
echo -e "${GREEN}✓ README.md updated${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠ README.md first line doesn't match expected format, skipping${NC}"
|
||||
echo -e "${YELLOW}Expected: # FlexLöve v0.0.0${NC}"
|
||||
echo -e "${YELLOW}Found: $FIRST_LINE${NC}"
|
||||
fi
|
||||
|
||||
echo -e "${CYAN}[3/4]${NC} Staging changes..."
|
||||
git add FlexLove.lua README.md
|
||||
echo -e "${GREEN}✓ Changes staged${NC}"
|
||||
|
||||
echo ""
|
||||
echo -e "${CYAN}Changes to be committed:${NC}"
|
||||
git diff --cached --stat
|
||||
echo ""
|
||||
|
||||
echo -e "${YELLOW}Ready to commit and create tag${NC}"
|
||||
echo -e "${CYAN}Commit message:${NC} v${NEW_VERSION} release"
|
||||
echo -e "${CYAN}Tag:${NC} v${NEW_VERSION}"
|
||||
echo ""
|
||||
read -p "Commit changes and create tag? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo -e "${YELLOW}Changes staged but not committed${NC}"
|
||||
echo "You can:"
|
||||
echo " - Review changes: git diff --cached"
|
||||
echo " - Commit manually: git commit -m 'v${NEW_VERSION} release'"
|
||||
echo " - Unstage: git restore --staged FlexLove.lua README.md"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Commit changes
|
||||
echo ""
|
||||
echo -e "${CYAN}[4/4]${NC} Committing and tagging..."
|
||||
git commit -m "v${NEW_VERSION} release"
|
||||
git tag -a "v${NEW_VERSION}" -m "Release version ${NEW_VERSION}"
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}═══════════════════════════════════════${NC}"
|
||||
echo -e "${GREEN}✓ Version bump complete!${NC}"
|
||||
echo -e "${GREEN}═══════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
echo -e "${CYAN}Version:${NC} ${CURRENT_VERSION} → ${GREEN}${NEW_VERSION}${NC}"
|
||||
echo -e "${CYAN}Tag created:${NC} ${GREEN}v${NEW_VERSION}${NC}"
|
||||
echo ""
|
||||
echo -e "${BLUE}Release will be available at:${NC}"
|
||||
echo " https://github.com/$(git remote get-url origin | sed 's/.*github.com[:/]\(.*\)\.git/\1/')/releases/tag/v${NEW_VERSION}"
|
||||
echo ""
|
||||
Reference in New Issue
Block a user