我目前正在使用以下脚本将缩进的纯文本转换为HTML列表代码:
jQuery(function($) {
var indentedToHtmlList = function indentedToHtmlList (text, indentChar, folderChar, listType, showIcons) {
indentChar = indentChar || '\t';
folderChar = folderChar || ':';
listType = listType || 'ul';
showIcons = !!showIcons;
var lastDepth,
lines = text.split(/\r?\n/),
output = '<' + listType + '>\n',
depthCounter = new RegExp('^(' + indentChar + '*)(.*)');
for (var i = 0; i < lines.length; i++) {
var splitted = lines[i].match(depthCounter),
indentStr = splitted[1],
fileName = splitted[2],
currentDepth = (indentStr === undefined) ? 0 : (indentStr.length / indentChar.length),
isFolder = (fileName.charAt(fileName.length - 1) === folderChar);
if (isFolder) {
fileName = fileName.substring(0, fileName.length -1);
}
if (lastDepth === currentDepth) {
output += '</li>\n';
} else if (lastDepth > currentDepth) {
while (lastDepth > currentDepth) {
output += '</li>\n</' + listType + '>\n</li>\n';
lastDepth--;
}
} else if (lastDepth < currentDepth) {
output += '\n<' + listType + '>\n';
}
output += '<li>';
if (showIcons) {
output += '<span class=" glyphicon glyphicon-' +
(isFolder ? 'folder-open' : 'file') +
'"></span> ';
}
output += fileName;
lastDepth = currentDepth;
}
while (lastDepth >= 0) {
output += '\n</li>\n</' + listType + '>';
lastDepth--;
}
return output;
};
runConvert = function() {
var originalText = $('#textarea-plain-text').val(),
listType = $('#list-type').val(),
showIcons = !!$('#glyph-selector-box').prop('checked'),
result = indentedToHtmlList(originalText, '\t', ':', listType, showIcons);
$('#textarea-converted-text').val(result);
return $('#div-converted-text').html(result);
};
bind = function() {
return $('#list-conversion-button').click(runConvert);
};
$(bind);
});
脚本输出正确显示的代码,这是花费一段时间注意语法关闭的部分原因。这是一个示例文本,转换后的版本(即脚本的结果),以及转换后的文本的标记版本,显示错误的位置:
据我所知,脚本似乎正在插入无关的</li>
标记,并在层次结构中的嵌套列表上放置关闭</ul>
标记。编辑第一个while
循环似乎是</li>
问题的解决方案,但是我和另一个开发人员无法弄清楚逻辑在</ul>
上出错的地方。< / p>
这是一个当前已实现脚本的页面(因此您可以生成自己的示例而无需创建页面):Convert Indented/Nested Plain Text to an HTML List。
答案 0 :(得分:1)
这段代码正在构建一个线性字符串,这非常令人困惑且容易出错。没有提到对代码缺乏评论。通过利用jQuery,您可以将元素创建为对象,然后对其进行操作,甚至无需担心标记。我还没有测试下面的代码,它更像是我刚才所说的一个例子:
function indentedToHtmlList (text, indentChar, folderChar, listType, showIcons) {
indentChar = indentChar || '\t';
folderChar = folderChar || ':';
listType = listType || 'ul';
showIcons = !!showIcons;
var lines = text.split(/\r?\n/),
currentLevel = 1,
rootLevel,
currentList = rootLevel = $('<' + listType + '/>'),
previousItem,
previousLists = [rootLevel];
for(var i = 0; i < lines.length; i++){
//split line into array
var line = lines[i].split(indentChar);
//handle levels
if(line.length > currentLevel){
//add current list to history and create new list
previousLists.push(currentList);
currentList = $('<' + listType + '/>');
previousItem.append(currentList);
currentLevel++;
} else if(line.length < currentLevel){
//get last list from history, until matches current level
while(line.length < currentLevel){
currentList = previousLists.pop();
currentLevel--;
}
}
//create current item
var itemText = line[line.length - 1];
var item = $('<li/>').text(itemText);
//check if is folder
var isFolder = itemText.charAt(itemText.length - 1) === folderChar;
//handle icon
if (showIcons) {
item.prepend($('<span/>').addClass('glyphicon glyphicon-' + isFolder ? 'folder-open' : 'file'));
}
// add item to list
console.log(currentList);
currentList.append(item);
previousItem = item;
}
return rootLevel.html();
}
有时只是更快地重写坏代码,而不是找到需要更改的单个字符。在你的情况下,我肯定会改写它......