Javascript 将缩进文本列表转换为HTML列表(jQuery)

Javascript 将缩进文本列表转换为HTML列表(jQuery),javascript,jquery,html,html-lists,Javascript,Jquery,Html,Html Lists,我试图创建一个jQuery脚本,它将任意长度和深度的缩进文本列表转换为格式正确的HTML列表。我将运行此脚本的列表是目录的简单树结构。在树结构中,文件夹由文件夹名称后面的分号表示(文件没有结束标点)。鉴于此,我想在适当的行上附加一个或 我发现生成大部分结构相当容易,但我似乎无法获得递归(我怀疑这是必要的),以确保标记正确嵌套。实现此功能的页面将包括最新(即3.0.3)版本的引导,因此可以随意使用其任何功能。我有大约24个(通常是流产的)代码片段,我已经尝试过,或者目前正试图调整这些片段以产生所需

我试图创建一个jQuery脚本,它将任意长度和深度的缩进文本列表转换为格式正确的HTML列表。我将运行此脚本的列表是目录的简单树结构。在树结构中,文件夹由文件夹名称后面的分号表示(文件没有结束标点)。鉴于此,我想在适当的行上附加一个

我发现生成大部分结构相当容易,但我似乎无法获得递归(我怀疑这是必要的),以确保标记正确嵌套。实现此功能的页面将包括最新(即3.0.3)版本的引导,因此可以随意使用其任何功能。我有大约24个(通常是流产的)代码片段,我已经尝试过,或者目前正试图调整这些片段以产生所需的结果。我没有发布大量(可能没有帮助的)代码,而是创建了一个包含基本表单(将用于输入/输出)、一点jQuery、一个示例列表和一些加载的外部库的


任何帮助或建议都将得到极大的赞赏。

可以使用跨度和类来表示文件和文件夹,但是您应该考虑使用UL和Li元素,它们是为此构建的。

整个列表应包含在ul元素中。顶级列表中的每个条目都应该在主元素内部创建一个li元素。如果元素是文件夹,那么它还应该附加另一个ul。这就是需要递归来允许正确嵌套的地方

然而,如果您打算使用缩进(没有双关缩进),制表符和/或空格解析本身就是一个问题,我在这个答案中没有解决这个问题。在本例中,我将假设您有一个神奇的函数,可以将文本转换为一个名为MyList的已解析列表,并且属于文件夹的文件位于每个列表元素的第一个分号之后

var turnTextIntoList=function(AText) {
    //magic stuff;
    return SomeList;
};

var populateList=function(AList) {
    var mainelement=jQuery('<ul></ul>');
    for(element in AList) { 
        var the_li=jQuery('<li></li>');
        if(element.indexOf(';')!=-1) {
             the_li.append('<span class="file">'+element+'</span>');
        } else {
              var thefolder=element.split(';')
              the_li.append('<span class="folder">'+thefolder[0]+'</span>');
              the_li.append(populateList(turnTextIntoList(thefolder[1])));
        } 
        mainelement.append(the_li);
    }
    return mainelement;
};

var MyList=turnTextIntoList(MyText);
jQuery('#targetdiv').append(populateList(MyList));

它将继续钻取嵌套层,直到它到达一个文件,这样它就可以开始返回

> P>可以使用跨类和类来表示文件和文件夹,但是应该考虑使用UL和LI元素,它们是为此构建的。 整个列表应包含在ul元素中。顶级列表中的每个条目都应该在主元素内部创建一个li元素。如果元素是文件夹,那么它还应该附加另一个ul。这就是需要递归来允许正确嵌套的地方

然而,如果您打算使用缩进(没有双关缩进),制表符和/或空格解析本身就是一个问题,我在这个答案中没有解决这个问题。在本例中,我将假设您有一个神奇的函数,可以将文本转换为一个名为MyList的已解析列表,并且属于文件夹的文件位于每个列表元素的第一个分号之后

var turnTextIntoList=function(AText) {
    //magic stuff;
    return SomeList;
};

var populateList=function(AList) {
    var mainelement=jQuery('<ul></ul>');
    for(element in AList) { 
        var the_li=jQuery('<li></li>');
        if(element.indexOf(';')!=-1) {
             the_li.append('<span class="file">'+element+'</span>');
        } else {
              var thefolder=element.split(';')
              the_li.append('<span class="folder">'+thefolder[0]+'</span>');
              the_li.append(populateList(turnTextIntoList(thefolder[1])));
        } 
        mainelement.append(the_li);
    }
    return mainelement;
};

var MyList=turnTextIntoList(MyText);
jQuery('#targetdiv').append(populateList(MyList));

它将继续钻取嵌套层,直到它到达一个文件,这样它就可以开始返回

> P>可以使用跨类和类来表示文件和文件夹,但是应该考虑使用UL和LI元素,它们是为此构建的。 整个列表应包含在ul元素中。顶级列表中的每个条目都应该在主元素内部创建一个li元素。如果元素是文件夹,那么它还应该附加另一个ul。这就是需要递归来允许正确嵌套的地方

然而,如果您打算使用缩进(没有双关缩进),制表符和/或空格解析本身就是一个问题,我在这个答案中没有解决这个问题。在本例中,我将假设您有一个神奇的函数,可以将文本转换为一个名为MyList的已解析列表,并且属于文件夹的文件位于每个列表元素的第一个分号之后

var turnTextIntoList=function(AText) {
    //magic stuff;
    return SomeList;
};

