Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert multiline plain text to HTML paragraphs with AngularJS

I'm getting a multiline plain text from my backend.

For example:

Lorem ipsum dolor sit amet, <strong>consectetur</strong> adipiscing elit.

Nunc porta velit ut nunc pretium, quis auctor nunc placerat.
In quis porta neque.
Fusce dapibus faucibus mi ut egestas.

<p>Phasellus egestas magna posuere, bibendum dui quis, lacinia nisl.</p>

I want to render it with AngularJS as an HTML paragraphs.

So this example will become:

<p>Lorem ipsum dolor sit amet, &lt;strong&gt;consectetur&lt;/strong&gt; adipiscing elit.</p>

<p>Nunc porta velit ut nunc pretium, quis auctor nunc placerat.
In quis porta neque.
Fusce dapibus faucibus mi ut egestas.</p>

<p>&lt;p&gt;Phasellus egestas magna posuere, bibendum dui quis, lacinia nisl.&lt;/p&gt;</p>

Please notice, that all HTML code that existed in the initial plain text must be securely escaped (including existing <p>'s) so I can't just apply my filter and do escaping afterwards.

I see it as a 3 steps process:

  1. Escape HTML inclusions in initial text.
  2. Apply filter to break multiline text to paragraphs.
  3. Output text without further escaping.

But I'm not sure what is the best method of implementing each step.

Could you guide me with the right approach vector? Thank you!

like image 583
Slava Fomin II Avatar asked Apr 08 '14 18:04

Slava Fomin II


People also ask

How to make paragraphs in HTML?

To add a new paragraph in HTML, place your insertion mark cursor into the HTML document where you want to add the new paragraph. Then type the paragraph start tag: <p>. Then type the paragraph's text. At the end of the new paragraph's text, type the end tag: </p>.

How do I show multiple lines of text in HTML?

As part of a form, the <textarea> tag creates a multiline text-entry area in the user's browser display. In it, the user may type a nearly unlimited number of lines of text.

How do you make a hollow paragraph in HTML?

You can use the <br> element whenever you need to add an HTML new line but not a new paragraph. As it is an empty element, it does not have a closing tag.

How do you change the paragraph spacing in HTML?

Add space below a line or paragraph of text To add extra space below a line or paragraph of text, or push text down lower on the page once, you can use the <br> tag.


1 Answers

I think I've finally solved this issue. I hope this answer will help someone.

As I mentioned earlier this is a 3-steps process.

  1. Escape HTML inclusions in initial text.
  2. Apply filter to break multiline text to paragraphs.
  3. Output text without further escaping.

For the first step I were trying to find some existing function to escape initial text, but to no avail. Seems like AngularJS is not exposing any methods of doing this (please correct me if I'm wrong). Finally I've created my own filter to escape HTML:

myModule.filter('htmlEscape', function() {
    return function(input) {
        if (!input) {
            return '';
        }
        return input.
            replace(/&/g, '&amp;').
            replace(/</g, '&lt;').
            replace(/>/g, '&gt;').
            replace(/'/g, '&#39;').
            replace(/"/g, '&quot;')
        ;
    };
});

Then I've created a filter to break plain text into paragraphs:

myModule.filter('textToHtml', ['$sce', 'htmlEscapeFilter', function($sce, htmlEscapeFilter) {
    return function(input) {
        if (!input) {
            return '';
        }
        input = htmlEscapeFilter(input);

        var output = '';
        $.each(input.split("\n\n"), function(key, paragraph) {
            output += '<p>' + paragraph + '</p>';
        });

        return $sce.trustAsHtml(output);
    };
}])

I'm injecting early created htmlEscape filter to it and using $sce.trustAsHtml method to return value suitable for use with ng-bind-html directive.

And in the end I'm invoking this filter in the partial template like this:

<div ng-bind-html="someText|textToHtml"></div>

Here's the result:

Result of applying the filter

like image 177
Slava Fomin II Avatar answered Sep 23 '22 16:09

Slava Fomin II