An open API service indexing awesome lists of open source software.

https://github.com/tenjininc/ghostwriter

A Ruby gem that rewrites HTML as plain text while preserving as much legibility and functionality as possible.
https://github.com/tenjininc/ghostwriter

email html plaintext ruby

Last synced: 7 months ago
JSON representation

A Ruby gem that rewrites HTML as plain text while preserving as much legibility and functionality as possible.

Awesome Lists containing this project

README

          

# Ghostwriter

A ruby gem that converts HTML to plain text, preserving as much legibility and functionality as possible.

It's sort of like a reverse-markdown or a *very* simple screen reader.

## But Why, Though?

* Some email clients won't or can’t offer HTML support.
* Some people explicitly choose plaintext for accessibility or just plain preference.
* Spam filters tend to prefer emails with a plain text alternative (but if you use this gem to spam people,
not only might you be
[breaking](https://fightspam.gc.ca)
[various](https://gdpr.eu/)
[laws](https://www.ftc.gov/tips-advice/business-center/guidance/can-spam-act-compliance-guide-business),
I will also personally curse you)

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'ghostwriter'
```

And then execute:

bundle

Or install it manually with:

gem install ghostwriter

## Usage

Create a `Ghostwriter::Writer` and call `#textify` with the html string you want modified:

```ruby
html = <<~HTML


This is some text with a link


It handles other stuff, too.




Stuff Like



  • Images

  • Lists

  • Tables

  • And more




HTML

ghostwriter = Ghostwriter::Writer.new

puts ghostwriter.textify(html)
```

Produces:

```
This is some text with a link (tenjin.ca)

It handles other stuff, too.

----------

-- Stuff Like --
- Images
- Lists
- Tables
- And more
```

### Links

Links are converted to the link text followed by the link target in brackets:

```html
Visit our Website
```

Becomes:

```
Visit our Website (https://example.com)
```

#### Relative Links

Since emails are wholly distinct from your web address, relative links might break.

To avoid this problem, either use the `` header tag:

```html

Use the base tag to expand links.

```

Becomes:

```
Use the base tag to expand (https://www.example.com/contact) links.
```

Or you can use the `link_base` configuration:

```ruby
Ghostwriter::Writer.new(link_base: 'tenjin.ca').textify(html)
```

### Images

Images with alt text are converted:

```html
ACME Anvils
```

Becomes:

```
ACME Anvils (logo.jpg)
```

But images lacking alt text or with a presentation ARIA role are ignored:

```html



```

And images with data URIs won't include the data portion.

```html

Data picture
```

Becomes:

```
Data picture (embedded)
```

### Paragraphs and Linebreaks

Paragraphs are padded with a newline at the end. Line break tags add an empty line.

```html

I would like to propose a toast.


This meal we enjoy together would be improved by one.




... Plug in the toaster and I'll get the bread.


```

```
I would like to propose a toast.

This meal we enjoy together would be improved by one.

... Plug in the toaster and I'll get the bread.

```

### Headings

Headings are wrapped with a marker per heading level:

```html

Dog Maintenance and Repair


Food Input Port


Exhaust Port Considerations


```

Becomes:

```
-- Dog Maintenance and Repair --
---- Food Input Port ----
------ Exhaust Port Considerations ------
```

The `` tag is treated like an `

` tag.

### Lists

Lists are converted, too. They are padded with newlines and are given simple markers:

```html


  • Planes

  • Trains

  • Automobiles



  1. I get knocked down

  2. I get up again

  3. Never gonna keep me down


```

Becomes:

```
- Planes
- Trains
- Automobiles

1. I get knocked down
2. I get up again
3. Never gonna keep me down
```

### Tables

Tables are still often used in email structuring because support for more modern HTML and CSS is inconsistent. If your
table is purely presentational, mark it with `role="presentation"`. See below for details.

For real data tables, Ghostwriter tries to maintain table structure for simple tables:

```html




Ship
Captain




Enterprise
Jean-Luc Picard


TARDIS
The Doctor


Planet Express Ship
Turanga Leela

```

Becomes:

```
| Ship | Captain |
|---------------------|-----------------|
| Enterprise | Jean-Luc Picard |
| TARDIS | The Doctor |
| Planet Express Ship | Turanga Leela |
```

### Customizing Output

Ghostwriter has some constructor options to customize output.

You can set heading markers.

```ruby
html = <<~HTML

Emergency Cat Procedures


HTML

writer = Ghostwriter::Writer.new(heading_marker: '#')

puts writer.textify(html)
```

Produces:

```
# Emergency Cat Procedures #
```

You can also set list item markers. Ordered markers can be anything that responds to `#next` (eg. any `Enumerator`)

```ruby
html = <<~HTML


  1. Mercury

  2. Venus

  3. Mars



  • Teapot

  • Kettle


HTML

writer = Ghostwriter::Writer.new(ul_marker: '*', ol_marker: 'a')

puts writer.textify(html)
```

Produces:

```
a. Mercury
b. Venus
c. Mars

* Teapot
* Kettle
```

And tables can be customized:

```ruby
writer = Ghostwriter::Writer.new(table_row: '.',
table_column: '#',
table_corner: '+')

puts writer.textify <<~HTML


MoonPortfolio


PhobosFear & Panic
DeimosDread and Terror


HTML
```

Produces:

```
# Moon # Portfolio #
+........+..................+
# Phobos # Fear & Panic #
# Deimos # Dread and Terror #

```

#### Presentation ARIA Role

Tags with `role="presentation"` will be treated as a simple container and the normal behaviour will be suppressed.

```html


The table is a lie


  • No such list


```

Becomes:

```
The table is a lie
No such list
```

### Mail Gem Example

To use `#textify` with the [mail](https://github.com/mikel/mail) gem, just provide the text-part by pasisng the html
through Ghostwriter:

```ruby
require 'mail'

html = 'My email and a link'
ghostwriter = Ghostwriter::Writer.new

Mail.deliver do
to 'bob@example.com'
from 'dot@example.com'
subject 'Using Ghostwriter with Mail'

html_part do
content_type 'text/html; charset=UTF-8'
body html
end

text_part do
body ghostwriter.textify(html)
end
end

```

## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/TenjinInc/ghostwriter

This project is intended to be a friendly space for collaboration, and contributors are expected to adhere to the
[Contributor Covenant](contributor-covenant.org) code of conduct.

### Core Developers

After checking out the repo, run `bundle install` to install dependencies. Then, run `rake spec` to run the tests. You
can also run `bin/console` for an interactive prompt that will allow you to experiment.

#### Local Install

To install this gem onto your local machine only, run

`bundle exec rake install`

#### Gem Release

To release a gem to the world at large

1. Update the version number in `version.rb`,
2. Run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push
the `.gem` file to [rubygems.org](https://rubygems.org).
3. Do a wee dance

## License

The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).