Custom functions in Google Apps Script tend to take long time to process and I wouldn't recommend to use it in several cells. I would like to understand better what you trying to do with this data in order to answer properly, but anyway, I would try one of these two solutions:
1 - Inline formula:
Using only native functions has a better performance. Not sure how you could achieve this, since you are iterating inside that TAGS function.
2- Calculate values interely with Script and replace values in column E:
You could create a function that may run from onEdit event or get activated by a custom menu. Generally it would be like this:
function calculateColumnE() {
var sheet = SpreadsheetApp.openById('some-id').getSheetByName('some-name');
var row_count = sheet.getLastRow();
var input_data = sheet.getRange(1, 1, row_count, 4).getValues();
var data = [];
for (var i = 0; i < row_count; i++) {
var row_data; // this variable will receive value for column E in this row
/*
...
manage input_data here
...
*/
data.push([row_data]); // data array MUST be a 2 dimensional array
}
sheet.getRange(1, 5, data.length, 1).setValues(data);
}
EDIT
Here is the full code for solution 2:
function TAGS(input,textreplacement) { //keeping your original function
if (input.length > 0) {
var lst = input.split(",")
var rep = textreplacement.match(/<[^>]*>/g)
for (i in rep){
textreplacement = textreplacement.replace(rep[i],'"'+lst[i]+'"')
}
return textreplacement
}
else{
return textreplacement
}
}
function calculateColumnE() {
var sheet = SpreadsheetApp.openById('some-id').getSheetByName('some-name');
var row_count = sheet.getLastRow();
var input_data = sheet.getRange(1, 1, row_count, 4).getValues();
var data = [];
for (var i = 0; i < row_count; i++) {
var row_data; // this variable will receive value for column E in this row
if (input_data[i][0] == "Spec") {
row_data = "# SPEC " + input_data[i][1];
} else if (input_data[i][0] == "Scenario") {
row_data = "## " + input_data[i][1];
} else if (input_data[i][0] == "Step") {
row_data = "* " + TAGS(input_data[i][2], input_data[i][3]);
} else if (input_data[i][0] == "Tag") {
row_data = "Tags: " + input_data[i][1].replace(/\s/, ''); // not sure what this is doing
} else if (input_data[i][0] == "") {
row_data = "";
}
data.push([row_data]); // data array MUST be a 2 dimensional array
}
sheet.getRange(1, 5, data.length, 1).setValues(data);
}
I also created a working example, which you can check here: https://docs.google.com/spreadsheets/d/1q2SYD7nYubSuvkMOKQAFuGsrGzrMElzZNIFb8PjM7Yk/edit#gid=0 (send me request if you need it).
It works like a charm using onEdit event to trigger calculateColumnE()
with few lines, I'm curious to know about the result in your 1000+ rows sheet. If it get slow, you may need to run this function manually.