It's Easy to Build: Custom docs project | Part 2 - HTML to MD
Tags: ruby, tutorial, html, markdown
Published: 2020-04-22 05:17:42

---
title: It's Easy to Build: Custom docs project | Part 2 - HTML to MD
published: true
date: 2020-04-22 05:17:01 UTC
tags: ruby, tutorial, html, markdown
canonical_url: https://blog.cdadityang.xyz/its-easy-to-build-custom-docs-project-part2/
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/o1rv0173ww5bq5ms4vlp.png
series: It's Easy to Build - Custom docs project
---

Hello there, welcome to part 2 of my series to build a custom docs project. Since I'm a kind of DRY person, you should see [part 1 of this series here](https://dev.to/cdadityang/it-s-easy-to-build-custom-docs-project-part-1-md-to-html-11g8) to see the introduction and problem statement of this project.

In this tutorial, we'll learn how to convert our HTML code to the markdown text using the [`reverse_markdown`](https://github.com/xijo/reverse_markdown) gem. We'll also learn how to add a definition of a custom HTML tag(`<bold></bold>`) and parse it with this gem.

_Note: This part is not something that we'll implement in our docs project. I wanted to write this to show you guys that we can do something like this for your future projects._

## Getting Started

![It's Easy to Build: Custom docs project | Part 2 - HTML to MD](https://blog.cdadityang.xyz/content/images/2020/04/rocket-3122690_640.png)<figcaption>Image from Pixabay</figcaption>

For this tutorial, you'll need Ruby installed in your machine. You can use this [GoRails guide](https://gorails.com/setup/ubuntu/18.04) to setup ruby.

First, create a new folder and `cd` into it:
```bash
$ mkdir htmltomd
$ cd htmltomd
```

Install the `reverse_markdown` gem:
  - First, you need to create a file named Gemfile
```bash
$ touch Gemfile
```

  - Then add `reverse_markdown` gem to this file:
```ruby
# Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

# Your ruby version
## It's a good practice to mention it here!
ruby '2.6.5'

gem 'reverse_markdown', '~> 2.0'
```

Install the dependencies:
```bash
$ bundle i
```

Now create three files:
  - `config.rb`: We'll write our ruby code logic in this file
  - `bold_converter.rb`: We'll implement a custom tag `<bold></bold>` in our example, so `reverse_markdown` will not know about our custom tag, so we'll add this logic here.
  - `index.html`: We'll write our HTML code in this file
  - `hello.md`: The output of the converted HTML code to markdown will be injected in this file.
```bash
$ touch config.rb
$ touch bold_converter.rb
$ touch input.html
$ touch hello.md
```

## Codebase:
Let's start writing the code:


First, open up your favorite editor and write a sample HTML code in `index.html` file:
```html
<h1>Hello world</h1>

<p>Hey there</p>

<hr />

<blockquote>Let there be the end</blockquote>

<table>
  <tr>
    <td>Hello 1</td>
    <td>Hello 2</td>
  </tr>
  <tr>
    <td>Body 1</td>
    <td>Body 2</td>
  </tr>
  <tr>
    <td>Body 3</td>
    <td>Body 4</td>
  </tr>
</table>

<bold>This is bold</bold>
```

Now, open the `config.rb` file and write our logic:
```ruby
# First, we need to import `reverse_markdown` library
require 'reverse_markdown'

# Then import the `bold_converter.rb` - See point 3
require './bold_converter'

# Now let us import our `index.html` and `hello.md` files:
## For `index.html`, we only give READ permission
## For `hello.md`, we'll give RE-WRITE permission
### This means, everytime we parse code,
### It will clean `hello.md` file and rewrite code.
index_html_file = File.open('./index.html', 'r')
hello_md_text_file = File.open('./hello.md', 'w+')

# Read the contents of `index.html` file
html_code = index_html_file.read

# Register our custom `<bold></bold>` tag - See point 3
ReverseMarkdown::Converters.register :bold, ReverseMarkdown::Converters::Bold.new

# Config for reverse_markdown
ReverseMarkdown.config do |config|
  ## If there is an unknown tag, raise an error
  config.unknown_tags = :raise
  config.github_flavored = true
end

# Now, convert the HTML code to MD
md_text = ReverseMarkdown.convert(html_code)

# Now, inject the MD text in `hello.md` file
hello_md_text_file.puts md_text

# Now, close the files
index_html_file.close
hello_md_text_file.close
```
  - This was simple; everything is explained in the code comments above, and to summarize:
  - We first import the `reverse_markdown` gem.
  - Then we import our `bold_converter.rb` file - See next point
  - Then we import our `index.html` and `hello.md` files.
  - We then register our new `Bold` tag, add config to `reverse_markdown` and then convert our HTML code to MD.
  - We inject the converted MD text to `hello.md` file.
  - Finally, we close both the files as a good practice.
  - If you run the script now, you'll see an error because `<bold></bold>` tag is not yet defined. We'll get this error because we've used `config.unknown_tags = :raise` to raise errors when we have undefined tags. For more options details [see the docs](https://github.com/xijo/reverse_markdown#configuration). We'll define it now!

Now, open the `bold_converter.rb` file and write our custom tag logic:
```ruby
# bold_converter.rb

module ReverseMarkdown
  module Converters
    class Bold < Base
      # This is the main convert logic
      def convert(node, state = {})
        content = treat_children(node, state.merge(already_bolded_out: true))
        if content.strip.empty? || state[:already_bolded_out]
          content
        else
          " **#{content}**"
        end
      end
    end
  end
end
```
  - `treat_children` method performs conversion of all child nodes. If `<bold></bold>` tag is already defined in `reverse_markdown`(which it is not), then we don't want to convert anything.
  - Even if the string is empty, we don't want to convert anything.
  - If everything is right, add `**` to the content.

Running the script:
  - Run the script by using this command:
```bash
$ ruby config.rb
```

Now, in the `hello.md` file, you'll see the HTML to MD converted text.


## Summary and conclusion
![It's Easy to Build: Custom docs project | Part 2 - HTML to MD](https://blog.cdadityang.xyz/content/images/2020/04/industry-1530608_1280.jpg)<figcaption>Image from Pixabay</figcaption>

Let's take a quick look at what we learned today:

1. First of all, I introduced myself, so don't forget to connect with me at [Twitter](https://twitter.com/cdadityang) or [elsewhere](https://cdadityang.xyz/).
2. Since I'm a DRY person, I referred to my [part 1 article](https://dev.to/cdadityang/it-s-easy-to-build-custom-docs-project-part-1-md-to-html-11g8) where you can see the introduction and problem statement.
3. Then we saw what the prerequisites are, and we also set up and understood our file structure for this tutorial.
4. We then wrote our ruby code logic to solve our problem, i.e., to convert an HTML code to markdown text and injecting it into an `hello.md` file.
5. Finally, we took a quick look at this very summary...

That's it and Let there be the end. 🙏