Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 112 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
[![PyPI version](https://badge.fury.io/py/article-cli.svg)](https://badge.fury.io/py/article-cli)
[![Python Support](https://img.shields.io/pypi/pyversions/article-cli.svg)](https://pypi.org/project/article-cli/)

A command-line tool for managing LaTeX articles with git integration and Zotero bibliography synchronization.
A command-line tool for managing LaTeX articles and presentations with git integration and Zotero bibliography synchronization.

## Features

- **Repository Initialization**: Complete setup for LaTeX article projects with one command
- **LaTeX Compilation**: Compile documents with latexmk/pdflatex, watch mode, shell escape support
- **GitHub Actions Workflows**: Automated PDF compilation, artifact upload, and GitHub releases
- **Repository Initialization**: Complete setup for LaTeX article or presentation projects with one command
- **Project Types**: Support for articles, Beamer presentations, and posters
- **LaTeX Compilation**: Compile documents with latexmk/pdflatex/xelatex/lualatex, watch mode, shell escape support
- **Font Installation**: Download and install fonts for XeLaTeX projects (Marianne, Roboto Mono, etc.)
- **GitHub Actions Workflows**: Automated PDF compilation with XeLaTeX support, artifact upload, and GitHub releases
- **Git Release Management**: Create, list, and delete releases with gitinfo2 support
- **Zotero Integration**: Synchronize bibliography from Zotero with robust pagination and error handling
- **LaTeX Build Management**: Clean build files and manage LaTeX compilation artifacts
Expand Down Expand Up @@ -113,6 +115,24 @@ default_branch = "main"

[latex]
clean_extensions = [".aux", ".bbl", ".blg", ".log", ".out", ".synctex.gz"]

[fonts]
directory = "fonts"

[fonts.sources]
marianne = "https://github.com/ArnaudBelcworking/Marianne/archive/refs/heads/master.zip"
roboto-mono = "https://github.com/googlefonts/RobotoMono/releases/download/v3.000/RobotoMono-v3.000.zip"

[themes]
directory = "."

# Custom theme sources (numpex is built-in)
# [themes.sources.my-theme]
# url = "https://example.com/theme.zip"
# description = "My custom theme"
# files = ["beamerthememytheme.sty"]
# requires_fonts = false
# engine = "pdflatex"
```

## Usage
Expand All @@ -123,6 +143,12 @@ clean_extensions = [".aux", ".bbl", ".blg", ".log", ".out", ".synctex.gz"]
# Initialize a new article repository (auto-detects main .tex file)
article-cli init --title "My Article Title" --authors "John Doe,Jane Smith"

# Initialize a Beamer presentation project
article-cli init --title "My Presentation" --authors "Author" --type presentation

# Initialize with numpex theme (requires theme files from presentation.template.d)
article-cli init --title "NumPEx Talk" --authors "Author" --type presentation --theme numpex

# Specify custom Zotero group ID
article-cli init --title "My Article" --authors "Author" --group-id 1234567

Expand All @@ -134,11 +160,12 @@ article-cli init --title "My Article" --authors "Author" --force
```

The `init` command sets up:
- **GitHub Actions workflow** for automated PDF compilation and releases
- **GitHub Actions workflow** for automated PDF compilation and releases (with XeLaTeX support for presentations)
- **pyproject.toml** with dependencies and article-cli configuration
- **README.md** with comprehensive documentation
- **.gitignore** with LaTeX-specific patterns
- **VS Code configuration** for LaTeX Workshop with auto-build and SyncTeX
- **Font configuration** (for presentation projects using custom themes)

### Git Release Management

Expand Down Expand Up @@ -178,6 +205,12 @@ article-cli compile main.tex
# Compile with pdflatex engine
article-cli compile --engine pdflatex

# Compile with XeLaTeX (for custom fonts)
article-cli compile --engine xelatex

# Compile with LuaLaTeX
article-cli compile --engine lualatex

# Enable shell escape (for code highlighting, etc.)
article-cli compile --shell-escape

Expand All @@ -191,6 +224,64 @@ article-cli compile --clean-first --clean-after
article-cli compile --output-dir build/
```

### Font Installation

Install fonts for XeLaTeX projects (useful for custom Beamer themes):

```bash
# Install default fonts (Marianne, Roboto Mono) to fonts/ directory
article-cli install-fonts

# Install to a custom directory
article-cli install-fonts --dir custom-fonts/

# Force re-download even if fonts exist
article-cli install-fonts --force

# List installed fonts
article-cli install-fonts --list
```

**Default fonts:**
- **Marianne**: French government official font
- **Roboto Mono**: Google's monospace font for code

### Theme Installation

Install Beamer themes for presentations:

```bash
# List available themes
article-cli install-theme --list

# Install numpex theme (NumPEx Beamer theme)
article-cli install-theme numpex

# Install to a custom directory
article-cli install-theme numpex --dir themes/

# Force re-download even if theme exists
article-cli install-theme numpex --force

# Install from a custom URL
article-cli install-theme my-theme --url https://example.com/theme.zip
```

**Available themes:**
- **numpex**: NumPEx Beamer theme following French government visual identity (requires XeLaTeX and custom fonts)

**Complete presentation setup:**
```bash
# 1. Install the theme
article-cli install-theme numpex

# 2. Install required fonts
article-cli install-fonts

# 3. Compile with XeLaTeX
article-cli compile presentation.tex --engine xelatex
```

### Project Setup

```bash
Expand Down Expand Up @@ -237,6 +328,22 @@ MIT License - see LICENSE file for details.

## Changelog

### v1.2.0
- Add font installation command (`install-fonts`) for XeLaTeX projects
- Support Marianne and Roboto Mono fonts by default
- Add theme installation command (`install-theme`) for Beamer presentations
- Built-in support for numpex theme with automatic download
- Extended GitHub Actions workflow with XeLaTeX and multi-document support
- Add presentation project type with Beamer template support
- Add `--engine` option for xelatex and lualatex compilation
- Improved CI/CD with font installation steps

### v1.1.0
- Add `init` command for repository initialization
- Add `compile` command with watch mode and multiple engines
- GitHub Actions workflow generation
- VS Code configuration generation

### v1.0.0
- Initial release
- Git release management
Expand Down
97 changes: 97 additions & 0 deletions src/article_cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ def create_parser() -> argparse.ArgumentParser:
%(prog)s config create # Create sample config file
%(prog)s install-fonts # Install fonts for XeLaTeX
%(prog)s install-fonts --list # List installed fonts
%(prog)s install-theme numpex # Install numpex Beamer theme
%(prog)s install-theme --list # List available themes

Environment variables:
ZOTERO_API_KEY : Your Zotero API key (required for update-bibtex)
Expand Down Expand Up @@ -207,6 +209,36 @@ def create_parser() -> argparse.ArgumentParser:
help="List installed fonts instead of installing",
)

# Install-theme command
theme_parser = subparsers.add_parser(
"install-theme", help="Download and install Beamer themes for presentations"
)
theme_parser.add_argument(
"theme_name",
nargs="?",
help="Name of theme to install (e.g., 'numpex')",
)
theme_parser.add_argument(
"--dir",
type=Path,
help="Directory to install theme (default: current directory)",
)
theme_parser.add_argument(
"--force",
action="store_true",
help="Re-download theme even if already installed",
)
theme_parser.add_argument(
"--list",
action="store_true",
dest="list_themes",
help="List available themes instead of installing",
)
theme_parser.add_argument(
"--url",
help="Custom URL to download theme from (use with theme_name)",
)

return parser


Expand Down Expand Up @@ -496,6 +528,68 @@ def handle_install_fonts_command(args: argparse.Namespace, config: Config) -> in
return 1


def handle_install_theme_command(args: argparse.Namespace, config: Config) -> int:
"""Handle the install-theme command"""
try:
from .themes import ThemeInstaller

themes_config = config.get_themes_config()

# Override directory if specified on command line
themes_dir = args.dir if args.dir else Path(themes_config.get("directory", "."))

# Get configured sources
sources = themes_config.get("sources", {})

installer = ThemeInstaller(themes_dir=themes_dir, sources=sources)

# List available themes if requested
if args.list_themes:
available = installer.list_available()
installed = installer.list_installed()

print_info("Available themes:")
for theme in available:
name = theme["name"]
desc = theme.get("description", "")
engine = theme.get("engine", "pdflatex")
fonts = (
" (requires custom fonts)" if theme.get("requires_fonts") else ""
)
installed_marker = (
" [installed]" if any(i["name"] == name for i in installed) else ""
)
print(f" - {name}: {desc}")
print(f" Engine: {engine}{fonts}{installed_marker}")

return 0

# Theme name is required for installation
if not args.theme_name:
print_error("Theme name is required. Use --list to see available themes.")
return 1

# Install from custom URL if provided
if args.url:
success = installer.install_from_url(
name=args.theme_name,
url=args.url,
force=args.force,
)
else:
# Install from known sources
success = installer.install_theme(
name=args.theme_name,
force=args.force,
)

return 0 if success else 1

except Exception as e:
print_error(f"Theme installation failed: {e}")
return 1


def main(argv: Optional[list] = None) -> int:
"""
Main entry point for article-cli
Expand Down Expand Up @@ -552,6 +646,9 @@ def main(argv: Optional[list] = None) -> int:
elif args.command == "install-fonts":
return handle_install_fonts_command(args, config)

elif args.command == "install-theme":
return handle_install_theme_command(args, config)

else:
print_error(f"Unknown command: {args.command}")
return 1
Expand Down
37 changes: 37 additions & 0 deletions src/article_cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,29 @@ def get_fonts_config(self) -> Dict[str, Any]:
"sources": self.get("fonts", "sources", default_sources),
}

def get_themes_config(self) -> Dict[str, Any]:
"""Get theme installation configuration"""
# Default theme sources
default_sources = {
"numpex": {
"url": "https://github.com/numpex/presentation.template.d/archive/refs/heads/main.zip",
"description": "NumPEx Beamer theme following French government visual identity",
"files": [
"beamerthemenumpex.sty",
"beamercolorthemenumpex.sty",
"beamerfontthemenumpex.sty",
],
"directories": ["images"],
"requires_fonts": True,
"engine": "xelatex",
},
}

return {
"directory": self.get("themes", "directory", "."),
"sources": self.get("themes", "sources", default_sources),
}

def validate_zotero_config(
self, args: argparse.Namespace
) -> Dict[str, Optional[str]]:
Expand Down Expand Up @@ -399,6 +422,20 @@ def create_sample_config(self, path: Optional[Path] = None) -> Path:
# name = "Roboto Mono"
# url = "https://fonts.google.com/download?family=Roboto+Mono"
# description = "Google's monospace font"

# Theme installation settings (for Beamer presentations)
[themes]
# Directory to install themes (default: current directory)
directory = "."

# Theme sources (default: numpex theme)
# [themes.sources.numpex]
# url = "https://github.com/numpex/presentation.template.d/archive/refs/heads/main.zip"
# description = "NumPEx Beamer theme"
# files = ["beamerthemenumpex.sty", "beamercolorthemenumpex.sty", "beamerfontthemenumpex.sty"]
# directories = ["images"]
# requires_fonts = true
# engine = "xelatex"
"""

try:
Expand Down
Loading