Tag in Tag Javascript Replace [duplicate] - javascript

I have coded a Javascript bbcode similar to the one I'm using to write this message. It also incorporates a live preview box like the one I see below. The only problem I'm facing at the moment is that some nested bbcode is not parsing.
For example:
[quote]
[quote][/quote]
[/quote]
Is not parsing correctly.
This is my Javascript currently.
function preview() {
var txt = $('#editor').val();
txt = txt.replace(/</g,'<');
txt = txt.replace(/>/g,'>');
txt = txt.replace(/[\r\n]/g,'%lb%');
var find = [
/\[quote\](.*?)\[\/quote\]/gi,
/\[quote author="(.*?)" date="(.*?)"\](.*?)\[\/quote\]/gi,
/\[b\](.*?)\[\/b\]/gi,
/\[i\](.*?)\[\/i\]/gi,
/\[u\](.*?)\[\/u\]/gi,
/\[left\](.*?)\[\/left\]/gi,
/\[center\](.*?)\[\/center\]/gi,
/\[right\](.*?)\[\/right\]/gi,
/\[size=(10|12|24|30)](.*?)\[\/size\]/gi,
/\[font=(.*?)](.*?)\[\/font\]/gi,
/\[color=(.*?)](.*?)\[\/color\]/gi,
/\[url(?:\=?)(.*?)\](.*?)\[\/url\]/gi,
/\[email=(.*?)\](.*?)\[\/email\]/gi,
/\[email\](.*?)\[\/email\]/gi,
/\[img(.*?)\](.*?)\[\/img\]/gi,
/(?:%lb%|\s)*\[code(?:\=?)(?:.*?)\](?:%lb%|\s)*(.*?)(?:%lb%|\s)*\[\/code\](?:%lb%|\s)*/gi,
/\[list(.*?)\](.*?)\[\*\](.*?)(?:%lb%|\s)*(\[\*\].*?\[\/list\]|\[\/list\])/i,
/(?:%lb%|\s)*\[list\](?:%lb%|\s)*(.*?)(?:%lb%|\s)*\[\/list\](?:%lb%|\s)*/gi,
/(?:%lb%|\s)*\[list=(\d)\](?:%lb%|\s)*(.*?)(?:%lb%|\s)*\[\/list\](?:%lb%|\s)*/gi,
/(?:%lb%){3,}/g
];
var replace = [
'<blockquote><div class="quote"><div class="quote_body">$1</div></div></blockquote>',
'<blockquote><div class="quote"><div class="quote_author"><span class="quote_from">Quote from</span> <span class="author">$1</span> on <span class="date">$2</span></div><div class="quote_body">$3</div></div></blockquote>',
'<b>$1<\/b>',
'<i>$1<\/i>',
'<u>$1<\/u>',
'<div class="align_left">$1<\/div>',
'<div class="align_center">$1<\/div>',
'<div class="align_right">$1<\/div>',
'<span style="font-size:$1px;">$2</span>',
'<span style="font-family:$1;">$2</span>',
'<span style="color:$1;">$2</span>',
'$2',
'$2',
'$1',
'<img $1 src="$2" />',
'<pre><code>$1</code></pre>',
'[list$1]$2<li>$3</li>$4',
'<ul>$1</ul>',
'<ol start=$1>$2</ol>',
'%lb%%lb%'
];
// fix [*] so that they only work inside [/list]
for(var i in find)
{
txt = txt.replace(find[i],replace[i]);
if(i == 17) while(txt.match(find[i],replace[i])) txt = txt.replace(find[i],replace[i]);
}
// Fix Smilies
txt = txt.replace(/%lb%/g,'<br />');
txt = txt.replace(/\:\)/g, '<img class="smiley" src="/img/smilies/smile.gif">');
txt = txt.replace(/\:-\)/g, '<img class="smiley" src="/img/smilies/happy.gif">');
txt = txt.replace(/\:D/g, '<img class="smiley" src="/img/smilies/biggrin.gif">');
txt = txt.replace(/\:\(/g, '<img class="smiley" src="/img/smilies/sad.gif">');
txt = txt.replace(/8\)/g, '<img class="smiley" src="/img/smilies/cool.gif">');
txt = txt.replace(/=O/g, '<img class="smiley" src="/img/smilies/surprised.gif">');
txt = txt.replace(/\:-\|\|/g, '<img class="smiley" src="/img/smilies/mad.gif">');
txt = txt.replace(/\:P/g, '<img class="smiley" src="/img/smilies/stongue.gif">');
txt = txt.replace(/\}\-\(/g, '<img class="smiley" src="/img/smilies/confused.gif">');
// Format Dates
txt = txt.replace(/\d{10}/g, function($0) {
var d = new Date($0*1000);
var months = new Array('January','February','March','April','May','June','July','August','September','October','November','December');
return "" + months[d.getMonth()] + " " + d.getDate() + ", " + d.getFullYear() + ", " + (d.getHours()%12) + ":" + d.getMinutes() + " " + (d.getHours()<12 ? 'AM' : 'PM');
});
// Update the preview box
$('.preview').html(txt);
}
This flips most all my bbcode tags. The quote tag is problematic in that it sometimes does not flip nested quote tags or parse the contents of the inner quote tags.
If anyone is able to offer a solution I would be very grateful. Thank you!

