Simple book MD syntax does not recognize [TOC], also will not according to the title line (#) to insert directory, as each time to see the information like to see the directory to grasp the overall ME, very not accustomed to, search jump is not convenient, so consider their own write a small script automatically identify and generate directory; OS: MAC 10.12 Chrome: 59.0

Brief book directory script address

preface

  1. I was trying to do a sidebar from Octotree, The directory does not scroll with the content of the article, which is similar to the navigation pane of MS Word, but the technology is not home, and if you want to make chrome Extension, you have to put it on the shelf (developer mode loading plug-in seems to prompt warning, not like), feeling a little complicated, give up;

  2. Use Tampermonkey, a user script manager, to write a small tool that automatically recognizes header lines and generates an ordered list.

Jianshu MD AUTO Scroll is a script that will Scroll the edit area and preview area simultaneously when writing an article.

Train of thought

By identifying h2, H3, H4, H5,h6 title lines, insert the list at the beginning of the article, indent according to the title level, click to jump; P.S. Since the main title of the short book article is H1, it is not inserted into the directory by default. I started to identify it from H2 and can modify the script by myself if necessary.

1. HTML page automatically jump method

Either way, you have to add the ID attribute to the target location tag, and the text header line does not have the ID attribute by default, as shown below:

2. Iterate and addidattribute

Because the book comes with jquery, you can use it directly.

var menuIndex = 0;
var firstPaddingOrder = 1; // The first header line tag level 

-> 1,

-> 2, the first level is not indent

let titles = $('body').find('h2,h3,h4,h5,h6'); if(titles.length == 0) {return; } // Get the first table of contents line hierarchy in the article except for the title let firstElement = titles.first(); let firstTagName = firstElement[0].tagName; firstPaddingOrder = parseInt(firstTagName.substring(1)); // Iterate through all the title lines in the article, adding id values as needed, and adding records to the directory list titles.each(function(){ let tagName = $(this) [0].tagName.toLocaleLowerCase(); let content = $(this).text(); // Title content // If the title id does not exist, use the new id let newTagId =$(this).attr('id'); if(! $(this).attr('id')){ newTagId = 'id_'+menuIndex; $(this).attr('id',newTagId); menuIndex++; // Inserts the searched header line information into the directoryappendMenuItem(tagName,newTagId,content); }});Copy the code

3. Insert the list at the beginning of the article

, so you can insert a < OL > tag at the beginning of that div;

// Add an aside sidebar inside the body tag to display the document's contents
$('.show-content').prepend('
      );
$('#sideMenu').append('
      );// Do not display the default dot symbol before the li entry, and do not use the default indentation
Copy the code

P.S. wanted it to be aside bar, so it used it aside.

4. Insert the title line information to the directory list

This is optimized to indent by level, but the default first-level title of the article content (h1 is not considered) is not indent. For example, if the first-level title of the article is H3 and the second-level title is H4, the table of contents will only be indent 20px from h4.

function appendMenuItem(tagName,id,content){
    let paddingLeft = (tagName.substring(1) - firstPaddingOrder) * 20;
    $('#menu_nav_ol').append('<li class="' + id +'" style="padding-left: '+ paddingLeft +'px;" > ' + content + '</li>');
}
Copy the code

5. Click jump to set the item in the directory list

$('#menu_nav_ol').append('<li class="' + id +'" style="padding-left: '+ paddingLeft +'px;" >+id+'" >' + content + '</a></li>');`
Copy the code

But as I said at the beginning, this method changes the URL (which doesn’t really matter), so I use the fourth method:

// Bind directory li click event, click to jump to the corresponding location
$('#menu_nav_ol li').on('click'.function () {
    let targetId = $(this).attr('class');
    // document.getElementById(id).scrollIntoView();
    $("#" + targetId)[0].scrollIntoView(true);
});
Copy the code

Full script

// ==UserScript==
// @name Jianshu side menu
// @name: zh-cn
// @description: zh-cn Automatically inserts directories
// @namespace https://github.com/lucid-lynxz
/ / @ version 0.1
// @description try to take over the world!
// @author Lynxz
// @match http://www.jianshu.com/p/*
//// @require http://code.jquery.com/jquery-latest.js
// @grant none
// ==/UserScript==
// A script that automatically inserts text into a directory for tamperMonkey
// Jquery already comes with jquery, so you don't need to add this dependency
var menuIndex = 0;
var firstPaddingOrder = 1; // The first header line tag level 

-> 1,

-> 2, the first level is not indent

function scrollToView(id) { var element = $("#" + id)[0]; console.log(id + " \n" + element); // document.getElementById(id).scrollIntoView(); element.scrollIntoView(); } // Add a directory entry to the sidebar function appendMenuItem(tagName, id, content) { let paddingLeft = (tagName.substring(1) - firstPaddingOrder) * 20; //$('#menu_nav_ol').append('
  • ' + content + '
  • ');
    $('#menu_nav_ol').append('<li class="' + id + '" style="padding-left: ' + paddingLeft + 'px;" > ' + content + '</li>'); //$('#menu_nav_ol').append('
  • ' + content + '
  • ');
    } (function () { 'use strict'; let titles = $('body').find('h2,h3,h4,h5,h6'); if (titles.length == 0) { return; } // Add an aside sidebar inside the body tag to display the document's contents $('.show-content').prepend(' ); $('#sideMenu').append(' );// Do not display the default dot symbol before the li entry, and do not use the default indentation // Get the first table of contents line hierarchy in the article except for the title let firstElement = titles.first(); let firstTagName = firstElement[0].tagName; firstPaddingOrder = parseInt(firstTagName.substring(1)); // Iterate through all the title lines in the article, adding id values as needed, and adding records to the directory list titles.each(function () { let tagName = $(this) [0].tagName.toLocaleLowerCase(); let content = $(this).text(); // console.log('oriId = '+$(this).attr('id') + '\t menuIndex = ' + menuIndex); // If the title id does not exist, use the new id let newTagId = $(this).attr('id'); if(! $(this).attr('id')) { newTagId = 'id_' + menuIndex; $(this).attr('id', newTagId); menuIndex++; } // console.log('newId = ' +newTagId); appendMenuItem(tagName, newTagId, content); }); $('#sideMenu').append('</ol>'); // Bind directory li click event, click to jump to the corresponding location $('#menu_nav_ol li').on('click'.function () { let targetId = $(this).attr('class'); // document.getElementById(id).scrollIntoView(); $("#" + targetId)[0].scrollIntoView(true); }); }) ();Copy the code

    P.S. function and code are very simple, but use, in addition to write two small scripts, there is a need can also be installed:

    1. CSDN AD clearance please adapt the width
    2. Nuggets blog posts do not login directly display the full text