Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
insertTags in 140byt.es

We all know the little toolbar buttons to insert something into a textarea, like BBCode, Wiki markup or HTML tags (fun fact: GitHub doesn't have a toolbar). One of the resources I used once was this German site but there are many more. I was wondering, how much of this nifty, widespread code could be squished into 140 bytes.

Currently, this is 159 bytes and I'm looking for your help. One thing I could do is to remove a.focus(); and +b.length but doing so I will loose a major feature. I'm looking for other ways to make this smaller.

function(a, b, c, d, e, f, g) //textarea, left and right tag
{
d = 'selection';
e = d + 'End';
d += 'Start';
a.focus(); //not really required but very helpful
f = a[e]; //get cursor position
g = a.value.split(''); //short replacement for substr
g[a[d] - 1] += b; //append both tags
g[f - 1] += c;
a.value = g.join(''); //set new text
a[e] = a[d] = f + b.length //set cursor position
}
function(a,b,c,d,e,f,g){d='selection';e=d+'End';d+='Start';a.focus();f=a[e];g=a.value.split('');g[a[d]-1]+=b;g[f-1]+=c;a.value=g.join('');a[e]=a[d]=f+b.length}
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2011 Thiemo Mättig <http://maettig.com>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
{
"name": "insertTags",
"description": "Surrounds selected text in a textarea with tags, e.g. BBCode or Wikitext.",
"keywords": [
"bbcode",
"forms",
"tags",
"textarea",
"toolbar"
]
}
<!DOCTYPE html>
<button onclick="insertTags(a, &quot;'''&quot;, &quot;'''&quot;)">'''bold'''</button>
<button onclick="insertTags(a, &quot;''&quot;, &quot;''&quot;)">''italic''</button>
<button onclick="insertTags(a, '[[', ']]')">[[link]]</button><br>
<textarea cols="80" rows="20">Select a word and click a button.</textarea><br>
<script type="text/javascript">
var insertTags = function(a, b, c, d, e, f, g) //textarea, left and right tag
{
d = 'selection';
e = d + 'End';
d += 'Start';
a.focus(); //not really required but very helpful
f = a[e]; //get cursor position
g = a.value.split(''); //short replacement for substr
g[a[d] - 1] += b; //append both tags
g[f - 1] += c;
a.value = g.join(''); //set new text
a[e] = a[d] = f + b.length //set cursor position
}
var a = document.getElementsByTagName('TEXTAREA')[0];
</script>
@maettig
Owner

Known bug: Because I'm using split and join instead of substr slice this fails for the first word in the textarea. But it saves 9 3 bytes.

@atk

Save one byte by using the focus(argument): a.focus(d='selection';e=d+'End';d+='Start').

@maettig
Owner

Updated, thanks. Here is another idea to save 5 9 bytes, but this will replace the first occurrence of a selected substring instead of the selected one: g=a.value;a.value=g.replace(g=g.slice(a[d],f),b+g+c);.

@atk

I already thought of that, even tried to think up a clever idea with a replace s/(.{x})(.{y})(.{z})/$1b$2c$3/, but it was considerably longer than the original. Even using exec instead of replace doesn't help there.

@maettig
Owner

I also tried to use a regular expression but it's, well, complicated. Here is the shortest solution I found so far: a.value=a.value.replace(RegExp('([\\s\\S]{'+a[d]+'})([\\s\\S]{'+(f-a[d])+'})'),'$1'+b+'$2'+c);. The most reliable solution is this, but it's 3 bytes longer than using split: g=a.value;a.value=g.slice(0,a[d])+b+g.slice(a[d],f)+c+g.slice(f);.

@atk

Eval makes this 4 bytes shorter: a.value=a.value.replace(eval('/([\s\S]{'+a[d]+'})([\s\S]{'+(f-a[d])+'})/'),'$1'+b+'$2'+c);

@maettig
Owner

I found a reliable (does not work well when nothing is selected) but very short solution based on a regular expression. It works for all positions in the string including the first character. It's short but still to long (164 163 bytes).

function(a,b,c,d,e,f){a.focus(d='selection');e=d+'End';d+='Start';f=a[e];a.value=a.value.replace(/|/g,function(g,h){return a[d]-h?f-h?g:c:b});a[e]=a[d]=f+b.length}
// The following version also works when nothing is selected (168 bytes)
function(a,b,c,d,e,f){a.focus(d='selection');e=d+'End';d+='Start';f=a[e];a.value=a.value.replace(/|/g,function(g,h){return(a[d]-h?g:b)+(f-h?g:c)});a[e]=a[d]=f+b.length}
@atk

I thought about the possibility of function reusal for the replace callback...

@maettig
Owner

I give up. The following version (132 bytes) does not care about setting the cursor position at all. But it works in all cases mentioned above (when the first character or nothing is selected). Anyway, new ideas are welcome.

function(a,b,c,d,e,f){a.focus(d='selection');e=a[d+'End'];d=a[d+'Start'];f=a.value;a.value=f.slice(0,d)+b+f.slice(d,e)+c+f.slice(e)}
@xpansive

Do you really need to use split and join at all? You should be able to access into the string like an array.

@maettig
Owner

@xpansive, I already tried this, but accessing single characters with [] seems to be read-only and can't be abused to insert something.

@xpansive

@maettig Too bad. I was thinking in C...

@maettig
Owner

Doing the same for Internet Explorer is incredible easy, including setting the focus and not losing the cursor position (78 bytes):

function(a,b,c){a=document.selection.createRange(a.focus());a.text=b+a.text+c}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.