Three solutions:
Write a parser. This will produce the best solution but takes a non-trivial amount of effort.
Find a BBCode parsing library. Probably as good as #1 in quality and substantially easier.
Add a negative lookahead to the inside of each tag regex and continuously apply until no match. E.g.:
\[quote\]((?:[^](?!\[quote\]))*?)\[\/quote\]
This will capture the inner quote, then once its replaced, the outer one. Not nearly as clean as the other two but probably the quickest fix.

Related

Paste and Modify Content Pasted In Textarea - Showing Twice

I am trying to replace the content that pastes in the Textarea, but facing a problem that it shows in the Textarea the original content and the "modified" content both. Hope you can help me.
HTML Code (just a simple textarea):
<textarea name="Notes_999" class="cssDetail" id="Notes_999" autocomplete="off"> </textarea>
The Jquery code:
$(".cssDetail").bind("paste", function(e){
// access the clipboard using the api
var elemID = $(this).attr("id");
console.log("elemID: " + elemID);
var t_string = "";
var pastedData = e.originalEvent.clipboardData.getData('text');
console.log("pastedData " + pastedData );
var arrayOfLines = pastedData.split('\n');
$.each(arrayOfLines, function(index, item) {
var cnt_spaces = item.search(/\S|$/);
console.log("cnt_spaces: " + cnt_spaces + " - line: " + item);
item = item.replace(/^\s+|\s+$/g, '');
if (cnt_spaces == 8) {
t_string += "- " + item + '\n';
} else {
t_string += item + '\n';
}
});
//console.log("elemID: " + elemID);
$("#"+elemID).text(''); // Try to clean before replace new content but not working.
$("#"+elemID).text(t_string);
});
The function above works fine and does what I expected. However, the result inside the Textarea has both the original and the "modified " one (t_string variable). I only want the "modified" one in the textarea, please help.
Thank you,

Create a link inside xml in javascript

