Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

another-toc-solution-for-blogdown-fixing-the-pure-Chinese-issue #17

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions exampleSite/content/post/2018-01-11-test-toc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
title: another toc solution for blogdown fixing the pure Chinese issue
author: Heaven Zone
date: '2018-01-11'
slug: another-toc-solution-for-blogdown-fixing-the-pure-Chinese-issue
categories:
- R
tags:
- R
- blogdown
simpletoc: true
---

## origination

after taking a little bit of effort to read these two articles in ENGLISH from yihui's blog: [1st](https://yihui.name/en/2017/12/blogdown-book/), [2nd](https://yihui.name/en/2017/09/pull-requests-as-a-teaching-tool/), I decided to make a pull request to give some feedbacks to Yihui.

As a amateur and beginneR, thanks for Yihui's GREAT present BLOGDOWN.

@yihui, I love reading your articles, especially the Chinese articles, like: [16 小时骑行——我的天津绝望之旅](https://yihui.name/cn/2005/08/ride-to-tianjin-in-16-hours/). Yihui's words are always sharp. I feel some sad that it has been a very very long time since you last updated your blog for Chinese articles as a literary youth.

## feture

1. Originally intended for fixing the issue that not generating the links for pure Chinese headlines
1. Toc with fixed position floating right
1. Automatically generate the sections numbers

## usage

just add `simpletoc: true` into the block `---`.

### like this:

```
title: another toc solution for blogdown fixing the pure Chinese issue
author: Heaven Zone
date: '2018-01-11'
slug: another-toc-solution-for-blogdown-fixing-the-pure-Chinese-issue
categories:
- R
tags:
- R
- blogdown
simpletoc: true
```

### what i did for this pull requrest?

1. add one partial file `simpletoc.html`
1. add one js file `simpletoc.js`
1. modified single.html appending three rows of codes
1. add one post for example using custom param `simpletoc: true` for generating the toc

#### H4 Test Section

Test

## H2 Test Section

7 changes: 6 additions & 1 deletion layouts/_default/single.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ <h1><span class="title">{{ .Title }}</span></h1>
{{ if .Params.date }}<h2 class="date">{{ .Date.Format "2006/01/02" }}</h2>{{ end }}
</div>

<main>
<main id="post-content">

{{ if .Params.simpletoc }}
{{ partial "simpletoc.html" . }}
{{ end }}

{{ .Content }}
</main>

Expand Down
19 changes: 19 additions & 0 deletions layouts/partials/simpletoc.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<script src="/js/simpletoc.js"></script>
<script>
var firstLvl = 2; // h2 start
var lastLvl = 4; // h4 end
var divID = "TOC";
var divToSearch = "post-content";
window.onload=function(){
//params
// param1:firstlevel,default: h2
// param2:lastLevel,defualt: h3
// param3:divID, the div to place the toc,default: TOC
// param4:the wrapper div containing headlines to search
toc(firstLvl, lastLvl, divID, divToSearch);
diyStyle(divID);
addNewStyle('@media (max-width: 48em) {#'+divID+'{display: none;} }');
addNewStyle('.TOCSectNum {margin-right: 0.5em;}');
}
</script>
<div id="TOC"></div>
155 changes: 155 additions & 0 deletions static/js/simpletoc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/**
* 本代码修改自:https://www.cnblogs.com/qiudeqing/p/3229583.html
*
*
*/
// =================添加变量控制标题深度
// 默认是h2至h4;
// 定于全局divID,方便toc函数和diyStyle参数调用
function isInArray(value, arr)
{
for (var i = 0; i < arr.length; i++)
{
if (value === arr[i])
{
return true;
}
}
return false;
}

function toc(firstLevel = 2, lastLevel = 3, divID = "TOC", divToSearch = "")
{

// 如果参数设置不正确的调整
if (firstLevel < 1 || firstLevel > 6 || firstLevel > lastLevel)
firstLevel = 2;
if (lastLevel < firstLevel || lastLevel > 6)
lastLevel = 3;
if (divToSearch == "")
{
elementToSearch = document.body;
}
else
{
elementToSearch = document.getElementById(divToSearch);
}
var depth = lastLevel - firstLevel + 1;
var searchHeadings = new Array();

// Find the TOC container element.
// If there isn't one, create one at the start of the document.
var toc = document.getElementById(divID);
if (!toc)
{
toc = document.createElement("div");
toc.id = divID;
document.body.insertBefore(toc, document.body.firstChild);
}
// Find all section heading elements
var headings;
// =================生成要生成toc标题的标签
for (var i = firstLevel; i < firstLevel + depth; i++)
{
searchHeadings[i] = "H" + i;
}
//if (document.querySelectorAll) // Can we do it the easy way?
// headings = document.querySelectorAll("h1,h2,h3,h4,h5,h6");
//else // Otherwise, find the headings the hard way
// ==================用elementToSearch控制搜索范围
headings = findHeadings(elementToSearch, [], searchHeadings);
// Recursively traverse the document body looking for headings
function findHeadings(root, sects)
{
for (var c = root.firstChild; c != null; c = c.nextSibling)
{
if (c.nodeType !== 1)
continue;
//if (c.tagName.length == 2 && c.tagName.charAt(0) == "H")
// ================= 判断tagName是否在设置的标签里面
if (isInArray(c.tagName, searchHeadings))
sects.push(c);
else
findHeadings(c, sects);
}
return sects;
}
// Initialize an array that keeps track of section numbers.
var sectionNumbers = [0, 0, 0, 0, 0, 0];
// Now loop through the section header elements we found.
for (var h = 0; h < headings.length; h++)
{
var heading = headings[h];
// Skip the section heading if it is inside the TOC container.
if (heading.parentNode == toc)
continue;
// Figure out what level heading it is.
var level = parseInt(heading.tagName.charAt(1));
if (isNaN(level) || level < 1 || level > 6)
continue;
// Increment the section number for this heading level
// and reset all lower heading level numbers to zero.
sectionNumbers[level - 1]++;
for (var i = level; i < 6; i++)
sectionNumbers[i] = 0;
// Now combine section numbers for all heading levels
// to produce a section number like 2.3.1.
//=================修改成从firstLevel开始生成toc
var sectionNumber = sectionNumbers.slice(firstLevel - 1, level).join(".")
// Add the section number to the section header title.
// We place the number in a <span> to make it styleable.
var span = document.createElement("span");
span.className = "TOCSectNum";
span.innerHTML = sectionNumber;
heading.insertBefore(span, heading.firstChild);
//===============改成直接在headlines上添加id用于链接跳转
heading.setAttribute("id", divID + sectionNumber);

// Wrap the heading in a named anchor so we can link to it.
//var anchor = document.createElement("a");
//anchor.name = "TOC"+sectionNumber;
//heading.parentNode.insertBefore(anchor, heading);
//anchor.appendChild(heading);

// Now create a link to this section.
var link = document.createElement("a");
link.href = "#" + divID + sectionNumber; // Link destination
link.innerHTML = heading.innerHTML; // Link text is same as heading
// Place the link in a div that is styleable based on the level.
var entry = document.createElement("div");
//=================修改成firstLevel的标题在生成cssClass的名称的level为1开始递增
level = level - firstLevel + 1;
entry.className = "TOCEntry TOCLevel" + level;
entry.appendChild(link);
// And add the div to the TOC container.
toc.appendChild(entry);
}
}

// 添加样式函数
function addNewStyle(newStyle)
{
var styleElement = document.getElementById('styles_js');

if (!styleElement)
{
styleElement = document.createElement('style');
styleElement.type = 'text/css';
styleElement.id = 'styles_js';
document.getElementsByTagName('head')[0].appendChild(styleElement);
}
styleElement.appendChild(document.createTextNode(newStyle));
}
// 自定义样式,用不同的divid也可以有默认样式
function diyStyle(divID)
{
addNewStyle('#' + divID + ' .TOCSectNum { padding-right: 0.3em; }');
addNewStyle('#' + divID + ' a { text-decoration: none; color: #0077bb !important; }');
addNewStyle('#' + divID + ' .TOCLevel1 { padding-left: 0.2em; border-left:#0077bb solid 0.2em;}');
for (i = 2; i <= 6; i++)
{
k = i - 1;
addNewStyle('#' + divID + ' .TOCLevel' + i + ' { margin-left: ' + k + 'em;}');
}
addNewStyle('#' + divID + ' {float:right;margin:0 0 1em 1em;position:fixed;top:50px;right:50px;border: 1px solid #ccc;webkit-border-radius: 6px;moz-border-radius: 6px;border-radius: 12px;padding: 0.8em;}');
}