DocContract is a rails engine that is an application wrapper around the pdf creation library.

The objective is to create and maintain contracts for customers as easy as possible and thereby removing redundancy, which gives reason to errors and to create for example a maintenance contract for a new year by just setting the yaml configuration to:

year: 2022


The structure of contract maintenance is that you create a contract template for a customer, for example a maintenance contract by creating a configuration (yaml) and a markdown formatted contract. The markdown is then handlebars processed to prevent search/replace, summation and redundancy errors.

Then the LaTeX based pandoc system using the eisvogel template is further used to convert the readable markdown to a nicely formatted PDF contract.

This engine is inpired by the walle/gimli gem but was no longer viable due to lack of maintenance and apparently a better renderer that is pandoc


Create a contract template consisting of a configuration yaml and a markdown formatted contract. The yaml might look like:

titlepage:          true
title:              Maintenance contract {{customer}} {{year}}
subtitle:           To the future and beyond!
date:               2022-01-24
year:               2021
full_customer_name: E-corp located in Gotham City
customer:           E-corp
contractor:         Path-E-Tech Management
full_contractor_name: Path-E-Tech Management L.L.C. located in Gotham City
author:             Dullbert
header-left:        "{{title}}"
header-right:       "{{contractor}}"
footer-left:        "{{customer}} | {{today}}"
toc:                true
toc-own-page:       true
numbersections:     true
footer-right:       '\thepage\ of \pageref{LastPage}'
geometry:           margin=2.5cm
urlcolor:           blue
header-includes:    '\usepackage{lastpage}'
  - label: Maintenance of the platform infrastructure
    amount: 2_000
  - label: Maintenance of the application API
    amount: 2_000
  - label: Do migrations for the Infrastructure adapter
    amount: 2_500

And a basic markdown:

# Introduction

## Client

This maintenance contract is requested by:
{{full_customer_name}}, hereafter {{customer}},

And created by:
{{full_contractor_name}}, hereafter {{contractor}}.

## Behest
contract stuff

# Quote breakdown

## Fixed costs

Subject                     | Cost/y
---                         | ---:
{{#each offer_items}}{{this.label}} | {{euro this.amount}}
{{/each}}**Total** | **{{euro offer_items_total}}**

The total costs for {{year}} for {{to_sentence (map offer_items 'label')}} will thereby be {{to_words offer_items_total}} ({{euro offer_items_total}}). All the amounts include
a VAT of 21%.

## Variable costs
And more contract stuff

NOTE: the to_words handlebars helper uses the (numbers_and_words)[\_and\_words] gem.


Install the system dependencies

The largest dependency is the LaTeX installation:

$ sudo apt-get install texlive-full
$ sudo apt-get install pandoc

NOTE: For trimmed down version of texlive-full do trial and error or check docs

Or for mac:

$ brew install mactex
$ brew install pandoc

And to be able to use the pandoc-latex-environment also install that one:

$ pip install pandoc-latex-environment

Add the engine to your rails app

Add this line to your application's Gemfile:

gem "doc_contract"

And then execute:

$ bundle
$ bundle exec rails db:migrate

Mount the engine to your routes

In your config/routes.rb file add:

  mount DocContract::Engine => '/doc-contract'

Add the authorizations

In your app/models/ability.rb file add the authorizations. This is a custom operation that you have to adjust to your needs. To allow all users full controll to the contracts add:

    can :manage, DocContract::ContractTemplate
    can :manage, DocContract::ContractInstance

If the Ability file does not yet exist, generate it using:

rails generate cancan:ability

Other languages (i18n)

To use for a lets say Spanish based website add rails-i18n to your Gemfile

gem 'rails-i18n'

And configure your application in config/application.rb to handle the languages:

  config.i18n.available_locales = %i[en es]
  config.i18n.default_locale = :en


The main page

The main page of this engine is a bit of a placeholder page. The contents of this page can be found in app/views/doc_contract/application/main.html.slim. To put your own version of this page create a view having this path in the main application. To only deactivate the README content there put the following in your config/application.rb file:

  config.x.doc_contract.show_readme_on_main_page = false

The default value for config/application.rb is:

  config.x.doc_contract.link_home_content = -> { '<i class="arrow left icon"></i> Back' }

To change for example the icon, see the options at the fomantic-ui site. Note that the value is a lambda to allow the use of for example I18n.


Edit template scnreenshot


There are many ways to contribute. Here some example steps that should work.

1. Fork the repository

Go to the original repository at\_contract and fork the project. Then git clone your code on your local computer.

If you are in the git repository directory you can tell your system to use the local code when actually the gitlab repository is specified for faster debugging. To achieve this type:

bundle config local.doc_contract .

2. Add your forked codebase to a project

To start from zero, create a new rails (> 7) project and add the doc_contract gem configured to use gitlab as a base:

rails new my_doc_contract_project
cd my_doc_contract_project

Then in the Gemfile

git_source(:gitlab) do |repo_name|
  repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")

gem 'doc_contract', gitlab: '<your gitlab name>/doc_contract', branch: :master


The CHANGELOG can be found using


The gem is available as open source under the terms of the MIT License.