From e225bf8da7aa316ca93daf9f9cb82a440095218d Mon Sep 17 00:00:00 2001
From: Vladimir <48120135+izmalk@users.noreply.github.com>
Date: Mon, 2 Feb 2026 14:14:46 +0000
Subject: [PATCH 1/2] Hugo PoC demo
---
.gitignore | 9 +
CONTRIBUTING.md | 10 +-
HUGO_QUICKREF.md | 69 ++
HUGO_README.md | 77 ++
MIGRATION_SUMMARY.md | 170 +++
cleanup-jekyll.sh | 34 +
content/_index.html | 188 +++
.../documentation/01-printer-application.md | 132 +++
.../02-designing-printer-drivers.md | 1050 +++++++++++++++++
.../03-designing-scanner-drivers.md | 106 ++
content/documentation/04-packaging-drivers.md | 306 +++++
content/documentation/05-User-Manual.md | 409 +++++++
content/documentation/_index.md | 7 +
hugo.toml | 35 +
layouts/_default/baseof.html | 26 +
layouts/_default/list.html | 35 +
layouts/_default/single.html | 3 +
layouts/index.html | 1 +
static/css/style.css | 112 ++
19 files changed, 2774 insertions(+), 5 deletions(-)
create mode 100644 HUGO_QUICKREF.md
create mode 100644 HUGO_README.md
create mode 100644 MIGRATION_SUMMARY.md
create mode 100755 cleanup-jekyll.sh
create mode 100644 content/_index.html
create mode 100644 content/documentation/01-printer-application.md
create mode 100644 content/documentation/02-designing-printer-drivers.md
create mode 100644 content/documentation/03-designing-scanner-drivers.md
create mode 100644 content/documentation/04-packaging-drivers.md
create mode 100644 content/documentation/05-User-Manual.md
create mode 100644 content/documentation/_index.md
create mode 100644 hugo.toml
create mode 100644 layouts/_default/baseof.html
create mode 100644 layouts/_default/list.html
create mode 100644 layouts/_default/single.html
create mode 100644 layouts/index.html
create mode 100644 static/css/style.css
diff --git a/.gitignore b/.gitignore
index 17692e16..9136b28e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,3 +30,12 @@ _site/
.jekyll-cache/
.jekyll-metadata
Gemfile.lock
+
+# Hugo build artifacts
+/public/
+/resources/_gen/
+/assets/jsconfig.json
+hugo_stats.json
+
+# Hugo module dependencies
+.hugo_build.lock
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 7e564ad7..48ec040b 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -3,17 +3,17 @@
Help from community is necessary to make any opensource project great. We want to keep it as easy as possible for community to contribute changes. There are a few guidlines that we need to follow so that it is easy for others to understand and change the codebase.
### Getting Started
-* Setup jekyll environment. You can follow [this link](https://jekyllrb.com/docs/).
-* Now, you have a working jekyll environment. Clone the source code from [github](https://github.com/OpenPrinting/openprinting.github.io).
+* Install Hugo. You can follow [this link](https://gohugo.io/installation/).
+* Now, you have Hugo installed. Clone the source code from [github](https://github.com/OpenPrinting/openprinting.github.io).
* Go to the directory and run:
```
-bundle exec jekyll serve
+hugo server
```
* If you want to access website from some other device on local network, use:
```
-bundle exec jekyll serve --host=0.0.0.0
+hugo server --bind 0.0.0.0
```
-* Open ``` localhost:4000 ```
+* Open ``` localhost:1313 ```
### Issues
* If you want to work on some issue, first comment on that issue that you want to work.
diff --git a/HUGO_QUICKREF.md b/HUGO_QUICKREF.md
new file mode 100644
index 00000000..b0b901cf
--- /dev/null
+++ b/HUGO_QUICKREF.md
@@ -0,0 +1,69 @@
+# Quick Reference: Hugo Commands
+
+## Development
+```bash
+# Start development server
+hugo server
+
+# Start with network access
+hugo server --bind 0.0.0.0
+
+# Start with drafts visible
+hugo server -D
+
+# Start with live reload
+hugo server --disableFastRender
+```
+
+## Building
+```bash
+# Build for production
+hugo
+
+# Build with minification
+hugo --minify
+
+# Build drafts
+hugo -D
+
+# Clean public directory before build
+hugo --cleanDestinationDir
+```
+
+## Content Management
+```bash
+# Create new page
+hugo new content/page-name.md
+
+# Create new documentation page
+hugo new documentation/new-doc.md
+
+# Create new post
+hugo new posts/my-post.md
+```
+
+## Useful Commands
+```bash
+# Check Hugo version
+hugo version
+
+# List all content
+hugo list all
+
+# Check for errors
+hugo --verbose
+
+# Generate man pages
+hugo gen man
+```
+
+## File Locations
+- **Config**: `hugo.toml`
+- **Content**: `content/`
+- **Templates**: `layouts/`
+- **Static files**: `static/`
+- **Build output**: `public/`
+
+## URLs
+- **Dev server**: http://localhost:1313
+- **Network access**: http://0.0.0.0:1313 or http://[your-ip]:1313
diff --git a/HUGO_README.md b/HUGO_README.md
new file mode 100644
index 00000000..42278476
--- /dev/null
+++ b/HUGO_README.md
@@ -0,0 +1,77 @@
+# OpenPrinting Hugo Migration
+
+This site has been migrated from Jekyll to Hugo.
+
+## Building and Running
+
+### Prerequisites
+Install Hugo (extended version recommended):
+- Linux: `sudo snap install hugo` or download from [Hugo releases](https://github.com/gohugoio/hugo/releases)
+- macOS: `brew install hugo`
+- Windows: `choco install hugo-extended` or `scoop install hugo-extended`
+
+### Development Server
+Run the development server:
+```bash
+hugo server
+```
+
+Access the site at `http://localhost:1313`
+
+To access from other devices on your local network:
+```bash
+hugo server --bind 0.0.0.0
+```
+
+### Building the Site
+Build the static site:
+```bash
+hugo
+```
+
+The built site will be in the `public/` directory.
+
+## Project Structure
+
+```
+.
+├── hugo.toml # Hugo configuration file
+├── content/ # All content files
+│ ├── _index.html # Homepage (HTML file)
+│ └── documentation/ # Documentation pages
+├── layouts/ # HTML templates
+│ ├── _default/ # Default templates
+│ └── index.html # Homepage template
+└── static/ # Static files (images, CSS, JS)
+```
+
+## Content Management
+
+### Adding New Pages
+Create markdown files in the `content/` directory:
+```bash
+hugo new documentation/new-page.md
+```
+
+### Using HTML Files
+Hugo supports HTML files directly. The homepage (`content/_index.html`) is kept as HTML as requested.
+
+## Migration Notes
+
+- Jekyll's `_config.yml` → Hugo's `hugo.toml`
+- Jekyll's `_documentation/` → Hugo's `content/documentation/`
+- Jekyll's front matter remains compatible with Hugo
+- Hugo uses `.Content` instead of Jekyll's `{{ content }}`
+- Hugo templates use Go templating instead of Liquid
+
+## Removed Files
+The following Jekyll-specific files can be removed:
+- `_config.yml`
+- `Gemfile`
+- `Gemfile.lock`
+- Jekyll directories: `_includes/`, `_layouts/`, etc. (if not reused)
+
+## Resources
+- [Hugo Documentation](https://gohugo.io/documentation/)
+- [Hugo Quick Start](https://gohugo.io/getting-started/quick-start/)
+- [Content Management](https://gohugo.io/content-management/)
diff --git a/MIGRATION_SUMMARY.md b/MIGRATION_SUMMARY.md
new file mode 100644
index 00000000..00cdc880
--- /dev/null
+++ b/MIGRATION_SUMMARY.md
@@ -0,0 +1,170 @@
+# Jekyll to Hugo Migration Summary
+
+## ✅ Completed Tasks
+
+### 1. Hugo Setup
+- **Created** [hugo.toml](hugo.toml) - Hugo configuration file
+ - Configured site title, base URL, and parameters
+ - Set up main navigation menu
+ - Enabled unsafe HTML rendering for markdown (to support HTML in markdown files)
+
+### 2. Directory Structure
+Created the following Hugo directory structure:
+```
+content/ # All content files
+├── _index.html # Homepage (self-contained HTML)
+└── documentation/ # Documentation pages
+ ├── _index.md # Documentation landing page
+ └── *.md # Individual documentation pages
+
+layouts/ # HTML templates
+├── _default/
+│ ├── baseof.html # Base template
+│ ├── list.html # List pages template
+│ └── single.html # Single page template
+└── index.html # Homepage template
+
+static/ # Static assets
+└── css/
+ └── style.css # Basic styling
+```
+
+### 3. Content Migration
+- **Homepage**: Converted `index.html` from Jekyll's Liquid templating to pure HTML
+ - Replaced Jekyll includes with inline HTML and CSS
+ - Preserved all content and structure
+ - Made it self-contained with inline styles
+ - Kept front matter for Hugo processing
+
+- **Documentation**: Migrated `_documentation/` folder to `content/documentation/`
+ - All markdown files copied and working with Hugo
+ - Front matter is compatible with Hugo
+
+### 4. Templates Created
+- **baseof.html**: Base layout with header, navigation, main content area, and footer
+- **single.html**: Template for individual pages
+- **list.html**: Template for section pages with automatic listing of subsections and pages
+- **index.html**: Special template for the homepage
+
+### 5. Updated Files
+- **[CONTRIBUTING.md](CONTRIBUTING.md)**: Updated build instructions
+ - Removed Jekyll setup instructions
+ - Added Hugo installation and usage instructions
+ - Updated localhost port (4000 → 1313)
+ - Updated server commands
+
+- **[.gitignore](.gitignore)**: Added Hugo-specific entries
+ - `/public/` (Hugo build output)
+ - `/resources/_gen/` (Hugo generated resources)
+ - `.hugo_build.lock` (Hugo lock file)
+
+### 6. Documentation
+- **[HUGO_README.md](HUGO_README.md)**: Complete Hugo usage guide
+ - Installation instructions
+ - Development server usage
+ - Build instructions
+ - Project structure explanation
+ - Migration notes
+
+## 🔧 How to Use
+
+### Development
+```bash
+hugo server
+# or for network access:
+hugo server --bind 0.0.0.0
+```
+Access at: http://localhost:1313
+
+### Production Build
+```bash
+hugo
+```
+Output in `public/` directory
+
+## 📝 Notes
+
+### About index.html
+The homepage (`content/_index.html`) is kept as a self-contained HTML file as requested. It includes:
+- Inline CSS styling
+- All content directly in the HTML
+- No external template dependencies
+- Hugo still processes the front matter
+
+Hugo handles HTML files natively, so no conversion to markdown was needed.
+
+### Jekyll Files to Remove
+A cleanup script has been created: [cleanup-jekyll.sh](cleanup-jekyll.sh)
+
+The following Jekyll-specific files can be safely removed:
+- `_config.yml` - Jekyll configuration
+- `Gemfile` - Ruby dependencies
+- `Gemfile.lock` - Ruby dependency lock file
+
+The following directories may need manual review before removal:
+- `_includes/` - Jekyll partial templates
+- `_layouts/` - Jekyll layouts (different from Hugo layouts)
+- `_data/` - Jekyll data files
+- `_posts/` - Blog posts (not yet migrated)
+- `_pages/` - Jekyll pages (may need migration)
+- Other underscore-prefixed directories
+
+**⚠️ Important**: Before removing any directories, check if they contain content that needs to be migrated to Hugo's `content/` structure.
+
+## 🎯 What's Working
+
+✅ Homepage loads correctly with all content
+✅ Documentation pages are accessible
+✅ Hugo builds successfully
+✅ Development server runs
+✅ Static files are served
+✅ Navigation menu is functional
+✅ Markdown rendering works
+✅ HTML files are processed correctly
+
+## 📋 Future Enhancements (Optional)
+
+1. **Migrate remaining content**: Posts, pages, GSoC/GSoD content
+2. **Add a theme**: Install a Hugo theme or create a custom one
+3. **Set up CI/CD**: Configure GitHub Actions for automatic deployment
+4. **Add search functionality**: Integrate search (e.g., Algolia, Lunr.js)
+5. **Optimize images**: Use Hugo's image processing features
+6. **Add RSS feeds**: Configure feeds for blog posts
+7. **Implement taxonomies**: Add tags and categories if needed
+
+## 🚀 Deployment
+
+For GitHub Pages deployment:
+1. Build the site: `hugo`
+2. The `public/` directory contains the static site
+3. Configure GitHub Pages to serve from the `public/` directory or set up a GitHub Action
+
+Example GitHub Actions workflow:
+```yaml
+name: Deploy Hugo site to Pages
+
+on:
+ push:
+ branches: ["main"]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: peaceiris/actions-hugo@v2
+ with:
+ hugo-version: 'latest'
+ - run: hugo --minify
+ - uses: peaceiris/actions-gh-pages@v3
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_dir: ./public
+```
+
+## 🆘 Support
+
+For Hugo-specific questions and documentation:
+- [Hugo Documentation](https://gohugo.io/documentation/)
+- [Hugo Discourse Forum](https://discourse.gohugo.io/)
+- [Hugo GitHub Repository](https://github.com/gohugoio/hugo)
diff --git a/cleanup-jekyll.sh b/cleanup-jekyll.sh
new file mode 100755
index 00000000..eb6d3177
--- /dev/null
+++ b/cleanup-jekyll.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# Script to clean up Jekyll-specific files after migration to Hugo
+
+echo "This script will remove Jekyll-specific files from the repository."
+echo "Make sure you have committed any important changes before proceeding."
+echo ""
+read -p "Do you want to continue? (y/n) " -n 1 -r
+echo
+if [[ ! $REPLY =~ ^[Yy]$ ]]
+then
+ exit 1
+fi
+
+echo "Removing Jekyll configuration files..."
+rm -f _config.yml
+rm -f Gemfile
+rm -f Gemfile.lock
+
+echo "The following Jekyll directories can be removed manually if not needed:"
+echo " - _includes/"
+echo " - _layouts/ (Jekyll layouts)"
+echo " - _data/"
+echo " - _posts/"
+echo " - _pages/"
+echo " - _gsoc*/ (if migrated)"
+echo " - _gsod*/ (if migrated)"
+echo " - _driverless/"
+echo " - _projects/"
+echo " - _upcoming-technologies/"
+echo ""
+echo "Note: Some of these directories may still contain important content"
+echo "that needs to be migrated to Hugo's content/ structure."
+echo ""
+echo "Jekyll cleanup completed for configuration files!"
diff --git a/content/_index.html b/content/_index.html
new file mode 100644
index 00000000..acaed659
--- /dev/null
+++ b/content/_index.html
@@ -0,0 +1,188 @@
+---
+title: "OpenPrinting"
+date: 2016-03-23T11:48:41-04:00
+---
+
+
+
+
+
+ OpenPrinting - Making Printing Just Work!
+
+
+
+
Most modern printers work using OpenPrinting software without additional drivers or software.
+ OpenPrinting also hosts a printer compatibility database of legacy printers supported by free software drivers.
+
+
+
+
+
+
Driverless Printers
+
Most modern printers work 'out of the box' with OpenPrinting software. Browse the thousands of driverless printers.
+
+
diff --git a/content/documentation/01-printer-application.md b/content/documentation/01-printer-application.md
new file mode 100644
index 00000000..2bcc7287
--- /dev/null
+++ b/content/documentation/01-printer-application.md
@@ -0,0 +1,132 @@
+---
+title: Printer Applications - A new way to print in Linux
+toc: true
+toc_sticky: true
+---
+
+Ever wondered how a Printer works? What are the different steps involved between the print command and the final output?
+
+The following document contains information about the history of printing and its evolution. It describes Printer Applications. What were the issues with the previous methodologies? How Printer Applications helped in solving them? Why it has been referred to as the "Technology for Future"? In the end, it also contains roles of different entities including OpenPrinting, Manufacturers, and the User.
+
+
+## Brief History
+
+The first release of CUPS was back in 1997. [1] Since then, Printer Drivers consisted of **PPD files** and **CUPS filters**.
+
+**PPD (PostScript Printer Description)** is a decades-old data format created by Adobe, probably together with PostScript or shortly after, to describe capabilities and user-settable options of PostScript printers and which PostScript commands to embed in the print job to execute the option settings.
+
+**PPD files** describe the printer's capabilities and which filters to use to produce the data format needed by the printer.
+
+This format was adopted because in that time printing under Linux and Unix worked via **PostScript**. Applications sent jobs in PostScript which could be understood by PostScript printers. It allowed users to use all PostScript printers directly. The system supports printers, the user uses printers.
+
+**CUPS** made the move from built-in printer drivers in Ghostscript to CUPS filters, with the help of the CUPS Raster device-independent print raster format. CUPS raster drivers used **PPD files** because it used **Ghostscript** or (on IRIX) **Impressario** (a version of Adobe's PostScript interpreter) to produce raster data for printing, and they could use embedded PostScript commands to control page size, colour space, etc. Since both PostScript and raster printers could then use PPD files, Michael Sweet adopted PPD as a common printer description format, which also got used for his company's ESP Print Pro (GUI) software and then later macOS and GNOME/KDE. CUPS provides reserved directories to drop these **PPD files** and **filters** into, so adding a printer driver was rather easy.
+
+Nowadays applications send jobs in PDF and CUPS does the **PDF-centric** processing, already for 8 years, since the first release of cups-filters back in 2012. So PPD files do not really fit in the picture anymore, and they also had their shortcomings, especially being rather unflexible in the possible types of user-settable options. Also, the need to drop filters and PPDs into reserved directories of CUPS makes it difficult to provide CUPS and printer drivers in sandboxed packages, like **Snaps**.
+
+Already several years ago, mainly due to the advent of smartphones and the desire to also print from these devices, printers got equipped with **driverless IPP** printing functionality: [AirPrint](https://support.apple.com/en-in/HT201311)(released in 2010), IPP Everywhere, [Mopria](https://mopria.org/), Wi-Fi Direct Print. These standards are practically all the same, the printer advertises its presence, its network address, and basic capabilities via DNS-SD (aka BonJour, mDNS, zero-conf, implemented with Avahi in Linux), accepts communication and jobs from clients via **IPP (Internet Printing Protocol)**, from the [Printer Working Group](http://www.pwg.org/), supplies complete capability info to clients via IPP and uses only common Page Description Languages (PDLs) for jobs: PDF, Apple Raster, PWG Raster, PCLm.
+
+
+## What is a Printer Application?
+
+A **Printer Application** is a background service, a GUI application, etc. that happens to respond to HTTP and IPP requests. It detects the supported printers and advertises those printers on the localhost as an IPP Everywhere printer. It can also listen on network interfaces (i.e. not just localhost) so provide access to a printer to all client devices on a network. Printer Applications are the recommended architecture for printer drivers.
+
+The Printer Application emulates a driverless IPP printer, so that the printing system does not need to distinguish, it simply needs to support driverless IPP printers. This way we add support for non-driverless printers and avoid deprecated and inconvenient methods, like using PPD (Postscript Printer Description) files on non-PostScript printers but also allow sandboxed packaging which allows providing OS-distribution-independent driver packages and improves security.
+
+In a **sandboxed package**, we cannot modify directory contents once it is built. Our system is no more modular. We cannot choose which printer driver package to install. Printer Applications address this problem of modularity and give us the same freedom as in the case of printer drivers.
+
+A **Printer Application's Web Interface** provides configurability and makes it more accessible to the user. Instead of the web interface, one can also use the standard interface IPP System Service. This allows defining configurable parameters that a device-independent client can poll from the IPP server and display in a GUI so that the user can change them appropriate to his needs. It allows creation and deletion of printers, viewing active and completed jobs, cancellation of job/jobs, configuring the loaded media and network settings, requesting software updates, etc. The underlying mechanism involves adding custom pages and contents using callbacks, static resources, or external files and directories.
+
+
+## Advantages of Printer Applications
+
+* One Driver for one Manufacturer
+
+ The classical printer driver binaries were specifically built for Linux distributions because the distribution provides the layout of CUPS, the libraries, and so on. Also, they have different packaging formats DEB, RPM, and many more. For each distro, drivers need to be built, packaged, and tested separately. It made the task next to impossible to execute. As a result, most of the hardware manufacturers refrained from making these drivers.
+
+ Printing Applications have reduced the intensity of manufacturer's task to a great extent as now they only need one application for all printers, for all distributions, and distribute it through **snaps**.
+
+* Usability
+
+ Users are enabled to directly install and configure CUPS and Printer Application Drivers by just a few simple steps. They do not require to manually drop the PPD files in reserved directories and hence make the process less error-prone. Also, they just need to have a single Printer Application Driver for different printers from the same manufacturer.
+
+* Easy Configuration
+
+ Printer Applications also provide a Web Interface to easily configure Printer's Capabilities, helping people who were earlier unaware to change properties of a Printer in PPD files and were forced to pass the same printing options through the Command line, every time.
+
+* Good Bye PPD!
+
+ PPD files which were earlier used to describe the printer's capabilities and which filters to use to produce the data format needed by the printer are not required by Printer Application.
+
+* Diversified Nature
+
+ Printer Applications have a lot in common. Therefore Michael Sweet has created PAPPL, a library that provides all the common functionality which is needed in every Printer Application. However, the manufacturer is expected to write the drivers on their own (using PAPPL) and defining functions like identifying the start of the page, the start of a line, etc, leading to Printer Application's Diversified Nature.
+
+* Technology for Future
+
+ As we know, Linux is moving to sandboxed packaging (Snap for example) and printing is also moving in that direction. In a sandboxed package, we cannot modify directory contents once it is built. Our system is no more modular. We cannot choose which printer driver package to install. Printer Applications address this problem of modularity and give us the same freedom as in the case of printer drivers.
+
+
+## Roles and Responsiblities
+
+
+
+### OpenPrinting
+
+* CUPS Snap [2]
+
+ This is a complete printing stack in a Snap. It contains not only CUPS but also cups-filters, Ghostscript, and Poppler. It is everything which is required for printing, except Printer Drivers. Till Kamppeter has created this in order to provide a complete printing stack for a purely Snap-based Operating System.
+
+* PAPPL [3]
+
+ Printer Applications have a lot in common. It would be a lot of re-inventing the wheel if everyone who wants to create a printer driver has to implement all this. Therefore Michael Sweet has created PAPPL, a library which provides all the common functionality which is needed in every Printer Application.
+
+* Web Interface
+
+ Printer Applications also provide a Web Interface to easily configure Printer's Capabilities. This GUI helps people who were unaware to change printer properties directly in PPD files and were forced to pass the similar printing options through Command line, each and every time.
+
+* CUPS filters [8]
+
+ These are APIs that can be utilized to perform the conversion of data of files from one format to another.
+
+ Currently, PAPPL supports only raster printers and that too for very few specific input formats like JPEG and PNG. For adding support for non-raster printers like PDF and PostScript printers, you need to supply an external utility that converts the whole job’s data into a data stream which the printer understands. Openprinting and CUPS Filters again come to the rescue here.
+
+ Manufacturers can use CUPS Filters to design these external utilities and decide which set of Filters to use and the order in which these should be invoked depending upon the efficiency and input-output formats. Kindly refer to guidelines for designing of printer applications[4] for more details.
+
+* Providing Sufficient Guidance
+
+ OpenPrinting also helps the manufacturer about designing of printer [4] and scanner drivers.[5] It also guides them about packaging those drivers and uploading on Snap Store. [6] It also educated users about using Printer Application Drivers. It provides neccessary documentation and tutorial for all the above mentioned things.[7]
+
+
+### Manufacturer
+
+The Manufacturer besides manufacturing Printers and Scanners, is also expected to design drivers for the same. They can use PAPPL[3] library which certainly reduces their task to an great extent. Also they could take help from the documentation and tutorial developed by the OpenPrinting team. [4]
+[5]
+
+After designing the drivers, they need to package them and Upload it to Snap Store. Again, documentation and tutorial for the same have developed by the OpenPrinting team which could be referred.[6]
+
+
+### User
+
+The user is relieved from most of the complexities and is just required to install CUPS and Printer Application Driver (based on the manufacturer).
+
+Further, he has the option to change his printer properties through the Web GUI provided with Printer Application.
+
+The OpenPrintring team has also worked out documentation and tutorials about installing CUPS and Drivers and using Web-based GUI, making the switch to this new technology easier for all.[7]
+
+## Resources
+
+[1] How all this began
+
+[2] CUPS Snap
+
+[3] PAPPL
+
+[4] Tutorial to Design Printer Drivers
+
+[5] Tutorial to Design Scanner Drivers
+
+[6] Packaging Drivers and Uploading them to Snap Store
+
+[7] User Manual
+
+[8] CUPS Filters
diff --git a/content/documentation/02-designing-printer-drivers.md b/content/documentation/02-designing-printer-drivers.md
new file mode 100644
index 00000000..9d0043b0
--- /dev/null
+++ b/content/documentation/02-designing-printer-drivers.md
@@ -0,0 +1,1050 @@
+---
+title: Designing Printer Drivers
+toc: true
+toc_sticky: true
+h_range: [1,2]
+---
+**This document contains a complete tutorial as well as information for manufacturers with examples for designing printer drivers. If you are looking for information regarding the use of printer drivers, kindly refer to User Manual**
+
+
+
Introduction
+
+A driver is a code or data specific to a certain model or group of hardware devices, needed to make the hardware work with the hardware-model-independent code of the operating system. Printing in Linux has moved towards [Driverless Printing](https://openprinting.github.io/driverless/), which means there is no need for any hardware-model-specific code or data. However, there are some problems with the current framework. For example, some printers(especially the old ones) that cannot handle IPP requests are devoid of driverless printing capability. Printer Applications help to address these issues. Kindly refer Printer Applications - A new way to print in Linux to learn more about Printer Applications, its working and benefits.
+
+For Designing the Printer Application Driver, it would be a lot of re-inventing the wheel if everyone who wants to create a printer driver has to implement all things from scratch. Therefore Michael Sweet has developed PAPPL, a library that provides all the common functionality which is required in every Printer Application.
+
+The flowchart below mentions the components of the driver that needs to be designed by you (boxes in blue color), along with the PAPPL utilities (boxes in red color) that would be used by your designed components.
+
+
+
+The following tutorial helps you to understand how to design each component and integrate the PAPPL Utilities to reduce your work.
+
+
Components for PAPPL-based Printer Driver
+
+* ### papplMainLoop
+
+ papplMainLoop is the main entry point for the application. It runs a standard main loop with a [system callback](#system_cb()). Also allows the printer application to define its own [usage callback](#usage_cb()) and have an [application specific subcommand](#subcmd_cb()).
+
+ The `papplMainloop` function runs until all processing for the current sub-command is complete, returning the exit status for the program.
+
+ ```c
+ int // O - Exit status
+ papplMainloop(
+ int argc, // I - Number of command line arguments
+ char *argv[], // I - Command line arguments
+ const char *version, // I - Version number
+ const char *footer_html, // I - Footer HTML or `NULL` for none
+ int num_drivers, // I - Number of drivers
+ pappl_pr_driver_t *drivers, // I - Drivers
+ pappl_pr_driver_cb_t driver_cb, // I - Driver callback
+ pappl_ml_autoadd_cb_t autoadd_cb, // I - Auto-add callback or `NULL` for none
+ const char *subcmd_name, // I - Sub-command name or `NULL` for none
+ pappl_ml_subcmd_cb_t subcmd_cb, // I - Sub-command callback or `NULL` for none
+ pappl_ml_system_cb_t system_cb, // I - System callback or `NULL` for default
+ pappl_ml_usage_cb_t usage_cb, // I - Usage callback or `NULL` for default
+ void *data // I - Context pointer
+ )
+ ```
+
+ Before looking at the arguments, you must be aware that there are two ways to configure the papplMainloop:
+
+ 1. **Use system callback argument**
+
+ The system is an object of type `pappl_system_t` that manages client and device connections, listeners, the log, printers, and resources. In addition, it provides an optional embedded web interface, raw socket printing, and USB printer gadget (Linux only).
+
+ The system callback argument specifies a function that will create a new system, i.e. a `pappl_system_t` object. You can use the callback function to customisably configure system properties using the PAPPL System Utilities. This includes configuring Footer HTML on your web interface and setting up drivers.
+
+ You can refer [designing system callback](#systemcallback) guidelines for retrieving more information about the System Callback function.
+
+ 2. **Without system callback function**
+
+ PAPPL allows the manufacture to refrain from the hardships of designing a system callback to create a system. You can specify the system callback as `NULL` and pass on only a few arguments:
+
+ * [Footer HTML](#footer)
+ * [Number of drivers](#num-of-driver)
+ * [Drivers](#drivers)
+ * [Driver Callback](#driver-callback)
+
+
+ If the "system_cb" argument is passed as `NULL`, PAPPL automatically sets up the list of drivers passed as "drivers" arguments and add the Footer HTML for the web interface (in "footer" argument is not `NULL`). A default system object is created for the printer application, which supports multiple printers and a web interface.
+
+ ___
+
+ The `argc` and `argv` arguments for `papplMainLoop` are those provided to the `main` function. Other arguments are given below.
+
+ 1. ### Version number
+
+ This argument is simply a string literal, denoting the numeric version of the printer driver that conforms to semantic versioning guidelines with up to four numbers, for example "1.2.3.4"
+
+ Examples of valid version number are "1.0", "2.1", etc.
+
+ 2.
Footer HTML
+
+ The "footer_html" argument can be provided to override the default footer text that appears at the bottom of the web interface.
+
+ As mentioned above, you can pass this argument as `NULL` and add the footer in system callback function. If system callback and "footer_html" argument both are `NULL` the default is used.
+
+ 3.
Number of drivers
+
+ The "num_drivers" argument specifies the number of drivers for printers. Specify `0` if the drivers are configured in the system callback.
+
+ 4.
Drivers
+
+ The drivers list is a collection of names, descriptions, IEEE-1284 device IDs, and extension pointers. You can pass this argument as `NULL` if the drivers are configured in the system callback.
+
+ A valid example for HP DeskJet, HP LaserJet, and a generic PCL driver, looks like this:
+
+ ```c
+ static pappl_pr_driver_t pcl_drivers[] =// Driver information
+ { /* name */ /* description */ /* device ID */ /* extension */
+ { "hp_deskjet", "HP Deskjet", NULL, NULL },
+ { "hp_generic", "Generic PCL", "CMD:PCL;", NULL },
+ { "hp_laserjet", "HP LaserJet", NULL, NULL }
+ };
+ ```
+
+ 5.
Driver Callback
+
+ The driver callback is responsible for providing the data associated with each driver and is called when the system is creating a new printer. It also responsible for letting the application know what functions to call when performing job functions like starting a job, starting a page, writing a line, ending a page, ending a job, printing a raw job, etc.
+
+ You can pass this argument as `NULL` if the drivers are configured in the system callback. Else, for designing the driver callback function, refer to the [design driver callback](#callback) guidelines.
+
+ 6. ### Autoadd Callback
+
+ The "autoadd_cb" argument specifies a callback for automatically adding new printers with the "autoadd" sub-command. It tells PAPPL which driver to use for the printers it finds.
+
+ 7. ### Sub-command name
+
+ This argument is a string literal that denotes the additional custom sub-command supported by your printer driver. By default, PAPPL helps each driver to support the following sub-commands:
+
+ * add
+ * cancel
+ * default
+ * delete
+ * devices
+ * drivers
+ * jobs
+ * modify
+ * options
+ * printers
+ * server
+ * shutdown
+ * status
+ * submit
+
+ If your printer doesn't support any additional custom sub-command, you may specify the argument as `NULL`.
+
+ 8.
Sub-command Callback
+
+ This callback argument is the function that is to be executed when the sub-command(other than the default sub-commands) is specified.
+
+ Since each driver is not bound to support additional sub-command, one may specify this argument as `NULL` in case the printer driver does not support any additional sub-command.
+
+ If you wish to support additional sub-command, then specify the name of the sub-command in the **sub-command name** argument and design a function using the **[design sub-command callback](#subcommandcallback)** guidelines.
+
+ 9.
System Callback
+
+ The System Callback function creates a system object and allows restoring the previous system configuration(if any). Kindly refer to the **[Design system callback](#systemcallback)** guidelines for retrieving more information about the System Callback function.
+
+ 10.
Usage Callback
+
+ This function helps the user to know about the capabilities of your printer by showing the set of sub-commands and options supported by your printer. For retrieving the output of this function, the user needs to pass the `--help` argument.
+
+ One may specify the usage callback argument as `NULL` in the papplMainloop function. The `default` function is utilized in this situation. The default function shows the default list of sub-commands and options. The output of the default usage callback function is shown below.
+
+ ```c
+ Usage: SUB-COMMAND [OPTIONS] [FILENAME]
+ [OPTIONS] [FILENAME]
+ [OPTIONS] -
+
+ Sub-commands:
+ add PRINTER Add a printer.
+ [autoadd Automatically add supported printers.]
+ cancel Cancel one or more jobs.
+ default Set the default printer.
+ delete Delete a printer.
+ devices List devices.
+ drivers List drivers.
+ jobs List jobs.
+ modify Modify a printer.
+ options List printer options.
+ printers List printers.
+ server Run a server.
+ shutdown Shutdown a running server.
+ status Show server/printer/job status.
+ submit Submit a file for printing.
+
+ Options:
+ -a Cancel all jobs (cancel).
+ -d PRINTER Specify printer.
+ -j JOB-ID Specify job ID (cancel).
+ -m DRIVER-NAME Specify driver (add/modify).
+ -n COPIES Specify number of copies (submit).
+ -o NAME=VALUE Specify option (add,modify,server,submit).
+ -u URI Specify ipp: or ipps: printer/server.
+ -v DEVICE-URI Specify socket: or usb: device (add/modify).
+ ```
+
+
+ If your printer supports only the default set of sub-commands, you can use the default usage callback function. If you wish to output different information when the user uses --help command-line argument, follow the designing **[usage callback function](#usagecallback)** guidelines.
+
+
+ 11. ### Data
+
+ This argument is a string literal and provides the application-specific data for any of the callback functions.
+
+
+
Designing Components
+
+*
Usage Callback
+
+ ```c
+ pappl_ml_usage_cb_t usage_cb (
+ void *data
+ );
+ ```
+
+ The usage callback function receives only one argument, i.e. the callback data.
+
+ The function objective is to show the usage details of the printer. Hence, the design guidelines for this function is quite trivial. It consists of a series of `printf` statements describing each supported sub-command and option. It can then return.
+
+___
+
+*
Sub-Command Callback
+
+ This function allows the printer application to have an application-specific subcommand.
+
+ ```c
+ pappl_ml_subcmd_cb_t subcmd_cb (
+ const char *base_name,
+ int options,
+ cups_option_t *options,
+ int num_files,
+ char **files,
+ void *data
+ );
+ ```
+
+ The Sub-Command callback function receives six arguments Basename, Number of options, Options, Number of files, Name of files, and Callback data. It then returns a new sub-command object.
+
+___
+
+*
System Callback
+
+ ```c
+ pappl_ml_system_cb_t *system_cb (
+ int num_options,
+ cups_option_t *options,
+ void *data
+ );
+ ```
+
+ The system callback function receives three arguments Number of options, Options, and Callback data. It then returns a new system object.
+
+ **Design Guidelines:**
+
+ 1. **Declare Objects and Variables**
+
+ The following objects and variables have to be declared:
+
+ | DataType | Variable Name | Significance |
+ |------------------|---------------|----------------------|
+ | pappl_system_t* | system | System object |
+ | char* | val | Current option value |
+ | char* | hostname | Hostname |
+ | char* | logfile | Log file |
+ | char* | system_name | System name |
+ | char* | spooldir_name | spool-directory |
+ | char* | authservice | auth-service |
+ | pappl_loglevel_t | loglevel | Log level |
+ | int | port | Port number |
+ | pappl_soptions_t | soptions | System options |
+ | pappl_version_t | versions | Software versions |
+
+
+ | Note |
+ |--------------------------------------------------------------------------------------------------------------------------------------------|
+ |Naturally, you can define other names for variables. We have assumed them as given in the table to reduce ambiguity in the subsequent steps.|
+
+ 2. **Fetch values using cupsGetOption**
+
+ From the above listed objects/variables, the following variables can get their values from corressponding option name, using `cupsGetOption` PAPPL utility:
+
+ | Variable Name | Option name |
+ |---------------|-----------------|
+ | loglevel | log-level |
+ | logfile | log-file |
+ | hostname | server-hostname |
+ | system_name | system-name |
+ | port | server-port |
+
+ The syntax for using `cupsGetOption` is:
+
+ ```c
+ = cupsGetOption(, num_options, options)
+ ```
+
+ Notes:
+
+ * The return type for `cupsGetOption` utility is char*. Hence for "log-level" and "server-port" options, first fetch them into the `val` variable.
+
+ * The values taken by `loglevel` variable based on value returned by "log-level" `cupsGetOption` can be summarised using the following table:
+
+ | log-level Option | Value for loglevel variable |
+ |------------------|-----------------------------|
+ | fatal | PAPPL_LOGLEVEL_FATAL |
+ | error | PAPPL_LOGLEVEL_ERROR |
+ | warn | PAPPL_LOGLEVEL_WARN |
+ | info | PAPPL_LOGLEVEL_INFO |
+ | debug | PAPPL_LOGLEVEL_DEBUG |
+
+
+ * The `port` variable can be retrived from "server-port" option using [atoi](https://linux.die.net/man/3/atoi) function.
+
+ * Don't forget to add a check for the port number. It must be between 0 to 65535(both inclusive).
+
+ 3. **Create a system using papplSystemCreate**
+
+ The variables defined and fetched above are passed to papplSystemCreate utility to create a system.
+
+ The system is an object of type `pappl_system_t` that manages client and device connections, listeners, the log, printers, and resources. It implements a subset of the IPP System Service ([PWG 5100.22](https://ftp.pwg.org/pub/pwg/candidates/cs-ippsystem10-20191122-5100.22.pdf)) with each printer implementing IPP Everywhere™ ([PWG 5100.14](https://ftp.pwg.org/pub/pwg/candidates/cs-ippeve11-20200515-5100.14.pdf)) and some extensions to provide compatibility with the full range of mobile and desktop client devices. In addition, it provides an optional embedded web interface, raw socket printing, and USB printer gadget (Linux only).
+
+ ```c
+ pappl_system_t* papplSystemCreate(
+ pappl_soptions_t options,
+ const char *name,
+ int port,
+ const char *subtypes,
+ const char *spooldir,
+ const char *logfile,
+ pappl_loglevel_t loglevel,
+ const char *auth_service,
+ bool tls_only
+ );
+ ```
+
+ * The `soptions` variable is passed as the first argument, which is an bitwise `ORed` of the following options:
+
+ | System Option | Significance |
+ |:---------------------------:|:------------------------------------------------------------------:|
+ | PAPPL_SOPTIONS_DNSSD_HOST | Use hostname in DNS-SD service names instead of serial number/UUID |
+ | PAPPL_SOPTIONS_LOG | Include link to log file |
+ | PAPPL_SOPTIONS_MULTI_QUEUE | Support multiple printers |
+ | PAPPL_SOPTIONS_NETWORK | Include network settings page |
+ | PAPPL_SOPTIONS_NONE | No options |
+ | PAPPL_SOPTIONS_RAW_SOCKET | Accept jobs via raw sockets |
+ | PAPPL_SOPTIONS_REMOTE_ADMIN | Allow remote queue management (vs. localhost only) |
+ | PAPPL_SOPTIONS_SECURITY | Include user/password settings page |
+ | PAPPL_SOPTIONS_STANDARD | Include the standard web pages |
+ | PAPPL_SOPTIONS_TLS | Include TLS settings page |
+
+ * The `system_name` variable fetched in 2nd Step is passed as second argument. Note that the system-name might be `NULL`. So, don't forget to add a check and pass a default value, in case the fetched system-name is `NULL`.
+ * The port number is passed as the third argument. You may pass it as `0` for auto.
+ * The 4th argument is a string literal that signifies DNS-SD sub-types. One may pass `NULL` for none.
+ * Pass the `spooldir`, `logfile` and `loglevel` variable fetched in 2nd Step as fifth, sixth and seventh argument respectively. You can pass `NULL` for the fifth and sixth arguments for default values.
+ * The 8th argument signifies the PAM authentication service. You may pass `auth_service` variable fetched in 2nd Step or `NULL` for none.
+ * If the system only supports TLS connection, pass true in the 9th argument, else false.
+
+
+ 4. **Add system configurations**
+
+ The system object has tons of configurable attributes and correspondingly a huge number of PAPPL utilities to configure them. These include utilities like Setting Hostname, Setting the footer HTML for the web interface, etc. A detailed list of these function can be found at PAPPL System Utilities.
+
+
+ 5. **Call the [Driver setup function](#setup)**
+
+ Pass the system object created in previous steps as an argument to the Driver setup function. See the [design guidlines](#setup) for knowing about the Driver setup function.
+
+ 6. **Return System Object**
+
+ The system object created and set up in the previous steps is returned in this step.
+
+___
+
+*
Driver setup Function
+
+ This function defines the list of printer drivers and [driver callback function](#callback).
+
+ ```c
+ void pcl_setup (
+ pappl_system_t *system
+ );
+ ```
+
+ The Driver setup function receives only one argument, i.e. system object.
+
+ **Design Guidelines:**
+
+ 1. **Define Drivers name and description**
+
+ Create two arrays of string literals, one for the names of the drivers and the other for their corresponding descriptions. Initialise them suitably and use as directed in 2nd Step.
+
+ 2. **Call papplSystemSetPrintDrivers**
+
+ ```c
+ void papplSystemSetPrintDrivers(
+ pappl_system_t *system,
+ int num_names,
+ const char * const *names,
+ const char * const *desc,
+ pappl_pdriver_cb_t cb,
+ void *data
+ );
+ ```
+
+ * The received pappl_system_t object is passed as the first argument.
+ * Pass the number of drivers as the second argument
+ * The defined driver name and description array are passed as the third and fourth arguments respectively.
+ * Pass the [Driver Callback Function](#callback) as fifth argument.
+ * Pass the callback data as the 6th argument.
+
+___
+
+*
Driver Callback Function
+
+ This function tells the printer application what functions to call when performing job functions like starting a job, starting a page, writing a line, ending a page, ending a job, printing a raw job. Driver capability information and defaults(such as resolution, color, etc.) are also provided here.
+
+ ```c
+ bool pcl_callback (
+ pappl_system_t *system,
+ const char *driver_name,
+ const char *device_uri,
+ const char *device_id,
+ pappl_pdriver_data_t *driver_data,
+ ipp_t **driver_attrs,
+ void *data
+ );
+ ```
+
+ The callback function receives six arguments System object, Driver name, Device URI, Driver data, Driver Attributes, and Callback data. It then returns either `true` on success or `false` on failure.
+
+ **Design Guidelines:**
+
+ 1. **Add suitable checks**
+
+ You may check that the passed values of `driver_name`, `device_uri`, `driver_data`, and `data` variable is non-NULL. Further, you must verify that the callback data is the same as the `data` variable.
+
+ 2. **Assign values to common `driver_data` members**
+
+ All the required information is stored in the `pappl_pdriver_data_t` [1] structure. These are a few examples of common driver attributes. For the entire list of attributes that can be provided, please look at the `pappl_pdriver_data_t` [1] structure.
+
+ | Member | Significance |
+ |--------------------|------------------------------------------------------|
+ | identify | [Identify-Printer function](#identify) |
+ | identify_default | "identify-actions-default" values |
+ | identify_supported | "identify-actions-supported" values |
+ | print | [Print (file) function](#print) |
+ | rendjob | [End raster job function](#rendjob) |
+ | rendpage | [End raster page function](#rendpage) |
+ | rstartjob | [Start raster job function](#rstartjob) |
+ | rstartpage | [Start raster page function](#rstartpage) |
+ | rwrite | [Write raster line function](#writeline) |
+ | status | [Status function](#status) |
+ | format | Printer-specific format |
+ | orient_default | "orientation-requested-default" value |
+ | quality_default | "print-quality-default" value |
+
+ 3. **Assign rest of the values `driver_data` members based on `driver_name`**
+
+ Here is the list of all the attributes of `pappl_pdriver_data_t` structure, used to describe driver capability information and defaults. The ones that were not assigned in the previous step may be assigned depending on the name of the driver.
+
+
+ | Member | Significance |
+ |-------------------------------|-----------------------------------------------------|
+ | bin[PAPPL_MAX_BIN] | Output bins |
+ | bin_default | Default output bin |
+ | borderless | Borderless margins supported? |
+ | bottom_top | Bottom and top margins in hundredths of millimeters |
+ | color_default | "print-color-mode-default" value |
+ | content_default | "print-content-default" value |
+ | darkness_supported | printer/print-darkness-supported (0 for none) |
+ | duplex | Duplex printing modes supported |
+ | features[PAPPL_MAX_VENDOR] | "ipp-features-supported" values |
+ | finishings | "finishings-supported" values |
+ | force_raster_type | Force a particular raster type? |
+ | format | Printer-specific format |
+ | gdither | , 'text', and 'graphic' dither array |
+ | icons[3] | "printer-icons" values |
+ | identify | Identify-Printer function |
+ | identify_supported | "identify-actions-supported" values |
+ | kind | "printer-kind" values |
+ | make_and_model[128] | "printer-make-and-model" value |
+ | media[PAPPL_MAX_MEDIA] | Supported media |
+ | media_ready[PAPPL_MAX_SOURCE] | Ready media |
+ | mode_supported | label-mode-supported |
+ | num_bin | Number of output bins |
+ | num_features | Number of "ipp-features-supported" values |
+ | num_media | Number of supported media |
+ | num_source | Number of media sources (trays/rolls) |
+ | num_type | Number of media types |
+ | num_vendor | Number of vendor attributes |
+ | orient_default | "orientation-requested-default" value |
+ | output_face_up | Does output media come out face-up? |
+ | pdither | dither array |
+ | ppm_color | "pages-per-minute-color" value, if any |
+ | print | Print (file) function |
+ | quality_default | "print-quality-default" value |
+ | raster_types | "pwg-raster-document-type-supported" values |
+ | rendjob | End raster job function |
+ | rendpage | End raster page function |
+ | rstartjob | Start raster job function |
+ | rstartpage | Start raster page function |
+ | rwrite | Write raster line function |
+ | scaling_default | "print-scaling-default" value |
+ | sides_default | "sides-default" value |
+ | source[PAPPL_MAX_SOURCE] | Media sources |
+ | speed_default | print-speed-default |
+ | status | Status function |
+ | tear_offset_supported[2] | label-tear-offset-supported (0,0 for none) |
+ | top_offset_supported[2] | media-top-offset-supported (0,0 for none) |
+ | tracking_supported | media-tracking-supported |
+ | type[PAPPL_MAX_TYPE] | Media types |
+ | vendor[PAPPL_MAX_VENDOR] | Vendor attribute names |
+ | y_default | Default resolution |
+
+
+
+ **Difference between [print](#print) and [write](#writeline) function**
+
+ Both the print and write functions execute a similar task, but they are invoked by the printer application in a different situation.
+
+ If the printer-specific format, i.e. the format which is understood by the printer and the format of the Job supplied is the same, then the `print` function is invoked. One may rightly guess that this is the case of raw print since no format conversion or processing is required.
+
+ In the other case, the `write` function is used. This is complemented using other functions such as `rstartpage`, `rendpage`, `rstartjob`, and `rendjob`.
+
+ 
+
+
+___
+
+*
Identify Function
+
+ The function helps to identify a printer using display, flash, sound, or speech.
+
+ ```c
+ void pcl_identify(
+ pappl_printer_t *printer,
+ pappl_identify_actions_t actions,
+ const char *message
+ );
+ ```
+
+ The Identify function receives three arguments that are the Printer, Actions to take, and Messages (if any).
+
+ The Identification methods are summarised in the table:
+
+ | Identification Method | Action |
+ |--------------------------------|--------------------------------|
+ | PAPPL_IDENTIFY_ACTIONS_SOUND | Make a sound |
+ | PAPPL_IDENTIFY_ACTIONS_DISPLAY | display a message (argument) |
+ | PAPPL_IDENTIFY_ACTIONS_SPEAK | speak a message (argument) |
+ | PAPPL_IDENTIFY_ACTIONS_FLASH | flashes a light on the printer |
+
+___
+
+*
Print Function
+
+ It is used to print a raw job (printer-ready) file, i.e. if the job format is the same as the format specified by the [driver callback](#callback).
+
+ ```c
+ bool pcl_print(
+ pappl_job_t *job,
+ pappl_poptions_t *options,
+ pappl_device_t *device
+ );
+ ```
+
+ The Print function receives three arguments that are Job, Job Options, and device.
+
+ * The "job" argument provides the current job object.
+ * The "options" pointer provides the current [print job options](#pappl_pr_options_s).
+ * The "device" argument is a pointer used to send data to the printer.
+
+ The function returns true on success and false on failure.
+
+ This callback will sometimes send some printer initialization commands followed by the job file and then any cleanup commands. It may also be able to count the number of pages (impressions) in the file, although that is not a requirement.
+
+___
+
+*
End Job Function
+
+ This function is called at the end of each page where the driver will typically eject the current page.
+
+ ```c
+ bool pcl_rendjob(
+ pappl_job_t *job,
+ pappl_poptions_t *options,
+ pappl_device_t *device
+ );
+ ```
+
+ The End Job function receives three arguments that are Job, Job Options, and device.
+
+ * The "job" argument provides the current job object.
+ * The "options" pointer provides the current [print job options](#pappl_pr_options_s).
+ * The "device" argument is a pointer used to send data to the printer.
+
+ The function returns true on success and false on failure.
+
+ Note that the job data set by [Start Job Function](#rstartjob) must be freed in this function.
+
+___
+
+*
End Page Function
+
+ This function is called each time a page is completed. It helps in resetting the buffers used by the driver.
+
+ ```c
+ bool pcl_rendpage(
+ pappl_job_t *job,
+ pappl_poptions_t *options,
+ pappl_device_t *device,
+ unsigned page
+ )
+ ```
+
+ The End Page function receives four arguments that are Job, Job Options, Device, and Page Number.
+
+ * The "job" argument provides the current job object.
+ * The "options" pointer provides the current [print job options](#pappl_pr_options_s).
+ * The "device" argument is a pointer used to send data to the printer.
+ * The "page" argument specifies the current page number staring at `0`.
+
+ The function returns true on success and false on failure.
+
+___
+
+*
Start Job Function
+
+ This function is called at the beginning of a job to allow the driver to initialize the printer for the current job.
+
+ ```c
+ bool pcl_rstartjob(
+ pappl_job_t *job,
+ pappl_poptions_t *options,
+ pappl_device_t *device
+ );
+ ```
+
+ The Start-Job function, like the End Job Function, receives three arguments that are Job, Job Options, and device.
+
+ * The "job" argument provides the current job object.
+ * The "options" pointer provides the current [print job options](#pappl_pr_options_s).
+ * The "device" argument is a pointer used to send data to the printer.
+
+ The function returns true on success and false on failure.
+
+___
+
+*
Start Page Function
+
+ This function is called when starting a page to allow the driver to do any per-page initialization and/or memory allocations and send any printer commands that are necessary to start a new page. Information regarding the page is obtained from the page header and attributes like resolution, margins, page size, orientation, and graphics are set appropriately.
+
+ ```c
+ bool pcl_rstartpage(
+ pappl_job_t *job,
+ pappl_poptions_t *options,
+ pappl_device_t *device,
+ unsigned page
+ )
+ ```
+
+ The Start Page function receives four arguments that are Job, Job Options, Device, and Page Number.
+
+ * The "job" argument provides the current job object.
+ * The "options" pointer provides the current [print job options](#pappl_pr_options_s).
+ * The "device" argument is a pointer used to send data to the printer.
+ * The "page" argument specifies the current page number staring at `0`.
+
+ The function returns true on success and false on failure.
+
+___
+
+*
Write Line Function
+
+ This function writes a line of graphics and is called for each raster line on the page. It is typically responsible for dithering and compressing the raster data for the printer.
+
+ ```c
+ bool pcl_rwrite(
+ pappl_job_t *job,
+ pappl_poptions_t *options,
+ pappl_device_t *device,
+ unsigned y,
+ const unsigned char *pixels
+ )
+ ```
+
+ The Write Line function receives five arguments that are Job, Job Options, Device, Line number, and Line.
+
+ * The "job" argument provides the current job object.
+ * The "options" pointer provides the current [print job options](#pappl_pr_options_s).
+ * The "device" argument is a pointer used to send data to the printer.
+ * The "y" argument specifies the current line number.
+ * The "pixels" argument is a pointer to the content of current line.
+
+ The function returns true on success and false on failure.
+
+___
+
+*
Printer Status Function
+
+ The PAPPL status callback is used to update the printer state, supply levels, and/or ready media for the printer:
+
+
+ ```c
+ bool pcl_status(
+ pappl_printer_t *printer
+ )
+ ```
+
+ The Printer Status Function receives only one argument and that is the printer. It returns true on success and false on failure.
+
+ The callback can open a connection to the printer using the `papplPrinterOpenDevice` function.
+
+
Add Support for Non-Raster Printers
+
+Currently, PAPPL supports only raster printers and that too for very few specific input formats like JPEG and PNG. For adding support for non-raster printers like PDF and PostScript printers, you need to supply an external utility that converts the whole job's data into a data stream which the printer understands. Refer to the below-mentioned steps to know how to implement the same.
+
+* **Set the printer-specific format in [callback function](#callback).**
+
+ You need to set `driver_data.format` in [callback function](#callback) to the printer-specific format, i.e. the format/language accepted by the printer. A few examples could be "application/postscript", "application/pdf", etc.
+
+* **Add a filter callback**
+
+ You need to add filter callback from format received by the printer application(formats which you wish your printer can support and accept the job in) to printer-specific format(format/languages that the printer actually understands) using `papplSystemAddMIMEFilter` utility.
+
+ ```c
+ void papplSystemAddMIMEFilter(
+ pappl_system_t *system,
+ const char *srctype,
+ const char *dsttype,
+ pappl_mime_filter_cb_t cb,
+ void *data
+ );
+ ```
+
+ | Parameter | Significance |
+ |-----------|-----------------------------------------------|
+ | system | System |
+ | srctype | Source MIME media type (constant) string |
+ | dsttype | Destination MIME media type (constant) string |
+ | cb | [Filter callback function](#filtercallback) |
+ | data | Filter callback data |
+
+ This utility is added in [system callback](#systemcallback) after calling [setup function](#setup) in Step 5.
+
+*
Define filter callback function
+
+ The filter callback function converts the whole job's data into a data stream which the printer understands.
+
+ ```c
+ bool papplJobFilter(
+ pappl_job_t *job,
+ pappl_device_t *device,
+ void *data
+ )
+ ```
+
+ The filter callback function receives 3 parameters, that are the Job, the Device, and the Filter data.
+
+ Depending upon the features, stability, ease of use, documentation, pricing, and license you may use any third party API to perform this task of conversion.
+
+ The default filter callback function added in PAPPL are `_papplJobFilterJPEG` and `_papplJobFilterPNG` which can be found in the file [Job-Filter.c](https://github.com/michaelrsweet/pappl/blob/master/pappl/job-filter.c) and can be referenced for writing your own callback function.
+
+
+
Template for PAPPL-based Printer Driver
+
+```c
+//
+// Include necessary headers...
+//
+# include
+
+
+// Declare structure for Job Data
+
+
+// Declare supported media sizes for different models of printers
+
+
+//
+// Declare local functions
+//
+
+static const char *pcl_autoadd(const char *device_info, const char *device_uri, const char *device_id, void *data);
+static bool pcl_callback(pappl_system_t *system, const char *driver_name, const char *device_uri, const char *device_id, pappl_pr_driver_data_t *driver_data, ipp_t **driver_attrs, void *data);
+static void pcl_compress_data(pappl_job_t *job, pappl_device_t *device, unsigned char *line, unsigned length, unsigned plane, unsigned type);
+static bool pcl_print(pappl_job_t *job, pappl_pr_options_t *options, pappl_device_t *device);
+static bool pcl_rendjob(pappl_job_t *job, pappl_pr_options_t *options, pappl_device_t *device);
+static bool pcl_rendpage(pappl_job_t *job, pappl_pr_options_t *options, pappl_device_t *device, unsigned page);
+static bool pcl_rstartjob(pappl_job_t *job, pappl_pr_options_t *options, pappl_device_t *device);
+static bool pcl_rstartpage(pappl_job_t *job, pappl_pr_options_t *options, pappl_device_t *device, unsigned page);
+static bool pcl_rwriteline(pappl_job_t *job, pappl_pr_options_t *options, pappl_device_t *device, unsigned y, const unsigned char *pixels);
+static void pcl_setup(pappl_system_t *system);
+static bool pcl_status(pappl_printer_t *printer);
+static void setup(pappl_system_t *system);
+static pappl_system_t *system_cb(int num_options, cups_option_t *options, void *data);
+
+
+//
+// 'main()' - Main entry for the application.
+//
+
+int
+main(int argc, // I - Number of command-line arguments
+ char *argv[]) // I - Command-line arguments
+{
+ return (papplMainloop(argc, argv,
+ /*version*/"1.0",
+ /*footer_html*/NULL,
+ (int)(sizeof(pcl_drivers) / sizeof(pcl_drivers[0])),
+ pcl_drivers, pcl_callback, pcl_autoadd,
+ /*subcmd_name*/NULL, /*subcmd_cb*/NULL,
+ /*system_cb*/NULL,
+ /*usage_cb*/NULL,
+ /*data*/NULL));
+}
+
+
+//
+// 'pcl_autoadd()' - Auto-add PCL printers.
+//
+
+static const char * // O - Driver name or `NULL` for none
+pcl_autoadd(const char *device_info, // I - Device name
+ const char *device_uri, // I - Device URI
+ const char *device_id, // I - IEEE-1284 device ID
+ void *data) // I - Callback data (not used)
+{
+
+}
+
+
+//
+// 'pcl_callback()' - PCL callback.
+//
+
+static bool // O - `true` on success, `false` on failure
+pcl_callback(
+ pappl_system_t *system, // I - System
+ const char *driver_name,
+ // I - Driver name
+ const char *device_uri,// I - Device URI (not used)
+ const char *device_id, // I - IEEE-1284 device ID (not used)
+ pappl_pr_driver_data_t *driver_data,
+ // O - Driver data
+ ipp_t **driver_attrs,
+ // O - Driver attributes (not used)
+ void *data) // I - Callback data (not used)
+{
+
+}
+
+
+//
+// 'pcl_compress_data()' - Compress a line of graphics.
+//
+
+static void
+pcl_compress_data(
+ pappl_job_t *job, // I - Job object
+ pappl_device_t *device, // I - Device
+ unsigned char *line, // I - Data to compress
+ unsigned length, // I - Number of bytes
+ unsigned plane, // I - Color plane
+ unsigned type) // I - Type of compression
+{
+
+}
+
+
+//
+// 'identify()' - Identify the printer.
+//
+
+static void
+identify(
+ pappl_printer_t *printer, // I - Printer
+ pappl_identify_actions_t actions, // I - Actions to take
+ const char *message) // I - Message, if any
+{
+// Identify a printer using display, flash, sound, or speech.
+}
+
+
+//
+// 'pcl_print()' - Print file.
+//
+
+static bool // O - `true` on success, `false` on failure
+pcl_print(
+ pappl_job_t *job, // I - Job
+ pappl_pr_options_t *options, // I - Options
+ pappl_device_t *device) // I - Device
+{
+
+}
+
+
+//
+// 'pcl_rendjob()' - End a job.
+//
+
+static bool // O - `true` on success, `false` on failure
+pcl_rendjob(
+ pappl_job_t *job, // I - Job
+ pappl_pr_options_t *options, // I - Options
+ pappl_device_t *device) // I - Device
+{
+
+}
+
+
+//
+// 'pcl_rendpage()' - End a page.
+//
+
+static bool // O - `true` on success, `false` on failure
+pcl_rendpage(
+ pappl_job_t *job, // I - Job
+ pappl_pr_options_t *options, // I - Job options
+ pappl_device_t *device, // I - Device
+ unsigned page) // I - Page number
+{
+
+}
+
+
+//
+// 'pcl_rstartjob()' - Start a job.
+//
+
+static bool // O - `true` on success, `false` on failure
+pcl_rstartjob(
+ pappl_job_t *job, // I - Job
+ pappl_pr_options_t *options, // I - Job options
+ pappl_device_t *device) // I - Device
+{
+
+}
+
+
+//
+// 'pcl_rstartpage()' - Start a page.
+//
+
+static bool // O - `true` on success, `false` on failure
+pcl_rstartpage(
+ pappl_job_t *job, // I - Job
+ pappl_pr_options_t *options, // I - Job options
+ pappl_device_t *device, // I - Device
+ unsigned page) // I - Page number
+{
+
+}
+
+
+//
+// 'pcl_rwriteline()' - Write a line.
+//
+
+static bool // O - `true` on success, `false` on failure
+pcl_rwriteline(
+ pappl_job_t *job, // I - Job
+ pappl_pr_options_t *options, // I - Job options
+ pappl_device_t *device, // I - Device
+ unsigned y, // I - Line number
+ const unsigned char *pixels) // I - Line
+{
+
+}
+
+
+//
+// 'pcl_status()' - Get printer status.
+//
+
+static bool // O - `true` on success, `false` on failure
+pcl_status(
+ pappl_printer_t *printer) // I - Printer
+{
+
+}
+
+
+//
+// 'setup()' - Setup PCL drivers.
+//
+
+static void
+setup(
+ pappl_system_t *system) // I - System
+{
+
+}
+
+
+//
+// 'system_cb()' - System callback.
+//
+
+pappl_system_t * // O - New system object
+system_cb(int num_options, // I - Number of options
+ cups_option_t *options, // I - Options
+ void *data) // I - Callback data
+{
+
+}
+```
+
+
Design Guidelines
+
+* **1 Printer/Scanner Application = 1 Snap:**
+Don't make a Snap which contains tons of different printer and scanner applications. This is to ensure that you don't occupy lots of ports and network resources when you have many printer and scanner applications.
+
+* **Printer/Scanner/Fax support can be in a single application:**
+To support multi-function devices you can put all the printer, scanner, and fax support into one application.
+For example, we recommend [HPLIP](https://developers.hp.com/hp-linux-imaging-and-printing) to be put into one single application.
+
+* **Recommended: 1 Printer/Scanner Application per project or manufacturer/product line:**
+It may be possible that a multi-function device may be served by different applications for printing and scanning. For example for legacy devices, scanning may be supported by retrofitted sane-airscan scanner application while printing is supported by the Gutenprint printer application. But here it is easier and better for the project, organization, and management that each project has its own printer/scanner application snap. So SANE will maintain a SANE scanner application snap and they put it on the Snap Store. Similarly, Gutenprint, HPLIP, foo2zjs, Epson, Canon, Ricoh, and so on will do the same.
+
+* **NOT make 1 Printer/Scanner Application for each device:**
+For example, HP Laserjet 4 and HP Laserjet 5 should not have different applications. Otherwise, Snap Store will be cluttered with thousands of applications, and spotting the real application would be difficult. Also, it would result in a lot of code duplication, requiring more storage on the user's machine.
+
+* **1 Printer/Scanner Application = 1 Port:**
+If there are several devices connected to the system and they are served by one printer/scanner application, do not open ports for each device. Because you may run out of ports. Also, ports are not always the same on each boot as other applications may start up before on the next boot.
+
+* **For more than 1 device on 1 Application use URI: ipp://localhost:\/ipp/print/\**
+This is the recommended way to cope up with several devices by only using a single port.
+
+* **DNS-SD service names must be always the same:**
+They must be independent of order application start at boot or of device discovery. To make sure that a printer application can serve several devices of the same model include the DNS-SD service name the CEON number of the devices.
+
+* **Web admin interface should allow:**
+ 1. **suppressing auto-setup for selected devices:**
+ Auto detecting devices might be unsuitable for some cases. For example, if two printer applications support the same device, the user must be able to select with which application he wishes to print. So web interface must contain the option to somehow blacklist a printer application.
+
+ 2. **manual setup of additional devices/instances**
+ Necessary for legacy printers that cannot be auto-discovered in the network.
+
+ 3. **configuration of options not accessible via IPP**
+ Many manufacturers have options that cannot be translated into IPP attributes. So web interface has to provide the possibility to set up these options.
+
+* **sane-airscan in SANE Scanner Application must be built without IPP Scan to avoid recursive discovery infinite loop (“Scanner bomb”)**
+
+
Resources
+
+[1] Printer Application
+
+[2] HP Printer App Example
+
+[3] PAPPL
+
+[4] PAPPL System Utilities
+
+[5] Packaging Drivers and Uploading them to Snap Store
+
+[6] User Manual
+
+[7] PS Printer App Example
\ No newline at end of file
diff --git a/content/documentation/03-designing-scanner-drivers.md b/content/documentation/03-designing-scanner-drivers.md
new file mode 100644
index 00000000..5d1d061a
--- /dev/null
+++ b/content/documentation/03-designing-scanner-drivers.md
@@ -0,0 +1,106 @@
+---
+title: Designing Scanner Drivers
+toc: true
+toc_sticky: true
+h_range: [1,3]
+---
+**Currently PAPPL only provides framework for Printer Applications. The codebase is currently under development and will be expanded in a future version of PAPPL to incorporate Multi Function Printer (MFP) functionalities such as scanning.**
+
+**This document contains information for manufacturers for designing scanner drivers. Note that since the codebase is still under development, the document describes things as planned to be executed. In case of any changes, it will be updated as soon as possible. Also a complete tutorial along with examples will be provided after the support for MFP functionality is released.**
+
+## Introduction
+
+A driver is code or data specific to a certain model or group of hardware devices, needed to make the hardware work with the hardware-model-independent code of the operating system. Printing in Linux has moved towards [Driverless Printing](https://openprinting.github.io/driverless/) and so does Scanning, which means there is no need for any hardware-model-specific code or data.
+
+Kindly refer to Tutorial to Design Printer Drivers to know more about Printer Applications and their designing. Designing Scanner Applications is very similar and expects the manufacturers to use the PAPPL framework to reduce their effort in implementing all things from scratch..
+
+## How a PAPPL-based Scanner Driver should work
+
+PAPPL provides support for the below-mentioned sub-commands by default:
+
+* add
+* cancel
+* default
+* delete
+* devices
+* drivers
+* jobs
+* modify
+* options
+* printers
+* scan
+* server
+* shutdown
+* status
+* submit
+
+Once the User issues any of the following sub-commands, the printer/scanner application converts these commands (or corresponding IPP requests) into the necessary USB/network/etc. communication to perform a scan, get capabilities, and so forth.
+
+In the class of device that we are supporting with PAPPL, the scanner will only produce raster data. It might provide native TIFF support, but that is probably all about it. PDF for example is not supported.
+
+The PAPPL scan interface should pull image data for the current page in one of three formats: 1-bit grayscale, 8-bit grayscale, and 24-bit sRGB. It will then be up to PAPPL to deliver the pages to the Client in `PNG`, `JPEG`, `TIFF`, or `PDF` format. For `PNG` and `JPEG`, each page is a separate document in the scan job. For `TIFF` and `PDF`, a single document is generated and streamed to the Client in response to the Get-Next-Document-Data operation.
+
+
+
+
+
+The scanner interface returns a single page at a time as uncompressed (or losslessly compressed) data, and PAPPL will convert that to a handful of formats requested by the Client. In the case of IPP Scan, `PDF` and `JPEG` are required and PAPPL should support `PNG` for lossless compression of single images and `TIFF` for multi-page images.
+
+## Designing Components
+
+PAPPL provides callbacks for most of the events including submitting print/scan jobs, querying printer/scanner status and capabilities, and so forth to reduce the manufacturer's workload and hence designing scanner applications is very much similar to designing printer applications. The only difference is the additional callback support provided for the scan command. Since this support is added in PAPPL, you as a manufacturer do not need to worry about this implementation as well.
+
+Hence refer to Tutorial to Design Printer Drivers and follow the same for Designing Scanner Applications as well.
+
+## Example for PAPPL-based Scanner Driver
+
+This section is under development. It will be documented after the support for Multi Function Printer (MFP) functionalities is released.
+
+## Template for PAPPL-based Scanner Driver
+
+This section is under development. It will be documented after the support for Multi Function Printer (MFP) functionalities is released.
+
+## Design Guidelines
+
+* **1 Printer/Scanner Application = 1 Snap:**
+Don't make a Snap which contains tons of different printer and scanner applications. This is to ensure that you don't occupy lots of ports and network resources when you have many printer and scanner applications.
+
+* **Printer/Scanner/Fax support can be in a single application:**
+To support multi-function devices you can put all the printer, scanner, and fax support into one application.
+For example, we recommend [HPLIP](https://developers.hp.com/hp-linux-imaging-and-printing) to be put into one single application.
+
+* **Recommended: 1 Printer/Scanner Application per project or manufacturer/product line:**
+It may be possible that a multi-function device may be served by different applications for printing and scanning. For example for legacy devices, scanning may be supported by retrofitted sane-airscan scanner application while printing is supported by the Gutenprint printer application. But here it is easier and better for the project, organization, and management that each project has its own printer/scanner application snap. So SANE will maintain a SANE scanner application snap and they put it on the Snap Store. Similarly, Gutenprint, HPLIP, foo2zjs, Epson, Canon, Ricoh, and so on will do the same.
+
+* **NOT make 1 Printer/Scanner Application for each device:**
+For example, HP Laserjet 4 and HP Laserjet 5 should not have different applications. Otherwise, Snap Store will be cluttered with thousands of applications, and spotting the real application would be difficult. Also, it would result in a lot of code duplication, requiring more storage on the user's machine.
+
+* **1 Printer/Scanner Application = 1 Port:**
+If there are several devices connected to the system and they are served by one printer/scanner application, do not open ports for each device. Because you may run out of ports. Also, ports are not always the same on each boot as other applications may start up before on the next boot.
+
+* **For more than 1 device on 1 Application use URI: ipp://localhost:\/ipp/print/\**
+This is the recommended way to cope up with several devices by only using a single port.
+
+* **DNS-SD service names must be always the same:**
+They must be independent of order application start at boot or of device discovery. To make sure that a printer application can serve several devices of the same model include the DNS-SD service name the CEON number of the devices.
+
+* **Web admin interface should allow:**
+ 1. **suppressing auto-setup for selected devices:**
+ Auto detecting devices might be unsuitable for some cases. For example, if two printer applications support the same device, the user must be able to select with which application he wishes to print. So web interface must contain the option to somehow blacklist a printer application.
+
+ 2. **manual setup of additional devices/instances**
+ Necessary for legacy printers that cannot be auto-discovered in the network.
+
+ 3. **configuration of options not accessible via IPP**
+ Many manufacturers have options that cannot be translated into IPP attributes. So web interface has to provide the possibility to set up these options.
+
+* **sane-airscan in SANE Scanner Application must be built without IPP Scan to avoid recursive discovery infinite loop (“Scanner bomb”)**
+
+## Resources
+[1] Tutorial to Design Printer Drivers
+
+[2] PAPPL
+
+[3] PAPPL System Utilities
+
+[4] Packaging Drivers and Uploading them to Snap Store
\ No newline at end of file
diff --git a/content/documentation/04-packaging-drivers.md b/content/documentation/04-packaging-drivers.md
new file mode 100644
index 00000000..9de953be
--- /dev/null
+++ b/content/documentation/04-packaging-drivers.md
@@ -0,0 +1,306 @@
+---
+title: Packaging Drivers and Release them to the Snap Store
+toc: true
+toc_sticky: true
+h_range: [1,3]
+---
+**This document contains a complete tutorial as well as information for manufacturers with examples for packaging printer/scanner drivers and releasing them to the Snap Store. If you are looking for information regarding the designing of printer/scanner drivers, kindly refer to Tutorial to Design Printer Drivers and Tutorial to Design Scanner Drivers respectively.**
+
+
Introduction
+
+After designing the printer/scanner application, you need to distribute these applications, so that the users can directly download and install these applications to support the printers and scanners manufactured by your company.
+
+One of the primary concerns while packaging the driver is **Distribution-independent packaging**. The classical printer driver binaries were specifically built for Linux distributions because the distribution provides the layout of CUPS, the libraries, and so on. Also, they have different packaging formats DEB, RPM, and many more.
+
+For each distro, drivers need to be built, packaged, and tested separately. It made the task next to impossible to execute. As a result, most of the hardware manufacturers refrained from making these drivers.
+
+But OpenPrinting has reduced the intensity of your task to a great extent as now you only need one driver for all printers, for all distributions, and distribute it through **snaps**.
+
+
Snaps
+
+Snaps are app packages for desktop, cloud, and IoT that are easy to install, secure, cross-platform and dependency-free.
+
+### Benefits of using snaps
+
+* A snap is a bundle of an app and its dependencies that works without modification across many different Linux distributions.
+
+* Snaps are more secure. Every package with all its libraries and files in its own sandbox(isolated from other snaps and the host system), fine-grained control for communication between packages.
+
+* Snaps are easily discoverable and installable from the Snap Store, an app store with an audience of millions who can browse and install snaps graphically in the Snap Store or from the command-line.
+
+You are encouraged to dive deep into the official Snap Documentation to explore more about it.
+
+
Packaging Drivers
+
+Most Snaps we create are driven using `snapcraft.yaml`. This file describes a snap’s build dependencies and run-time requirements, it integrates remote repositories and extensions and runs custom scripts and hooks for better integration with CI systems.
+
+As a distributor, you would create a `snapcraft.yaml` file. This will be used by the `snapcraft` command to build your snap. Next, you would upload this `.snap` file to the Snap Store and release it on the stable channel.
+
+To start building your snap, the initial step is to install snapcraft. Kindly refer the installation guidelines to follow the same.
+
+After installation, navigate to the directory containing your application and use the following command.
+
+ snapcraft init
+
+This creates a buildable `snapcraft.yaml` template within a snap sub-directory relative to your current filesystem location.
+
+
The snapcraft.yaml format
+
+The `snapcraft.yaml` file starts with a small amount of human-readable metadata. This data is used in the presentation of your app in the Snap Store. The former keys define the build dependencies and run-time requirements.
+
+### **Top Level metadata**
+
+* **name**
+ This is the identifying name of the snap. It must start with an ASCII character and can only contain letters in lower case, numbers, and hyphens, and it can’t start or end with a hyphen. The name must be unique if you want to publish it to the Snap Store.
+
+ In this field, you may wish to use the name of your organization along the part it is designed for.
+
+ name: hp-printer-app
+
+ For help on choosing a name and registering it on the Snap Store, see Registering your app name.
+
+___
+
+* **base**
+ The base keyword declares which base snap to use with your project. A base snap is a special kind of snap that provides a run-time environment alongside a minimal set of libraries that are common to most applications:
+
+ base: core18
+
+ As used above, core18 is the current standard base for snap building and is based on Ubuntu 18.04 LTS.
+
+ See Base snaps for more details.
+
+___
+
+* **version**
+ A human-readable string(enclosed within single-quotes) of maximum size 32 characters, represents the version number of your snap. A higher version number generally corresponds to a new application.
+
+ version: '1.0'
+___
+
+* **summary**
+ A single line summary that maybe 79 characters long, describes the snap in short and simple terms. It is used when users are searching through the Store for your application.
+
+ summary: HP Printer Application
+
+___
+
+* **description**
+ Description is used to provide a little more detail about your application. You could as many lines as you want in this field.
+
+ ```
+ description: |
+ HP Printer Application is a PAPPL (Printer Application Framework) based printer application
+ to support hp printers.
+ PAPPL is a simple C-based framework/library for developing CUPS
+ Printer Applications, which are the recommended replacement for
+ printer drivers.
+ ```
+
+___
+
+* **grade**
+ Grade defines the quality grade of the snap. It can have two values.
+
+ * **devel**: a development version of the snap, so as not to be published to the stable or candidate channels.
+
+ * **stable**: a stable release or release candidate, which can be released to all channels.
+
+ We would be using the grade value as stable.
+
+ grade: stable
+
+___
+
+* **confinement**
+ Confinement determines if the snap should be restricted in access or not. It could have three possible values.
+
+ * **strict**: for no access outside of declared interfaces through plugs. Can be published easily and installed without any special command-line argument.
+
+ * **devmode**: for unrestricted access to system resources. Snaps having this confinement cannot be published to Snap Store.
+
+ * **classic**: Allows access to your system’s resources in much the same way traditional packages do. To safeguard against abuse, publishing a classic snap requires manual approval, and installation requires the --classic command-line argument.
+
+ We would be using the confinement value as strict.
+
+ confinement: strict
+
+___
+
+There is other metadata that can be used to provide more information to snapcraft besides the above-listed ones. One may refer to Snapcraft top-level format documentation to know about it.
+
+___
+
+### **Apps Metadata**
+The `apps` keys and values in `snapcraft.yaml` detail the applications and services that a snap wants to expose, including how they’re executed and which resources they can access.
+
+Each application or service is an independent block, defined by a `` and corresponding combinations of keys and values. These are some of the keys that could be used.
+
+* **command**
+ The command to run inside the snap when `` is invoked.
+
+In most of the applications, command will be: `bin/`.
+
+* **daemon**
+ Declares that is a system daemon.
+
+* **plugs**
+ A list of plugs for interfaces to connect to.
+
+Other snapcraft `apps` metadata may be referred from Snapcraft Apps Metadata Documentation.
+
+A most basic example for writing `apps` metadata is given below:
+
+```
+apps:
+ hp-printer-app:
+ command: bin/hp-printer-app
+ plugs: [avahi-observe, home, log-observe, network, network-bind, network-manager, raw-usb]
+```
+
+Note that you must specify the `` same as `` so that it can be invoked by just specifying the ``. However, if they differ, the program will be exposed as `.`.
+
+___
+
+### **Parts Metadata**
+The most important part of the snap, that declares build dependencies and run-time requirements that will be pulled into your snap package. The `parts` key and value in `snapcraft.yaml` detail how `parts` are configured and built by the snapcraft.
+
+Each `part` is an independent building block, defined by a name and corresponding combinations of keys and values. These are some of the keys that could be used.
+
+* **plugin**
+ The plugin that will drive the build-process for this `part`.
+
+* **source**
+ A URL or path to a source tree to build. This can be a local path or remote and can refer to a directory tree, a compressed archive, or a revision control repository.
+
+* **source-type**
+ Used when the type of `source` entry cannot be detected.
+
+* **build-packages**
+ A list of packages required to build a snap.
+
+* **stage-packages**
+ A list of packages required at runtime by a snap.
+
+* **after**
+ Ensures that all the `parts` listed in after are staged before this `part` begins its lifecycle.
+
+Here is only a few `parts` metadata that is must to be used in a printer/scanner application. The other metadata can be referred from Snapcraft parts documentation.
+
+Your Application will contain at least these 3 `parts`:
+* PAPPL dependency (jpeglib)
+* PAPPL
+* Application
+
+Other `parts` includes additional dependencies if needed by your application.
+
+**Default Parts for Application**
+ These `parts` must be included in every application. They do not require modification and the developers may consider using it as boilerplate code for their applications.
+
+1. JPEGLIB
+
+ PAPPL supports `JPEG` and `PNG` format and for loading the image data, it uses the `jpeglib` library. Hence it is a dependency for PAPPL and built using the `autotool` plugin. The Tape Archive (TAR) file can be fetched from the below-mentioned URL.
+
+ ```
+ jpeglib:
+ plugin: autotools
+ source: https://www.ijg.org/files/jpegsrc.v9d.tar.gz
+ source-type: tar
+ ```
+
+
+2. PAPPL
+
+ It is the most important part of an application and is also built using the `autotool` plugin. It is fetched from Michael's GitHub repository using the "git" source-type. The build-packages and stage-packages are mentioned below.
+
+ *Note the `after` key is essential as `jpeglib` is a building dependency for PAPPL. Hence PAPPL must be staged after `jpeglib`.*
+
+ ```
+ pappl:
+ plugin: autotools
+ configflags: [--enable-libjpeg,--enable-libpng,--enable-libusb,--with-dnssd=avahi]
+ source: https://github.com/michaelrsweet/pappl
+ source-type: git
+ build-packages: [libavahi-client-dev, libcups2-dev, libcupsimage2-dev, libgnutls28-dev, libjpeg-dev, libpam-dev, libpng-dev, libusb-1.0-0-dev, zlib1g-dev]
+ stage-packages: [libavahi-client3, libcups2, libcupsimage2, libpng16-16, libusb-1.0-0]
+ after: [jpeglib]
+ ```
+
+
+
+**Non-Default Parts for Application**
+
+1. Application Dependency (Optional)
+
+ Your application may use different libraries / Utilities / APIs, for example, the ones used for converting one format of data to another format, especially in the case of non-raster printers. In this case, those libraries are a dependency for the application, which needs to be specified in the `parts` section.
+
+2. Application
+
+ The core of the snap.
+
+ *Note that the application has a dependency on libraries as well as PAPPL. Hence don't forget to add the `after` key so that the application must be staged at the last.*
+
+
+
Template
+
+```
+name: hp-printer-app
+base: core18
+version: '1.0'
+summary: HP Printer Application
+description: |
+ HP Printer Application is a PAPPL (Printer Application Framework) based printer application
+ to support hp printers.
+ PAPPL is a simple C-based framework/library for developing CUPS
+ Printer Applications, which are the recommended replacement for
+ printer drivers.
+
+grade: stable
+confinement: strict
+
+apps:
+ hp-printer-app:
+ command: bin/hp-printer-app
+ plugs: [avahi-observe, home, log-observe, network, network-bind, network-manager, raw-usb]
+
+parts:
+ jpeglib:
+ plugin: autotools
+ source: https://www.ijg.org/files/jpegsrc.v9d.tar.gz
+ source-type: tar
+
+ pappl:
+ plugin: autotools
+ configflags: [--enable-libjpeg,--enable-libpng,--enable-libusb,--with-dnssd=avahi]
+ source: https://github.com/michaelrsweet/pappl
+ source-type: git
+ build-packages: [libavahi-client-dev, libcups2-dev, libcupsimage2-dev, libgnutls28-dev, libjpeg-dev, libpam-dev, libpng-dev, libusb-1.0-0-dev, zlib1g-dev]
+ stage-packages: [libavahi-client3, libcups2, libcupsimage2, libpng16-16, libusb-1.0-0]
+ after: [jpeglib]
+
+ hp-printer-app:
+ plugin: make
+ source: .
+ after: [pappl]
+```
+
+
Releasing to Snap Store
+
+Once you have a snap that works under strict or classic confinement, you’re ready to publish the snap in the Snap Store where it can be showcased to millions.
+
+The further steps are extensively covered in the official documentation of Snaps and can be located at Releasing to Snap Documentation.
+
+
Resources
+[1] Tutorial to Design Printer Drivers
+
+[2] Tutorial to Design Scanner Drivers
+
+[3] Snap Documentation
+
+[4] Releasing to Snap Documentation
+
+[5] CUPS Snap
+
+[6] HP Printer App Example
+
+[7] PS Printer App Example
\ No newline at end of file
diff --git a/content/documentation/05-User-Manual.md b/content/documentation/05-User-Manual.md
new file mode 100644
index 00000000..789dabf0
--- /dev/null
+++ b/content/documentation/05-User-Manual.md
@@ -0,0 +1,409 @@
+---
+title: User Manual for Printer Applications
+toc: true
+toc_sticky: true
+h_range: [1,3]
+---
+
+**This document is a user manual, containing information about installing drivers provided as Printer/Scanner Applications, installing the CUPS Snap, configuring and using web interface options, and finally use the printer or scanner to print and scan respectively.**
+
+## Introduction
+
+The user is relieved from most of the complexities arising from classic CUPS printer drivers, like needing packages for their particular distro (or at least compatible with it). With new format for printer drivers they just need to install the driver provided as a Printer/Scanner Application (based on the manufacturer and model) and use the same to get their devices working.
+
+Further, many manufacturer's devices have options that cannot be translated into IPP attributes. So the users can change their printer/scanner properties through the Web GUI provided with the Printer/Scanner Application.
+
+
+## Before we start
+
+**If you have a modern, driverless IPP printer or scanner (AirPrint, Mopria, IPP Everywhere, Wi-Fi Direct Print), you do not need any Printer/Scanner Application.**
+
+The Printer/Scanner Application you need to use depends on your printer's manufacturer, model and which classic driver supports it. We at OpenPrinting have developed Printer Applications covering printer drivers which are available in Debian/Ubuntu to provide retro-fitting (to keep the old devices working, but without adding new features) support for older devices which are currently supported in the distributions, and we provide the Legacy Printer Application for devices, which drivers are no longer supported by the manufacturer or they aren't in distributions for various reasons (no open-source license, no public source code, nobody packaged it...). The Legacy Printer Application is able to find classic drivers installed on the system and print on the supported printers. The PostScript Printer Application also allows uploading PPD files for printers via its web administration interface.
+
+We at OpenPrinting provide Printer Applications as Snaps, so these manuals contain Snap-related information. However distributions might provide Printer Applications packaged under classic packaging systems like DEB or RPM, or by another container solution, f.e. Podman or OCI containers. The exception is the Legacy Printer Application, which cannot be containerized due to its nature, so it is part of [pappl-retrofit](https://github.com/OpenPrinting/pappl-retrofit/) and can be shipped only by classic packaging systems.
+
+All the four Printer Applications currently available at OpenPrinting are only for retrofitting purposes and any new drivers should be written as native Printer/Scanner Applications, which can be shipped as a container (Snap, Podman, OCI containers) or via classic packaging systems. The Native Printer Applications can be provided by the printer's manufacturer or by community developers who have access to the printer.
+
+### What printer application do you need?
+
+In case you require a classic driver, there are two ways depending on the source of your driver:
+
+1. For your printer you have used a driver which came with your distribution. Thn one of the Printer Applications at OpenPrinting contains it.
+
+2. For your printer you used a driver which is not in any package in your distribution, a proprietary driver from the printer's manufacturer for example. Install the Legacy Printer Application and it will see your classically installed driver and will use it.
+
+## Installation
+
+For installing Printer/Scanner Applications, you should have `snap` installed on your system. On many systems snap is already installed (for example Ubuntu), if not you can usually easily install it.
+
+### Snap
+
+To install `snap` from the Software Manager application, search for `snapd` and click Install.
+
+Alternatively, `snapd` can be installed from the command line:
+
+ sudo apt install snapd
+
+### Applications
+
+Once `snap` is installed, you can easily install any driver. Find the name of the application compatible with your device. This information will be provided by your device manufacturer. You can install the application browsing the Snap Store or from the command line:
+
+ snap install
+
+
+*Note: Driver auto-installation i.e. when a printer on the system is discovered, the driver can be found on the Snap Store and even can be automatically installed using the hardware signature, is [under development](https://forum.snapcraft.io/t/hardware-associated-snaps-snap-store-search-by-hardware-signature/). We will update this work on our website as soon as this is completed. Until then you have to install drivers manually.*
+
+Many interfaces are automatically connected when a snap is installed, and this ability is a property of either the interface itself or the snap. Interfaces not connected automatically require the user to make a manual connection using the `snap connect` command.
+
+ snap connect ::
+
+Information regarding which interfaces require manual connection will be mentioned by the manufacturer.
+
+## Web Interface
+
+The embedded server can also provide a web interface to the Printer/Scanner Application, and PAPPL includes a standard web interface that can be customized and/or overridden. Aside from the usual status monitoring functionality, the web interface can be configured to allow remote users (with proper authentication) to:
+
+* Create and delete printers
+
+* Set the printer location and DNS-SD name
+
+* Configure the loaded media
+
+* Configure remote access accounts
+
+* Configure networking settings such as the hostname
+
+* Update the TLS certificates used by the server
+
+
+
+___
+
+### Create and Delete Printers
+
+* **Create printers**
+
+ Resource path: /addprinter
+
+ 
+
+ The addition of a printer requires only the following attributes:
+ 1. **Name** of the printer
+ 2. **Device** can be one of the following:
+ * Label Printer
+ * Office Printer
+ * Network Printer
+
+ The choices here vary with the Printer Application and the available printer devices. Usually, here you will see printers which were discovered on your system, both local (USB and also manufacturer-specific or legacy connection types) and network printers. ideally only the ones supported by this Printer Application. Sometimes also manual options, like "Network Printer" with the possibility to enter a hostname/IP in the next field, are available, too.
+
+ 3. **Hostname/IP Address** of the printer required only in the case of a Network Printer.
+ 4. **Driver Name** needs to be selected from the available list of drivers provided by the manufacturer.
+
+
+* **Delete printers**
+
+ Resource path: /\/delete
+
+ This option can be exercised by pressing the delete button on the right side of the name of the printer, followed by pressing the button of confirmation.
+
+___
+
+### View Logs
+
+Resource path: /logs
+
+
+
+The complete system logs can be viewed here. If you prefer to read the text file instead, use the resource path: /logfile.txt.
+
+___
+
+### Update the TLS certificates
+
+Following are the options that can be used to update the Transport Layer Security (TLS) certificates used by the server:
+
+1. **Create New TLS Certificate**
+
+ Resource path: /tls-new-crt
+
+ 
+
+ This form creates a new 'self-signed' TLS certificate for secure printing. Self-signed certificates are not automatically trusted by web browsers.
+
+
+2. **Create TLS Certificate Request**
+
+ Resource path: /tls-new-csr
+
+ 
+
+ This form creates a certificate signing request ('CSR') that you can send to a Certificate Authority ('CA') to obtain a trusted TLS certificate. The private key is saved separately for use with the certificate you get from the CA.
+
+
+3. **Install TLS Certificate**
+
+ Resource path: /tls-install-crt
+
+ 
+
+ This form will install a trusted TLS certificate you have obtained from a Certificate Authority ('CA'). Once installed, it will be used immediately.
+
+___
+
+### Configure Printing Defaults
+
+* **Printing**
+
+ Resource path: /\/printing
+
+ 
+
+ Many manufacturer's devices have options that cannot be translated into IPP attributes. So the web interface provides the possibility to set up these options.
+
+ The printing defaults are automatically fetched for each job and the user is not required to pass them each time using the command-line.
+
+* **Media**
+
+ Resource path: /\/media
+
+ 
+
+ You can use this segment to configure the loaded media including the size, offset, and rolls.
+
+___
+
+### Set Location and DNS-SD name
+
+Resource path: /config
+
+
+
+___
+
+### Configure Networking Settings
+
+* **Networking**
+
+ Resource path: /network
+
+ 
+
+ The option can be used to configure networking settings such as the hostname and also to see the list of interfaces/addresses.
+
+* **Security**
+
+ Resource path: /security
+
+ 
+
+ You may use this option for setting the access password.
+
+___
+
+### Printer Specific Utilities
+
+Apart from configuring printing defaults for the printer, these are the other printer-specific utilities.
+
+1. **Supplies** (*Only available for Office Printers*)
+
+ Resource path: /\/supplies
+
+ 
+
+ This utility helps the user to know the remaining supplies of different inks in the cartridge(s) of the printer.
+
+2. **Identify Printers**
+
+ This option supports printer identification, usually a sound or a light on the printer, which is a requirement for IPP Everywhere™ and is used to visually or audibly isolate a particular printer for the user.
+
+3. **Print Test Page**
+
+ This option helps in testing printer functionality, by issuing a print command for a sample test page.
+
+## Working with Command-Line
+
+Before start working with your device, you must know about the capabilities of your printer/scanner by viewing the set of sub-commands and options supported by your printer/scanner. For retrieving this information, you need to pass the `--help` argument:
+
+ --help
+
+The default list of sub-commands and options available with all applications is shown below.
+
+```c
+Usage: SUB-COMMAND [OPTIONS] [FILENAME]
+ [OPTIONS] [FILENAME]
+ [OPTIONS] -
+
+Sub-commands:
+add PRINTER Add a printer.
+cancel Cancel one or more jobs.
+default Set the default printer.
+delete Delete a printer.
+devices List devices.
+drivers List drivers.
+jobs List jobs.
+modify Modify a printer.
+options List printer options.
+printers List printers.
+server Run a server.
+shutdown Shutdown a running server.
+status Show server/printer/job status.
+submit Submit a file for printing.
+
+Options:
+-a Cancel all jobs (cancel).
+-d PRINTER Specify printer.
+-j JOB-ID Specify job ID (cancel).
+-m DRIVER-NAME Specify driver (add/modify).
+-n COPIES Specify number of copies (submit).
+-o NAME=VALUE Specify option (add,modify,server,submit).
+-u URI Specify ipp: or ipps: printer/server.
+-v DEVICE-URI Specify socket: or usb: device (add/modify).
+```
+
+*Note: Printer Application can have additional sub-commands. You can get the information about them using the `--help` argument.*
+
+### Server Daemon
+
+* **Start Server**
+ Before adding devices and submitting jobs, you must start the application as a server daemon:
+
+ server [-o =]
+
+ The list of options you could use are:
+
+ | Option | Significance |
+ |-----------------|----------------------|
+ | spool-directory | Spool directory |
+ | log-file | Log File |
+ | server-hostname | Hostname |
+ | log-level | Log Level |
+ | server-port | Port |
+ | admin-group | Administrative Group |
+
+* **Close Server**
+ You can close the daemon using the following command:
+
+ shutdown
+
+___
+
+### Devices
+
+* **Adding Device**
+
+ Add a printer queue. The following fields are required to be mentioned for creating a printer queue:
+
+ 1. Device name
+ 2. Device URI
+ 3. Driver Name
+ 4. Default Options (Optional)
+
+ add -d -m -v [-o =]
+
+ You can obtain the possible list of `` values via the call with the `drivers` sub-command:
+
+ drivers
+
+ You can also obtain the possible list of `` values via the call with the `devices` sub-command:
+
+ devices
+
+* **Setting Default Device**
+
+ Get/Set the default the printer queue. The default device is used when the device is not inputted along with the job.
+
+ * Get the Default Device
+
+ default
+
+ * Set the Default Device
+
+ default -d
+
+* **Modifying Printer**
+
+ Modify a printer queue by changing the following fields:
+
+ 1. Device URI
+ 2. Driver Name
+ 3. Default Options
+
+ modify -d [-m ] [-v ] [-o = ]
+
+* **Deleting Device**
+
+ Delete a printer queue.
+
+ delete -d
+
+___
+
+### Handling Jobs
+
+* **Submit Jobs**
+
+ Submit a file for printing.
+
+ submit [-n ] [-o = ]
+
+* **Cancel Jobs**
+
+ * All jobs
+
+ cancel -a
+
+ * Specific Job
+
+ cancel -j
+
+___
+
+### Other Utilities
+
+* **List devices**
+
+ List the connected printers.
+
+ devices
+
+* **List drivers**
+
+ List the supported drivers.
+
+ drivers
+
+* **List jobs**
+
+ List pending print jobs.
+
+ jobs
+
+* **List printer options**
+
+ List the supported options.
+
+ options
+
+* **List printers**
+
+ List the printer queues.
+
+ printers
+
+* **Status**
+
+ Show server/printer/job status.
+
+ status
+
+## Resources
+
+[1] Printer Application
+
+[2] Snap Documentation
+
+[3] PS Printer App README
+
+[4] HP Printer App Man Page
+
+[5] PAPPL Documentation
diff --git a/content/documentation/_index.md b/content/documentation/_index.md
new file mode 100644
index 00000000..13e980e0
--- /dev/null
+++ b/content/documentation/_index.md
@@ -0,0 +1,7 @@
+---
+title: "Documentation"
+---
+
+# Documentation
+
+Welcome to the OpenPrinting documentation.
diff --git a/hugo.toml b/hugo.toml
new file mode 100644
index 00000000..164ee292
--- /dev/null
+++ b/hugo.toml
@@ -0,0 +1,35 @@
+baseURL = 'https://openprinting.github.io/'
+languageCode = 'en-us'
+title = 'OpenPrinting'
+
+[params]
+ description = "Making Printing Just Work."
+ author = "OpenPrinting"
+
+[menu]
+ [[menu.main]]
+ name = "Home"
+ url = "/"
+ weight = 1
+ [[menu.main]]
+ name = "Documentation"
+ url = "/documentation/"
+ weight = 2
+ [[menu.main]]
+ name = "About Us"
+ url = "/about-us/"
+ weight = 3
+ [[menu.main]]
+ name = "Printers"
+ url = "/printers/"
+ weight = 4
+
+[markup]
+ [markup.goldmark]
+ [markup.goldmark.renderer]
+ unsafe = true
+
+[outputs]
+ home = ["HTML", "RSS"]
+ section = ["HTML"]
+
diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html
new file mode 100644
index 00000000..8b069369
--- /dev/null
+++ b/layouts/_default/baseof.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+ {{ .Title }} - {{ .Site.Title }}
+
+
+
+
+
+
+
+
+ {{ block "main" . }}{{ end }}
+
+
+
+
diff --git a/layouts/_default/list.html b/layouts/_default/list.html
new file mode 100644
index 00000000..dd5a359b
--- /dev/null
+++ b/layouts/_default/list.html
@@ -0,0 +1,35 @@
+{{ define "main" }}
+
+
+