# airun-hwp

AI-powered HWP/HWPX document processing library for Hamonize

[![Python Version](https://img.shields.io/badge/python-3.8%2B-blue.svg)](https://python.org)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
[![PyPI Version](https://img.shields.io/pypi/v/airun-hwp.svg)](https://pypi.org/project/airun-hwp/)
[![Downloads](https://img.shields.io/pypi/dm/airun-hwp.svg)](https://pypi.org/project/airun-hwp/)

Convert HWP/HWPX documents with ease! 📄

airun-hwp is a powerful tool that converts Hancom Office HWP/HWPX files to Markdown and PDF formats.

## ⚡ Quick Start

```bash
# Install
pip install airun-hwp

# Convert (creates both Markdown and PDF)
airun-hwp document.hwpx

# Convert to PDF only
airun-hwp document.hwpx --format pdf
```

## ✨ Features

- **HWP Document Conversion**: Convert HWPX files to Markdown, PDF
- **Image Extraction**: Automatically extract images from documents
- **Table Processing**: Preserve table structure during conversion
- **Simple CLI**: Easy-to-use command-line interface
- **Auto-completion**: Tab completion support in bash/zsh

## 📦 Installation

```bash
pip install airun-hwp
```

PDF export functionality is included by default.

### Installation from Source

For the latest features before PyPI release:

```bash
git clone https://github.com/chaeya/airun-hwp.git
cd airun-hwp
pip install .
```

### For Developers

For contributors:

```bash
git clone https://github.com/chaeya/airun-hwp.git
cd airun-hwp
pip install -e ".[dev]"
```

## 🚀 Usage

### Command Line Interface

```bash
# Basic usage (creates both Markdown and PDF)
airun-hwp document.hwpx

# Convert to specific format
airun-hwp document.hwpx --format pdf
airun-hwp document.hwpx -f markdown

# Specify output directory
airun-hwp document.hwpx --format pdf --output ./results
airun-hwp document.hwpx -o ./output_folder

# Auto-detect best PDF engine (recommended)
airun-hwp document.hwpx --format pdf --pdf-engine auto

# Use LibreOffice for PDF conversion (preserves original formatting)
airun-hwp document.hwpx --format pdf --pdf-engine libreoffice

# Use WeasyPrint (fast, but limited formatting)
airun-hwp document.hwpx --format pdf --pdf-engine weasyprint

# Adjust LibreOffice conversion timeout (default: 30 seconds)
airun-hwp large_document.hwpx --format pdf --pdf-engine libreoffice --timeout 60

# Get help
airun-hwp --help
```

### PDF Conversion Engines

`airun-hwp` supports three PDF conversion engine modes:

| Mode | Description | Formatting Preservation | Speed | LibreOffice Required |
|------|-------------|------------------------|-------|---------------------|
| **auto** (default) | Auto-detects best engine | Auto-selects | Auto | Auto |
| **libreoffice** | Direct HWPX → PDF | Excellent (⭐⭐⭐⭐) | Moderate | ✅ Yes |
| **weasyprint** | Markdown → HTML → PDF | Basic (⭐⭐) | Fast | ❌ No |

#### Auto Mode (Recommended)
- ✅ Automatically detects LibreOffice availability
- ✅ Falls back to WeasyPrint if LibreOffice not found
- ✅ Best of both worlds
- **Best for**: All scenarios, lets the tool decide

#### WeasyPrint Mode
- ✅ Fast conversion
- ✅ No external dependencies
- ✅ Pure Python solution
- ⚠️ Limited formatting preservation
- **Best for**: Simple documents, quick conversions, environments without LibreOffice

#### LibreOffice Mode
- ✅ **Preserves original formatting**
- ✅ Better font support
- ✅ Accurate page layout
- ✅ Superior table rendering
- Requires: LibreOffice with HWP support (usually pre-installed on Linux)
- **Best for**: Complex documents, official files, formatting-critical tasks

**Note**: Use `--pdf-engine auto` to let the tool automatically choose the best available engine.

## 🔧 Shell Auto-completion

The CLI supports tab completion for bash, zsh, and fish shells. This makes it easier to use the command-line interface without remembering all options.

### Automatic Installation (Recommended)

Run the completion installer after installing the package:

```bash
# Install completion automatically (detects your shell)
airun-hwp completion install

# Or manually run:
python -c "from airun_hwp.cli_simple import install; install()"
```

The installer will:
- Detect your current shell (bash or zsh)
- Add completion script to your shell configuration file
- Show you how to activate it

### Manual Setup

#### Bash

Add this line to your `~/.bashrc`:

```bash
eval "$(_AIRUN_HWP_COMPLETE=bash_source airun-hwp)"
```

Then reload your shell:

```bash
source ~/.bashrc
```

#### Zsh

Add this line to your `~/.zshrc`:

```bash
eval "$(_AIRUN_HWP_COMPLETE=zsh_source airun-hwp)"
```

Then reload your shell:

```bash
source ~/.zshrc
```

#### Fish

Create a completion file:

```bash
mkdir -p ~/.config/fish/completions
airun-hwp --completion=bash > ~/.config/fish/completions/airun-hwp.fish
```

### Using Completion

Once enabled, you can use tab completion:

```bash
# File completion
airun-hwp doc<TAB>
# document.hwpx  report.hwpx  ...

# Option completion
airun-hwp <TAB>
# --format  --help  --output

# Option value completion
airun-hwp --format <TAB>
# all  markdown  md  pdf
```

## 📘 Python API

```python
from airun_hwp.reader.hwpx_reader_ordered import HWPXReaderOrdered
from airun_hwp.reader.hwpx_to_markdown import extract_text_from_file

# Parse HWPX file (full structure preserved)
reader = HWPXReaderOrdered()
document = reader.parse("document.hwpx")

# Extract text
text = document.get_all_text()
print(f"Total text length: {len(text)} characters")

# Extract images
images = document.extract_images("./output/images")
print(f"Extracted {len(images)} images")

# Convert to Markdown with tables
markdown_content = document.to_markdown_ordered(
    include_metadata=True,
    images_dir="./output/images"
)

# Save Markdown
with open("document.md", "w", encoding="utf-8") as f:
    f.write(markdown_content)

# For HWP files (plain text only)
hwp_text = extract_text_from_file("document.hwp")
print(f"HWP text (tables not preserved): {len(hwp_text)} characters")
```

## Advanced Usage

### PDF Generation with Custom Styling

```python
import markdown
import weasyprint
from airun_hwp.reader.hwpx_reader_ordered import HWPXReaderOrdered

# Parse document
reader = HWPXReaderOrdered()
document = reader.parse("document.hwpx")

# Extract images
document.extract_images("./output/images")

# Get Markdown content
md_content = document.to_markdown_ordered(
    include_metadata=True,
    images_dir="./output/images"
)

# Convert to HTML
html = markdown.markdown(md_content, extensions=['tables', 'fenced_code'])

# Add custom CSS
css = """
<style>
    body { font-family: 'Malgun Gothic', Arial, sans-serif; }
    img { max-width: 100%; height: auto; }
    table { border-collapse: collapse; width: 100%; }
    th, td { border: 1px solid #333; padding: 8px; }
</style>
"""

# Generate PDF
pdf = weasyprint.HTML(string=css + html).write_pdf("document.pdf")
```

## Document Structure

The library processes HWPX documents using a token-stream approach that preserves the original document order:

- **Text Runs**: Consecutive text segments
- **Images**: Embedded images with proper positioning
- **Tables**: Structured table data
- **Paragraph Breaks**: Logical document divisions
- **Page Breaks**: Document pagination

## HWP vs HWPX: Important Differences

This library handles HWP and HWPX files differently due to their fundamental format differences:

### HWPX Files (Recommended)
- **Format**: XML-based, open standard
- **Structure**: Preserves full document structure
- **Tables**: ✅ Extracted with proper formatting
- **Images**: ✅ Extracted with positioning
- **Layout**: Maintains original document flow

### HWP Files (Limited Support)
- **Format**: Binary, proprietary format
- **Structure**: Only plain text extraction available
- **Tables**: ❌ Not preserved (extracted as plain text only)
- **Images**: ❌ Cannot preserve original position/sequence
- **Layout**: Original structure and order lost

### Recommendation
For best results, use HWPX files. If you have HWP files:
1. Convert HWP to HWPX in Hanword (한글) before processing
2. Or use for plain text extraction only

## Output Structure

When processing a document named `document.hwpx`:

```
output/
└── document/
    ├── images/
    │   ├── image1.png
    │   ├── image2.png
    │   └── ...
    ├── document.md
    └── document.pdf
```

## Dependencies

- `pypandoc-hwpx>=0.1.0`: HWPX file format support
- `PyYAML>=6.0`: YAML configuration parsing
- `Pillow>=10.0.0`: Image processing
- `weasyprint>=60.0`: HTML to PDF conversion (included)
- `markdown>=3.5.0`: Markdown processing (included)
- `click>=8.0.0`: Command-line interface with auto-completion support

## 📄 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## 🤝 Contributing

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## 🆘 Support

- 📧 Email: chaeya@gmail.com (Kevin Kim)
- 🐛 Report bugs: [GitHub Issues](https://github.com/chaeya/airun-hwp/issues)
- 📖 Documentation: [GitHub Wiki](https://github.com/chaeya/airun-hwp/wiki)

## Changelog

### Version 0.3.0
- Simplified CLI interface: use `airun-hwp document.hwpx` directly
- Removed subcommands (`convert`, `process`) for cleaner UX
- Default behavior creates both Markdown and PDF
- Added shell auto-completion support (bash, zsh, fish)
- Cleaner, more user-focused README

### Version 0.2.9
- Simplified CLI interface: removed subcommands for direct usage
- Now use `airun-hwp document.hwpx` instead of `airun-hwp convert document.hwpx`
- Default behavior creates both Markdown and PDF outputs
- Added `--format all` option (default) for creating both formats
- Maintained backward compatibility with deprecated subcommands
- Cleaner and more intuitive command-line experience

### Version 0.2.8
- Added shell auto-completion support for bash, zsh, and fish
- Migrated CLI from argparse to Click for better user experience
- Added automatic completion installer (`airun-hwp-completion`)
- Enhanced CLI with tab completion for commands and options
- Improved error messages with Click's formatting

### Version 0.2.7
- Fixed PyPI publishing workflow with Trusted Publishing
- Fixed license format for Python 3.8 compatibility
- Updated build configuration

### Version 0.2.5
- Fixed `get_all_text()` method to properly extract text from token stream
- Improved text extraction to handle both tokens and paragraphs
- Added deduplication to prevent duplicate text extraction
- Updated documentation to clarify HWP vs HWPX limitations

### Version 0.2.0
- HWPX parsing support
- Markdown conversion
- PDF export functionality
- CLI tool
- Image extraction
- Table processing

### Version 0.1.0
- Initial release

---

**Made with ❤️ for the Hamonize project**