将文档中标题列表解析为排序树

问题描述:

我试图解析标题列表(h1,h2等)以获取结构良好的JavaScript变量中的内容表(有点像树)。将文档中标题列表解析为排序树

这里是我的文档的结构:

<div id="content"> 
    <h1>The content</h1>blah 
    <h2 class="show-in-toc">Test 1</h2> 
    <h3 class="show-in-toc">Test 1.1</h3> 
    <h3 class="show-in-toc">Test 1.2</h3> 
    <h4 class="show-in-toc">Test 1.2.1</h4> 
    <h4 class="show-in-toc">Test 1.2.2</h4> 
    <h2 class="show-in-toc">Test 2</h2> 
    <h3 class="show-in-toc">Test 2.1</h3> 
    <h4 class="show-in-toc">Test 2.1.1</h4> 
    <h3 class="show-in-toc">Test 2.2</h3> 
</div> 

这里就是我试图让:

[ 
    {"text": "Test 1","level": 2, "children": [ 
     {"text": "Test 1.1","level": 3,"children": []}, 
     {"text": "Test 1.2", "level": 3, "children": [ 
      {"text": "Test 1.2.1", "level": 4, "children": []}, 
      {"text": "Test 1.2.2", "level": 4, "children": []} 
     ]} 
    ]}, 
    {"text": "Test 2", "level": 2, "children": [ 
     {"text": "Test 2.1", "level": 3, "children": [ 
      {"text": "Test 2.1.1", "level": 4, "children": []} 
     ]}, 
     {"text": "Test 2.2", "level": 3, "children": []} 
    ]} 
] 

我猜的功能应该是递归的,而且应该是这样的:

headings = $('.show-in-toc:header'); // Maybe .toArray() ? 
toc = generateToc(headings, 2); // With 2 being the starting level 

我试图启发算法from this subject但我没有得到任何结果(他们直接把结果放到一个dom元素中)。

你有什么建议可以指导我吗?预先感谢您

+1

可能重复:https://*.com/questions/187619/is-there-a-javascript-solution-to-generating-a-table-of-contents-for-a-page – Snowmonkey

+0

@ Snowmonkey谢谢你,我没有看到那个。我会试着去研究它,但是起初看起来它的工作方式与我链接的方法非常相似 –

我终于设法做我想要的算法,感谢评论给了我一点提示。这里是the result on a JSFiddle,我会解释它并在稍后评论它,尽管它很容易理解。

function headerTagToObject(tag, level) { 
    tag = $(tag); 
    return { 
     'title': tag.text(), 
     'level': level, 
     'children': [] 
    } 
} 

function generateToc(level, filter = undefined, initial_parent = undefined, parent = undefined) { 
    var result, tags; 
    result = []; 
    if (parent) { 
     tags = $(parent).nextUntil('h' + (level - 1), 'h' + level).filter(filter); 
    } else { 
     if (initial_parent) { 
      tags = $(initial_parent).find('h' + level).filter(filter); 
     } else { 
      tags = $('h' + level).filter(filter); 
     } 

    } 

    tags.each(function(i, tag) { 
     var tagResult; 
     tagResult = headerTagToObject(tag, level); 
     tagResult['children'] = generateToc(level + 1, filter, initial_parent, tag); 
     result.push(tagResult); 
    }); 
    return result; 
} 

// Usage 
result = generateToc(2, '.show-in-toc', '#content');