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
|
tasks
|
||||||
testoutput
|
testoutput
|
||||||
luacov.*
|
luacov.*
|
||||||
|
docs/doc.json
|
||||||
|
docs/doc.md
|
||||||
|
docs/node_modules
|
||||||
|
releases/
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ Units.initialize(Context)
|
|||||||
Units.initializeErrorHandler(ErrorHandler)
|
Units.initializeErrorHandler(ErrorHandler)
|
||||||
|
|
||||||
-- Add version and metadata
|
-- Add version and metadata
|
||||||
flexlove._VERSION = "0.2.0"
|
flexlove._VERSION = "0.2.1"
|
||||||
flexlove._DESCRIPTION = "UI Library for LÖVE Framework based on flexbox"
|
flexlove._DESCRIPTION = "0I Library for LÖVE Framework based on flexbox"
|
||||||
flexlove._URL = "https://github.com/mikefreno/FlexLove"
|
flexlove._URL = "https://github.com/mikefreno/FlexLove"
|
||||||
flexlove._LICENSE = [[
|
flexlove._LICENSE = [[
|
||||||
MIT 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.**
|
**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
|
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
|
## API Conventions
|
||||||
|
|
||||||
### Method Patterns
|
### 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
|
## Files
|
||||||
|
|
||||||
|
- **api.html** - Beautiful, searchable API documentation (2.2MB)
|
||||||
- **index.html** - GitHub Pages landing page
|
- **index.html** - GitHub Pages landing page
|
||||||
- **doc.md** - Markdown API reference (47,000+ lines)
|
- **build-docs.js** - Node.js script to convert markdown to HTML
|
||||||
- **doc.json** - JSON API reference for tooling (11MB)
|
- **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
|
## Regenerating Documentation
|
||||||
|
|
||||||
To regenerate the documentation after making changes:
|
To regenerate the documentation after making changes:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./generate_docs.sh
|
./scripts/generate_docs.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
Or manually:
|
This will:
|
||||||
|
1. Extract version from `FlexLove.lua` (single source of truth)
|
||||||
```bash
|
2. Generate markdown from LuaLS annotations
|
||||||
lua-language-server --doc=. --doc_out_path=./docs
|
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
|
## Viewing Locally
|
||||||
|
|
||||||
@@ -66,4 +71,66 @@ The documentation is generated from LuaLS (Lua Language Server) annotations usin
|
|||||||
|
|
||||||
## Requirements
|
## 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
|
16
|
||||||
],
|
],
|
||||||
"type": "doc.type.table",
|
"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",
|
"file": "modules/Animation.lua",
|
||||||
"finish": [
|
"finish": [
|
||||||
@@ -446,7 +446,7 @@
|
|||||||
10
|
10
|
||||||
],
|
],
|
||||||
"type": "doc.field",
|
"type": "doc.field",
|
||||||
"view": "{ width: number?, height: number?, opacity: number? }",
|
"view": "{ width: number, height: number, opacity: number }",
|
||||||
"visible": "public"
|
"visible": "public"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -736,10 +736,10 @@
|
|||||||
16
|
16
|
||||||
],
|
],
|
||||||
"type": "doc.type.table",
|
"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",
|
"file": "modules/Animation.lua",
|
||||||
"finish": [
|
"finish": [
|
||||||
@@ -752,7 +752,7 @@
|
|||||||
10
|
10
|
||||||
],
|
],
|
||||||
"type": "doc.field",
|
"type": "doc.field",
|
||||||
"view": "{ width: number?, height: number?, opacity: number? }",
|
"view": "{ width: number, height: number, opacity: number }",
|
||||||
"visible": "public"
|
"visible": "public"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ function Animation.fade(duration: number, fromOpacity: number, toOpacity: number
|
|||||||
|
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
{ width: number?, height: number?, opacity: number? }
|
{ width: number, height: number, opacity: number }
|
||||||
```
|
```
|
||||||
|
|
||||||
## interpolate
|
## interpolate
|
||||||
@@ -86,7 +86,7 @@ function Animation.scale(duration: number, fromScale: table, toScale: table)
|
|||||||
|
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
{ width: number?, height: number?, opacity: number? }
|
{ width: number, height: number, opacity: number }
|
||||||
```
|
```
|
||||||
|
|
||||||
## transform
|
## transform
|
||||||
|
|||||||
1075
docs/examples.html
Normal file
1075
docs/examples.html
Normal file
File diff suppressed because it is too large
Load Diff
212
docs/index.html
212
docs/index.html
@@ -1,15 +1,19 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>FlexLöve Documentation</title>
|
<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>
|
<style>
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif;
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans",
|
||||||
|
Helvetica, Arial, sans-serif;
|
||||||
background-color: #0d1117;
|
background-color: #0d1117;
|
||||||
color: #c9d1d9;
|
color: #c9d1d9;
|
||||||
}
|
}
|
||||||
@@ -75,22 +79,84 @@
|
|||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
border: 1px solid #30363d;
|
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 {
|
.feature-card h3 {
|
||||||
color: #58a6ff;
|
color: #58a6ff;
|
||||||
margin-top: 0;
|
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 {
|
code {
|
||||||
background-color: #161b22;
|
background-color: #161b22;
|
||||||
padding: 0.2rem 0.4rem;
|
padding: 0.2rem 0.4rem;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
|
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo,
|
||||||
|
monospace;
|
||||||
}
|
}
|
||||||
pre {
|
pre {
|
||||||
background-color: #161b22;
|
background-color: #161b22;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
overflow-x: auto;
|
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 {
|
.footer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -111,40 +177,59 @@
|
|||||||
<div class="nav">
|
<div class="nav">
|
||||||
<a href="https://github.com/mikefreno/FlexLove">GitHub</a>
|
<a href="https://github.com/mikefreno/FlexLove">GitHub</a>
|
||||||
<a href="#getting-started">Getting Started</a>
|
<a href="#getting-started">Getting Started</a>
|
||||||
<a href="doc.md">API Reference (Markdown)</a>
|
<a href="examples.html">Examples</a>
|
||||||
<a href="doc.json">API Reference (JSON)</a>
|
<a href="api.html">API Reference</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
|
<h2 style="text-align: center; margin-bottom: 2rem">✨ Features</h2>
|
||||||
<div class="features">
|
<div class="features">
|
||||||
<div class="feature-card">
|
<a href="examples.html#layout" class="feature-card">
|
||||||
<h3>🎨 Flexbox & Grid Layouts</h3>
|
<h3>🎨 Flexbox & Grid Layouts</h3>
|
||||||
<p>Modern CSS-like layout system with full flexbox and grid support for building responsive UIs.</p>
|
<p>
|
||||||
</div>
|
Modern CSS-like layout system with full flexbox and grid support
|
||||||
<div class="feature-card">
|
for building responsive UIs.
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
<a href="examples.html#theme" class="feature-card">
|
||||||
<h3>🎭 Theme System</h3>
|
<h3>🎭 Theme System</h3>
|
||||||
<p>9-patch NinePatch theming with state support (normal, hover, pressed, disabled).</p>
|
<p>
|
||||||
</div>
|
9-patch NinePatch theming with state support (normal, hover,
|
||||||
<div class="feature-card">
|
pressed, disabled).
|
||||||
<h3>✨ Animations</h3>
|
</p>
|
||||||
<p>Built-in animation support for smooth transitions and effects with easing functions.</p>
|
</a>
|
||||||
</div>
|
<a href="examples.html#state" class="feature-card">
|
||||||
<div class="feature-card">
|
<h3>✨ State Management</h3>
|
||||||
<h3>📱 Responsive Design</h3>
|
<p>
|
||||||
<p>Viewport units (vw, vh, %) for automatic resizing and responsive layouts.</p>
|
Interactive components with state tracking, counters, toggles, and
|
||||||
</div>
|
dynamic updates.
|
||||||
<div class="feature-card">
|
</p>
|
||||||
<h3>⚡ Immediate Mode</h3>
|
</a>
|
||||||
<p>Optional immediate mode support alongside traditional retained mode rendering.</p>
|
<a href="examples.html#scroll" class="feature-card">
|
||||||
</div>
|
<h3>📜 Scrollable Content</h3>
|
||||||
<div class="feature-card">
|
<p>
|
||||||
<h3>🎯 Event System</h3>
|
Smooth scrolling containers with backdrop blur effects and
|
||||||
<p>Rich event handling with callbacks, focus management, and input fields.</p>
|
overflow handling for long content lists.
|
||||||
</div>
|
</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>
|
</div>
|
||||||
|
|
||||||
<div class="section markdown-body" id="getting-started">
|
<div class="section" id="getting-started">
|
||||||
<h2>Quick Start</h2>
|
<h2>Quick Start</h2>
|
||||||
<pre><code class="language-lua">local FlexLove = require("FlexLove")
|
<pre><code class="language-lua">local FlexLove = require("FlexLove")
|
||||||
|
|
||||||
@@ -176,27 +261,68 @@ function love.draw()
|
|||||||
end</code></pre>
|
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">
|
<div class="section">
|
||||||
<h2>Installation</h2>
|
<h2>Installation</h2>
|
||||||
<p>Add the <code>modules</code> directory and <code>FlexLove.lua</code> into your LÖVE project.</p>
|
<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
|
<pre><code>git clone https://github.com/mikefreno/FlexLove.git
|
||||||
cp -r FlexLove/modules your-project/
|
cp -r FlexLove/modules your-project/
|
||||||
cp FlexLove/FlexLove.lua your-project/</code></pre>
|
cp FlexLove/FlexLove.lua your-project/</code></pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="footer">
|
<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>
|
<p>
|
||||||
|
FlexLöve v0.2.0 | MIT License |
|
||||||
|
<a href="https://github.com/mikefreno/FlexLove" style="color: #58a6ff"
|
||||||
|
>GitHub Repository</a
|
||||||
|
>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<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>
|
</body>
|
||||||
</html>
|
</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