var populateList=function(AList) {
    var mainelement=jQuery('<ul></ul>');
    for(element in AList) { 
        var the_li=jQuery('<li></li>');
        if(element.indexOf(';')!=-1) {
             the_li.append('<span class="file">'+element+'</span>');
        } else {
              var thefolder=element.split(';')
              the_li.append('<span class="folder">'+thefolder[0]+'</span>');
              the_li.append(populateList(turnTextIntoList(thefolder[1])));
        } 
        mainelement.append(the_li);
    }
    return mainelement;
};

var MyList=turnTextIntoList(MyText);
jQuery('#targetdiv').append(populateList(MyList));

它将继续钻取嵌套层,直到它到达一个文件,这样它就可以开始返回

> P>可以使用跨类和类来表示文件和文件夹,但是应该考虑使用UL和LI元素,它们是为此构建的。 整个列表应包含在ul元素中。顶级列表中的每个条目都应该在主元素内部创建一个li元素。如果元素是文件夹,那么它还应该附加另一个ul。这就是需要递归来允许正确嵌套的地方

然而,如果您打算使用缩进(没有双关缩进),制表符和/或空格解析本身就是一个问题,我在这个答案中没有解决这个问题。在本例中,我将假设您有一个神奇的函数,可以将文本转换为一个名为MyList的已解析列表,并且属于文件夹的文件位于每个列表元素的第一个分号之后

var turnTextIntoList=function(AText) {
    //magic stuff;
    return SomeList;
};

var populateList=function(AList) {
    var mainelement=jQuery('<ul></ul>');
    for(element in AList) { 
        var the_li=jQuery('<li></li>');
        if(element.indexOf(';')!=-1) {
             the_li.append('<span class="file">'+element+'</span>');
        } else {
              var thefolder=element.split(';')
              the_li.append('<span class="folder">'+thefolder[0]+'</span>');
              the_li.append(populateList(turnTextIntoList(thefolder[1])));
        } 
        mainelement.append(the_li);
    }
    return mainelement;
};

var MyList=turnTextIntoList(MyText);
jQuery('#targetdiv').append(populateList(MyList));

它将继续钻取嵌套层,直到它到达一个文件,这样它就可以开始返回

似乎有人已经创建了一个可以执行此操作的。不幸的是,该脚本是用CoffeeScript编写的,而不是JavaScript。然而,有许多在线转换器将从CoffeeScript转换为JavaScript。感谢@charlietfl,他提供了一个到工作转换器的链接,见上文

以下是转换后的工作代码:

var bind, blank, convert, index, li, lineToMap, linesToMaps, parse, parseTuples, ptAccum, runConvert, tabCount, ul, ulEnd;

convert = function(text) {
  return parse(text.split('\n'));
};

li = function(t) {
  var html;
  html = "<li>" + t['line'] + "</li>";
  ptAccum.push(html);
  return html;
};

ul = function(t) {
  return ptAccum.push("<ul>" + (li(t)));
};

ulEnd = function() {
  return ptAccum.push("</ul>");
};

ptAccum = [];

index = 0;

parse = function(lines) {
  var ts;
  ts = linesToMaps(lines);
  ptAccum = ["<ul>"];
  index = 0;
  parseTuples(ts, 0);
  ulEnd();
  return ptAccum.join("\n");
};

parseTuples = function(tuples, level) {
  var stop, _p, _results;
  stop = false;
  _p = function() {
    var curLevel, t;
    t = tuples[index];
    curLevel = t['level'];
    index++;
    if (curLevel === level) {
      return li(t);
    } else if (curLevel < level) {
      index--;
      return stop = true;
    } else {
      ul(t);
      parseTuples(tuples, level + 1);
      return ulEnd();
    }
  };
  _results = [];
  while (!stop && index < tuples.length) {
    _results.push(_p());
  }
  return _results;
};

tabCount = function(line) {
  var c, count, i, inc, isTab, tc;
  tc = 0;
  c = '\t';
  count = 0;
  if (line) {
    count = line.length;
  }
  i = 0;
  isTab = function() {
    return c === '\t';
  };
  inc = function() {
    c = line.charAt(i);
    if (isTab()) {
      tc++;
    }
    return i++;
  };
  while (isTab() && i < count) {
    inc();
  }
  return tc;
};

lineToMap = function(line) {
  return {
    line: line,
    level: tabCount(line)
  };
};

blank = function(line) {
  return !line || line.length === 0 || line.match(/^ *$/);
};

linesToMaps = function(lines) {
  var line, _i, _len, _results;
  _results = [];
  for (_i = 0, _len = lines.length; _i < _len; _i++) {
    line = lines[_i];
    if (!(blank(line))) {
      _results.push(lineToMap(line));
    }
  }
  return _results;
};

runConvert = function() {
  var result;
  result = convert($('#textarea-plain-text').val());
  $('#textarea-converted-text').val(result);
  return $('#div-converted-text').html(result);
};

bind = function() {
  return $('#list-conversion-button').click(runConvert);
};

$(bind);
var-bind、blank、convert、index、li、lineToMap、lineToMap、parse、parseTuples、ptAccum、runConvert、tabCount、ul、ulEnd;
convert=函数(文本){
返回解析(text.split('\n'));
};
li=函数(t){
var-html;
html=“
  • ”+t['line']+”
  • ”; ptAccum.push(html); 返回html; }; ul=功能(t){ 返回ptAccum.push(“
      ”+(li(t)); }; ulEnd=函数(){ 返回ptAccum.push(“
    ”); }; ptAccum=[]; 指数=0; parse=函数(行){ var-ts; ts=线孔(线); ptAccum=[“
      ”]; 指数=0; 语法元组(ts,0); ulEnd(); 返回ptAccum.join(“\n”); }; parseTuples=函数(元组,级别){ var停止,_p,_resu