Most popular repository providers like GitHub, gitlab and bitbucket are using the readme.md file as a file descriptor. What is markdown? Markdown is a scri p ting language that is very lightweight.

BitBucket uses Markdown to format the documentation file called Readme.md and '.md' is the file extension. #4 Advantages of BitBucket. BitBucket Provides Unlimited private repositories. Bitbucket gives financial support to private support. BitBucket supports continuous integration. BitBucket can easily integrate with Jira and Trello. An example of Markdown with a TOC table working in bitbucket.

Markdown

Ruby on Rails™ Tutorial by Michael Hartl has become a must-read for developers learning how to build Rails apps.”

— Peter Cooper, Editor of Ruby Inside

Used by sites as varied as Twitter, GitHub, Disney, and Airbnb, Ruby on Rails is one of the most popular frameworks for developing web applications, but it can be challenging to learn and use. Whether you’re new to web development or new only to Rails,

Bitbucket Markdown Preview

Ruby on Rails™ Tutorial, Fourth Edition, is the solution.

Best-selling author and leading Rails developer Michael Hartl teaches Rails by guiding you through the development of three example applications of increasing sophistication. The tutorial’s examples focus on the general principles of web development needed for virtually any kind of website. The updates to this edition include full compatibility with Rails 5, a division of the largest chapters into more manageable units, and a huge number of new exercises interspersed in each chapter for maximum reinforcement of the material.

This indispensable guide provides integrated tutorials not only for Rails, but also for the essential Ruby, HTML, CSS, and SQL skills you need when developing web applications. Hartl explains how each new technique solves a real-world problem, and then he demonstrates it with bite-sized code that’s simple enough to understand, yet novel enough to be useful. Whatever your previous web development experience, this book will guide you to true Rails mastery.

This book will help you

  • Install and set up your Rails development environment, including pre-installed integrated development environment (IDE) in the cloud
  • Go beyond generated code to truly understand how to build Rails applications from scratch
  • Learn testing and test-driven development (TDD)
  • Effectively use the Model-View-Controller (MVC) pattern
  • Structure applications using the REST architecture
  • Build static pages and transform them into dynamic ones
  • Master the Ruby programming skills all Rails developers need
  • Create high-quality site layouts and data models
  • Implement registration and authentication systems, including validation and secure passwords
  • Update, display, and delete users
  • Upload images in production using a cloud storage service
  • Implement account activation and password reset, including sending email with Rails
  • Add social features and microblogging, including an introduction to Ajax
  • Record version changes with Git and create a secure remote repository at Bitbucket
  • Deploy your applications early and often with Heroku

For quite some time now, the content of the project pages on my site (this one, for example) was coming directly from the respective Markdown readme file on Bitbucket (this one, for example).

I already wrote multiple times about how my approach how to get this to work - here, here and a bit here.

Until now, the code where all the magic happened looked like this:

It just loads the Markdown file from $url, converts the content to HTML and returns the HTML.
The problem is that it’s pulling the Markdown file directly from Bitbucket - on each request.

Bitbucket markdown image

To make things worse, it’s not only the Markdown files: each readme contains at least one image (the project logo on the top), and some of the readmes have even more images - screenshots, for example.
All these images are directly coming from the Bitbucket repository as well…because in the Markdown files, I’m doing this:

In other words:
If you visited https://christianspecht.de/bitbucket-backup/, this happened:

Of course, all this together takes quite long:

It could be worse, but >700ms isn’t quick either.
So I tried to cache everything on my web server to avoid the requests to Bitbucket.

Caching the Markdown/HTML file

I’m using PHP to load the Markdown files (because my webspace runs PHP anyway), but I have nearly no actual coding experience with it. So I looked around how others do caching in PHP, and found this tutorial.

Based on the code there, here is a new version of the GetMarkdown function, now with caching.
Note that this is not the complete version yet…the version shown here includes only the changes necessary to cache the Markdown file (but not the images):

Quite simple, actually.
The function now expects a second parameter where I’m just passing the title of the calling page (“Bitbucket Backup”, for example). After removing blanks and converting to lowercase, the title becomes the name of the cached HTML file: bitbucket-backup.html

If there already is an existing cache file that’s not too old, I load the HTML from there.
If not, I make a request to the passed URL, get the Markdown file, convert it to HTML, save the HTML in the cache folder and return it to the caller.

That works well, but fixes only half of the loading time problem, because the images are still requested from Bitbucket.

Bitbucket Readme Markdown For Bullet

Caching the images

I knew what I wanted to do:

  1. Search for <img> tags in the HTML
  2. Get the image URL out there
  3. Download the image from that URL on my server
  4. Replace the original URL in the HTML by the “local” one on my server

I just didn’t know how to do it in PHP…so after some more googling, I added more code between these two lines from the last listing:

What I added was this:

The code gets the image URLs from the <img> tags and passes each one (together with the “blanks removed and lowercase” filename that was created for the cached HTML file) to the DownloadImage function:

This function downloads the image to my server, and returns the “new” URL of the image, which the calling code then replaces in the <img> tag.

To stick with the example from above: the logo from the top of Bitbucket Backup’s readme file will be located here after being copied to my server.
(if you click on the link now and the image is not there, it’s probably because I updated my site shortly before, and updating always empties the cache folder)

There’s one special case that wouldn’t work with the DownloadImage function listed above:
When the page contains two images from different URLs with identical file names, my current naming pattern $filename.'-'.basename($url) would lead to identical file names on my server as well, so the second image would overwrite the first one.
But I will neclect this, because I’m the only one with full control over the readme files, so I’ll just make sure that none of them has identical image file names.

I think there’s only one thing that needs additional explanation: the $html = preg_replace(...) line.
It’s there because DOMDocument has this (IMO unnecessary) feature that loadHTML always inserts <!DOCTYPE ...>, <html> and <body> tags whenever the loaded document is lacking them.
If someone doesn’t want that (like me), there seem to be only two options. I can’t use the first/proper one (yet) because the PHP version on my server is too old, so I have no other choice than to use the ugly-looking preg_replace(...) line.

Bitbucket Readme Markdown

Conclusion

The current (as of the time of writing this post) version of the code is here on Bitbucket.

After pushing it to the live site, I opened the site with Chrome’s developer tools again.

Bitbucket Readme Markdown

The first load actually took some more time than before:


(before the change, it was about 700 ms)

Readme

But I expected that, because of course that time also includes copying the images from Bitbucket onto my server.

On the other hand, all subsequent requests were way faster:

So the first visitor each day needs to wait a bit longer than before, but for everyone else the project pages are loading now nearly as fast as the other static pages (like this post).