Languages
[Edit]
EN

JavaScript - interpret URLs and emails in text replacing them with HTML link elements

5 points
Created by:
Walter
586

In this short article, we would liek to show how to interpret URLs and emails replacing them with links using JavaScript.

 

URLs and emails detection replacing them with HTML link elements using JavaScript.
URLs and emails detection replacing them with HTML link elements using JavaScript.

Practical example

Presented solution escapes HTML special characters making produced HTML safe.

// ONLINE-RUNNER:browser;

<!doctype html>
<html>
<head>
  <style>

    .link { color: #5f5fd0; }
    .email { color: #468b36; }

  </style>
</head>
<body>
  <div id="output"></div>
  <script>

    function RuleProcessor(expression, replacer) {
        if (expression.sticky === false) {
            throw new Error('Used regular expression does not have sticky flag.');
        }
        this.execute = function(index, text) {
            expression.lastIndex = index;
            return expression.exec(text);
        };
        this.process = function(match) {
            return replacer.apply(null, match);
        };
    }
    
    function TextProcessor(escape, rules) {
        if (escape == null) {
            escape = '\\';
        } else {
            if (escape.length !== 1) {
               throw new Error('Escape parameter must be single character.');
            }
        }
        this.processText = function(text) {
            var index = 0;
            var position = 0;
            var omitting = false;
            var result = '';
            loop:
            while (index < text.length) {
                var character = text[index];
                if (character === escape) {
                    if (position < index) {
                        omitting = true;
                        result += text.substring(position, index);
                        position = index;
                    } else {
                        if (omitting) {
                            omitting = false;
                            result += escape;
                        } else {
                            omitting = true;
                        }
                    }
                    position += 1;
                    index += 1;
                } else {
                    for (var i = 0; i < rules.length; ++i) {
                        var rule = rules[i];
                        var match = rule.execute(index, text);
                        if (match) {
                            var entry = match[0];
                            if (omitting) {
                                omitting = false;
                                result += entry;
                            } else {
                                if (position < index) {
                                    result += text.substring(position, index);
                                    position = index;
                                }
                                result += rule.process(match);
                            }
                            position += entry.length;
                            index += entry.length;
                            continue loop;
                        }
                    }
                    index += 1;
                }
            }
            if (position < index) {
                result += text.substring(position, index);
            }
            return result;
        };
    }

    

    // Helper logic:

    function escapeHtml(html) {
        var result = '';
        var escape = '';
        var helper = 0;
        var index = 0;
        for (; index < html.length; ++index) {
            switch (html.charCodeAt(index)) {
                case 34: escape = '&#34;'; break;  //  "  // &quot;
                case 38: escape = '&#38;'; break;  //  &  // &amp;
                case 39: escape = '&#39;'; break;  //  '
                case 60: escape = '&#60;'; break;  //  <  // &lt;
                case 62: escape = '&#62;'; break;  //  >  // &gt;
                default: continue;
            }
            if (helper < index) {
                result += html.substring(helper, index);
            }
            result += escape; 
            helper = index + 1;
        }
        if (helper < index) {
            result += html.substring(helper, index);
        }
        return result;
    }

    // Hint: link and email patterns base on improved ANGUALR 1.5.8 patterns.
    //
    var ESCAPE_REGEX = /[&<>]/y;
    var LINK_REGEX = /(?:\b[a-z][a-z\d.+-]*:\/{2,3}|\/\/(?![a-z][a-z\d.+-]*:\/{2,3})|\bwww\.)(?:[^:@\s]+(?::[^@\s]+)?@)?(?:[^\s:/?#]+|\[[a-f\d:]+\])(?::\d+)?(?:\/[^?#\s]*)?(?:\?[^#\s]*)?(?:#[^\s]*)?/y;
    var EMAIL_REGEX = /(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+\/0-9=?A-Z^_`a-z{|}~]+(?:\.[-!#$%&'*+\/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*/y;  // 64 + @ + 255 = 320

    function interpretEscapes(match) {
        switch (match) {
            case '&': return '&amp;';
            case '<': return '&lt;';
            case '>': return '&gt;';
            default: throw new Error('Not supported esacape character.');
        }
    }

    function interpretLink(match) {
        var href = escapeHtml(match);
        return '<a class="link" href="' + href + '">' + href + '</a>';
    }

    function interpretEmail(match) {
        var href = escapeHtml(match);
        return '<a class="email" href="mailto:' + href + '">' + href + '</a>';
    }

    var rules = [
        new RuleProcessor(ESCAPE_REGEX, interpretEscapes),
        new RuleProcessor(LINK_REGEX, interpretLink),
        new RuleProcessor(EMAIL_REGEX, interpretEmail)
    ];
    
    var processor = new TextProcessor('\\', rules);  //  '\\' is used as escape character for detected rules in the processed text

    
    
    // Usage example:

    var text = 'This is my email: john@e-mail.com, This is my website: https://john.com';
    var html = processor.processText(text);

    var output = document.querySelector('#output');

    output.innerHTML = html;

  </script>
</body>
</html>

 

Alternative titles

  1. JavaScript - interpret text and detect URLs and emails replacing them with HTML link elements
  2. JavaScript - URLs and emails detection replacing them with HTML link elements
  3. JavaScript - interpret text and escape HTML special characters, detect URLs and emails replacing them with HTML link elements
Donate to Dirask
Our content is created by volunteers - like Wikipedia. If you think, the things we do are good, donate us. Thanks!
Join to our subscribers to be up to date with content, news and offers.
Native Advertising
🚀
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

❤️💻 🙂

Join