DEV Community

Soham Thaker
Soham Thaker

Posted on

Adding new feature to my project

Commit

b96ef38

Feature

The feature I picked was parsing images from markdown to HTML. In markdown, images are denoted as ![alt text](link to image). I already have support for 2 markdown features in my project, and now I extended it by adding support for image parsing. The reason to pick this feature was due to the already existing feature in my project which converts markdown links denoted as ![alt text](link to image) to HTML <a> tags. I looked at the Docusaurus documentation and they support link parsing which I already have in place. As I was going through the documentation I noticed they had static image parsing as well, which has subtle differences, where images in markdown are denoted as ![alt text](link to image) whereas links are denoted as [alt text](link). So, I thought this would be a simple, easy to implement and a great feature to add to my project.

Feature Implementation

From my findings, Docusaurus uses an external library to perform parsing of markdown images to HTML images. My assumption is that the external library uses regular expression to check if the phrase matches the pattern in the form of, ![alt text](link to image) but I could be wrong. Due to this assumption, I implemented my feature entirely using regex to parse images. Considering I already had code that parsed links, adding this feature was quite straightforward for me. My existing regex code that checked for links was /\[([^\]]+)\]\(([^\)]+)\)/g. After this feature
was added it got changed to /(\!?)\[([^\]]+)\]\(([^\)]+)\)/g. Here the first group captures 0 or 1 of the escaped exclamation mark, the second group captures the text for the image or link and the third group captures the link/path to the image or hyperlink. The regex can match patterns throughout the line that is being read using the global flag. The code that handles parsing for hyperlinks and images is below,

const mdBlobs = bodyArr[i].match(new RegExp(mdBlobRegex, 'g'));

        if (mdBlobs && mdBlobs.length > 0) {
          mdBlobs.forEach((blob) => {

            const blobGroup = blob.match(mdBlobRegex);

            if (blobGroup) {
              const [mdPhrase, mdDelimiter, mdAltText, mdURL] 
              = blobGroup;

              if (mdDelimiter === '!') {
                // Replace md image with <img> tags
                bodyArr[i] = bodyArr[i].replace(
                  mdPhrase,
                  `<img src="${mdURL}" alt="${mdAltText}" width=150 height=150 >`
                );
              } else {
                // Replace md links with <a> tags
                bodyArr[i] = bodyArr[i].replace(
                  mdPhrase,
                  `<a href="${mdURL}" target="_blank">${mdAltText}</a>`
                );
              }
          }
});
Enter fullscreen mode Exit fullscreen mode

The above code first extracts all the hyperlinks and images from a line in markdown. Then it iterates over each of these blobs to extract the different parts of the blob grouped using the () notation in a regex. It gives details like the entire phrase/blob, delimiter like an exclamation mark, the alternate text and the link/path itself. Then it checks whether the delimiter which in the case of an image is an exclamation mark and replaces the entire phrase/blob with an image or anchor tag along with adding properties like src, alt, href, etc.

As far as testing is concerned, I tested my regex using a tool called regexr which breaks down a regex really well to explain each part of regex and also gives a playground to test the strings. Besides, I added multiple test cases in the markdown file where I'd put images with hyperlinks in the same line, images at the beginning, end and middle of a line, and a line full of quite a few images. The tool parsed the images and hyperlinks with no issues.

Next Steps

At the time of writing the blog, I haven't come across any issues that I can file for this feature but I'll actively be looking to find any issues that I could add with a detailed explanation to get people involved in my project. Moreover, I'll be using different tags like good first issue, beginner, difficulty:easy, bug, beginner-friendly, etc to get more eyes on my project. Also, I'm continuously finding ways to make my readme file as up-to-date and full of information as possible to attract more people. Besides, I aim to be there for help and support anytime a contributor needs me, with a good enough turnaround time. Furthermore, I'm aiming to add contributors to the dedicated contributors section or add a special contributors markdown file which mentions their names and GitHub handles, as a token to thank them for their contributions.

Top comments (0)