I have an xml String as:
var txt, parser, xmlDoc;
txt = "<Employees xmlns:xlink=\"http://www.w3.org/1999/xlink\"><Employee>"
+ "<ID xlink:type=\"simple\">1</ID>"
+ "<Name>Employee1</Name>"
+ "<Description>Employee1 Description</Description>"
+ "</Employee>"
+ "<Employee>"
+ "<ID xlink:type=\"simple\">2</ID>"
+ "<Name>Employee2</Name>"
+ "<Description>Employee2 Description</Description>"
+ "</Employee></Employees>";
var htmlString = htmlEntities(txt);
document.getElementById('empDetails').innerHTML = htmlString;
alert("HTML formatted display: \n" + htmlString);
function htmlEntities(str) {
var htmlString = String(str).replace(/&/g, '&').replace(/</g,
'<').replace(/>/g, '>').replace(/"/g, '"');
return htmlString;
}
Where my empDetails is a p tag as:
<p id="empDetails"></p>
now i am able to show xml inside this p tag.
The problem is that i want to show a hyperlink on the id's of the printed xml.
So when the xml is printed in the p tag it should show a hyperlink on the id node. i tried using xlink as you can see but it's of no use.
How to achieve this. Looking forward to your answers. Thanks in advance.
y don't you provide the xlink:href attribute in the ID tag?

Getting HTML markup in a string compiled

I'm trying to give a HTML element a markup but it outputs in a string.
My code:
var inputString = tweet.text;
var findme = screen_name;
tweet.text = inputString.replace(screen_name, "<span class='searched'>" + screen_name + "</span>")
You're likely experiencing this issue because you're setting the string on the UI as text, not HTML. Elements have an innerHTML property which will create child elements if necessary.
DEMO
var inputString = "Hello Daniel!";
var findme = "Daniel";
var replacedString = inputString.replace(findme, "<span class='searched'>" +
findme + "</span>");
document.querySelector('#output').innerHTML = replacedString;
Try
.innerHTML
.replace outputs strings, not html
EDIT
var inputString = tweet.text;
var findme = screen_name;
tweet.text = inputString.replace(screen_name, "<span class='searched'>" + screen_name + "</span>")
SomeHTMLObject.innerHTML=tweet.text;
Found out the solution myself:
In the HTML page, you can should use HTML-escape. So you have to use {{{ variable }}} instead of {{ variable }}
Simple solution, should have thought about that..

Store html code to javascript variable

I have a problem when converting store html code to javascript variable, I know we can convert using converter tools, but I can't use this converter in my situation.
I am trying the following code
var t_cls="font-effect-anaglyph rotator";
var randompostsurl="www.allinworld99.blogspot.com";
var randompoststitle="Open Inspect Element And see the Code";
var default_script = "<script> document.write('<div><a class="+t_cls+" href=\"' + randompostsurl + '\" rel=\"nofollow\">' + randompoststitle + '<\/a><\/div>'); <\/script>\n";
$("#apnd").append(default_script);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<div id="apnd"></div>
The above one will produce the following output
<a class="font-effect-anaglyph" rotator="" href="www.allinworld99.blogspot.com" rel="nofollow">Open Inspect Element And see the Code</a>
Why the rotator class will created as new attribute?
Because there are no quotes around the class attribute in the result. You need to add them, since you have a space in the attribute's value:
default_script = "<script> document.write('<div><a class=\""+t_cls+"\" href=\"' + randompostsurl + '\" rel=\"nofollow\">' + randompoststitle + '<\/a><\/div>');<\/script>\n";
// Here --------------------------------------------------------^^---------^^
Replace your default_script code
default_script = "<script> document.write('<div><a class='"+t_cls+"' href=\"' + randompostsurl + '\" rel=\"nofollow\">' + randompoststitle + '<\/a><\/div>');<\/script>\n";
As there are no quotes in class, it produce rotator as a new attribute. But you can achieve rotator as a class by the following way. i.e replacing single quotes with escape sequence.
<script>$(document).ready(function(){
var t_cls="font-effect-anaglyph rotator", randompostsurl="www.allinworld99.blogspot.com",
randompoststitle="Open Inspect Element And see the Code",
default_script = "document.write(\"<div><a class=\""+t_cls+"\" href=\"" + randompostsurl + "\" rel=\"nofollow\">\" + randompoststitle + \"<\/a><\/div>\");<\/script>\n";
$("#apnd").append(default_script);
});
</script>

javascript .replace width tag

Looking for help with a javascript reg ex replacement. What I need, is to replace all instances of
width="100">
With
style="width: 100px;"
But the actual px value is variable which is what is causing issues for me. I know reg expression is the way to go but I dont quite understand it.
This is a similar question but doesn't solve the issue for me:
JavaScript Regex Replace Width Attribute Matching
The reason this is a problem is because of the HTML generated by TinyMce...
Two options:
Using a regular expression
Parsing the HTML and working with the DOM (preferred)
Using a regular expression
The expression is fairly straightforward:
str = str.replace(/\bwidth="(\d+)"/g, 'style="width: $1px"');
The $1 in the replacement string is filled in with the content of the first capture group.
Example:
var str = '<div width="100">Stuff here</div><div width="240">More stuff here</div>';
display("Before: '" + str + "'");
str = str.replace(/\bwidth="(\d+)"/g, 'style="width: $1px"');
display("After: '" + str + "'");
function display(msg) {
document.body.insertAdjacentHTML(
"beforeend",
"<p>" +
String(msg)
.replace(/&/g, "&")
.replace(/</g, "<") +
"</p>"
);
}
But note that that will:
Replace width="nnn" everywhere in the string, even if not inside a start tag
End up adding a second style attribute to a tag that already has one
If that's okay, great; if not, you might want to parse the HTML, process the resulting parsed DOM nodes, and then serialize it again.
Parsing the HTML and working with the DOM
A better option is to parse the HTML and work with the DOM. You've said that the HTML will be for a div, so we don't have to worry about things like standalone table cells, etc.
Here's a simple parsing and updating example:
var str = '<div width="100">Stuff here</div><div width="240">More stuff here</div>';
var div = document.createElement('div');
div.innerHTML = str;
update(div.childNodes);
display("Before: '" + str + "'");
str = div.innerHTML;
display("After: '" + str + "'");
function update(nodes) {
Array.prototype.forEach.call(nodes, function(node) {
var width;
if (node.nodeType === 1) { // An element
width = node.getAttribute("width");
if (width) {
node.removeAttribute("width");
node.style.width = width + "px";
}
update(node.childNodes);
}
});
}
function display(msg) {
document.body.insertAdjacentHTML(
"beforeend",
"<p>" +
String(msg)
.replace(/&/g, "&")
.replace(/</g, "<") +
"</p>"
);
}
My first thought also was to work with the DOM instead of using RegEx. Instead of iterating over all the elements, we could just use querySelector, which supports attribute selectors.
var html = '<img src="//placehold.it/100x100" alt="" style="100px;">'+
'<img src="//placehold.it/120x120" alt="" width="120" style="border: 2px solid steelblue;">'+
'<img src="//placehold.it/140x140" alt="" width="140">',
wrap = document.createElement('div'),
nodes;
wrap.innerHTML = html;
nodes = wrap.querySelectorAll('[width]');
Array.prototype.forEach.call(nodes, function(el) {
var width = el.getAttribute('width');
if(width) {
el.removeAttribute('width');
el.style.width = width+'px';
}
});

Categories