Skip to content

Instantly share code, notes, and snippets.

@arthurattwell
Last active February 17, 2023 11:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arthurattwell/9eee6538411ac228d0caf33ed13e9ddc to your computer and use it in GitHub Desktop.
Save arthurattwell/9eee6538411ac228d0caf33ed13e9ddc to your computer and use it in GitHub Desktop.
Script for grabbing Electric Book nav and toc yaml from HTML
// Standard JS
/* globals window, copy */
// This script returns Electric-Book-compatible
// YAML for use in the nav and toc in _data/works.
// It's intended for EBTv2 (2023).
//
// Usage:
// 1. Generate the output HTML of a book.
// 2. Open the page you need TOC yaml for in a browser (e.g. 01.html)
// 3. Open the Inspect window (F12) and go to the Console tab.
// 4. Paste this entire script in there and press Enter.
// 5. The yaml that appears will be on your clipboard. Paste it into a text file.
// 6. To change the heading depth you need, edit the value of
// 'whichHeadings', under Options below. Use CSS selectors.
//
// Note: you mileage may vary, based on whether your text includes
// unusual markup. This script was tested mostly in Chrome.
// Options:
const whichHeadings = '.content h1, .content h2, .content h3, .content h4, .content h5, .content h6'
// Now for the main event
// Get the page name and all the headings in the doc,
// and create an empty entries array.
const path = window.location.pathname
const page = path.split('/').pop()
const headings = document.querySelectorAll(whichHeadings)
const entries = []
// Create a function for removing CSS-based capitalisation
function normalCase (element) {
'use strict'
element.style.textTransform = 'none'
return element
}
// Create a YAML entry from a heading, and its
// predecessor and successor, and add it to entries.
function createEntry (heading, previousHeading, nextHeading) {
'use strict'
const file = page.replace('.html', '')
const id = heading.id
// Remove CSS capitalisation from headings, and
// remove any markup tags and line breaks.
heading = normalCase(heading)
const label = heading.innerText.replace(/\n/, ' ')
const tag = heading.tagName
const headingLevel = tag.replace('H', '')
const headingLevelNumber = parseInt(headingLevel)
const twoSpaces = ' '
const indent = twoSpaces.repeat(headingLevelNumber * 2)
let entryChildren = ''
// We don't use these vars yet, but might
// in future versions of this script.
let isChild = false
let isParent = false
let isOlderSibling = false
let isYoungerSibling = false
// Check if this is a child item
let previousHeadingLevelNumber
if (previousHeading !== 'none') {
const previousHeadingLevel = previousHeading.tagName.replace('H', '')
previousHeadingLevelNumber = parseInt(previousHeadingLevel)
if (previousHeadingLevelNumber < headingLevelNumber) {
isChild = true // eslint-disable-line
}
}
// Check if this is a parent item, and
// if so, add the children
if (nextHeading !== 'none') {
const nextHeadingLevel = nextHeading.tagName.replace('H', '')
const nextHeadingLevelNumber = parseInt(nextHeadingLevel)
if (nextHeadingLevelNumber > headingLevelNumber) {
entryChildren = indent + ' children:\n'
isParent = true // eslint-disable-line
}
// Check if this is an older sibling item
if (nextHeadingLevelNumber === headingLevelNumber) {
isOlderSibling = true // eslint-disable-line
}
// Check if this is a younger sibling item
if (previousHeadingLevelNumber === headingLevelNumber) {
isYoungerSibling = true // eslint-disable-line
}
}
// Build the YAML for this entry...
const entry = indent + '- file: "' + file + '"\n' +
indent + ' id: "' + id + '"\n' +
indent + ' label: "' + label + '"\n' + entryChildren
// ...and add it to the entries array
entries.push(entry)
}
// Loop through all the headings, and pass each one
// to the createEntry function
function makeYAML (alltheheadings) {
'use strict'
alltheheadings.forEach(function (item, index) {
const thisEntry = item
let previousEntry
if (index === 0) {
previousEntry = 'none'
} else {
previousEntry = alltheheadings[index - 1]
}
let nextEntry
if (index === alltheheadings.length - 1) {
nextEntry = 'none'
} else {
nextEntry = alltheheadings[index + 1]
}
createEntry(thisEntry, previousEntry, nextEntry)
})
}
// Call the makeYAML() function to make the yaml
makeYAML(headings)
// Write the yaml to a variable
let yaml = ''
entries.forEach(function (entry) {
'use strict'
yaml += entry
})
// Write the yaml to the console
console.log(yaml)
copy(yaml)
/*jslint browser */
/*globals window, copy */
// This script returns Electric-Book-compatible
// YAML for use in the nav and toc in meta.yml.
//
// Usage:
// 1. Generate the output HTML of a book.
// 2. Open the page you need TOC yaml for in a browser (e.g. 01.html)
// 3. Open the Inspect window (F12) and go to the Console tab.
// 4. Paste this entire script in there and press Enter.
// 5. The yaml that appears will be on your clipboard. Paste it into a text file.
// 6. To change the heading depth you need, edit the value of
// 'whichHeadings', under Options below. Use CSS selectors.
//
// Note: you mileage may vary, based on whether your text includes
// unusual markup. This script was tested mostly in Chrome.
// Options:
var whichHeadings = '#content h1, #content h2, #content h3, #content h4, #content h5, #content h6';
// Now for the main event
// Get the page name and all the headings in the doc,
// and create an empty entries array.
var path = window.location.pathname;
var page = path.split("/").pop();
var headings = document.querySelectorAll(whichHeadings);
var entries = [];
// Create a function for removing CSS-based capitalisation
function normalCase(element) {
'use strict';
element.style.textTransform = "none";
return element;
}
// Create a YAML entry from a heading, and its
// predecessor and successor, and add it to entries.
function createEntry(heading, previousHeading, nextHeading) {
'use strict';
var file = page.replace('.html', '');
var id = heading.id;
// Remove CSS capitalisation from headings, and
// remove any markup tags and line breaks.
heading = normalCase(heading);
var label = heading.innerText.replace(/\n/, " ");
var tag = heading.tagName;
var headingLevel = tag.replace('H', '');
var headingLevelNumber = parseInt(headingLevel);
var twoSpaces = ' ';
var indent = twoSpaces.repeat(headingLevelNumber * 2);
var entryChildren = '';
// Check if this is a child item
var previousHeadingLevelNumber;
if (previousHeading !== 'none') {
var previousHeadingLevel = previousHeading.tagName.replace('H', '');
previousHeadingLevelNumber = parseInt(previousHeadingLevel);
if (previousHeadingLevelNumber < headingLevelNumber) {
var isChild = true;
}
}
// Check if this is a parent item, and
// if so, add the children
if (nextHeading !== 'none') {
var nextHeadingLevel = nextHeading.tagName.replace('H', '');
var nextHeadingLevelNumber = parseInt(nextHeadingLevel);
if (nextHeadingLevelNumber > headingLevelNumber) {
entryChildren = indent + ' children:\n';
var isParent = true;
}
// Check if this is an older sibling item
if (nextHeadingLevelNumber === headingLevelNumber) {
var isOlderSibling = true;
}
// Check if this is a younger sibling item
if (previousHeadingLevelNumber === headingLevelNumber) {
var isYoungerSibling = true;
}
}
// Build the YAML for this entry...
var entry = indent + '- file: "' + file + '"\n' +
indent + ' id: "' + id + '"\n' +
indent + ' label: "' + label + '"\n' + entryChildren;
// ...and add it to the entries array
entries.push(entry);
}
// Loop through all the headings, and pass each one
// to the createEntry function
function makeYAML(alltheheadings) {
'use strict';
alltheheadings.forEach(function (item, index) {
var thisEntry = item;
var previousEntry;
if (index === 0) {
previousEntry = 'none';
} else {
previousEntry = alltheheadings[index - 1];
}
var nextEntry;
if (index === alltheheadings.length - 1) {
nextEntry = 'none';
} else {
nextEntry = alltheheadings[index + 1];
}
createEntry(thisEntry, previousEntry, nextEntry);
});
}
// Call the makeYAML() function to make the yaml
makeYAML(headings);
// Write the yaml to a variable
var yaml = "";
entries.forEach(function (entry) {
'use strict';
yaml += entry;
});
// Write the yaml to the console
console.log(yaml);
copy(yaml);
@arthurattwell
Copy link
Author

arthurattwell commented Oct 8, 2017

To save having to copy–paste the script into the console for every chapter, you can embed the script on your Electric Book site temporarily by adding it between <script> </script> tags to _includes/end-elements:

<script>
// paste script here
</script>

Then just visit any page and view the Inspector console to see its yaml.

Make sure you remove the script when you're done. Do not leave this script running on a live site.

@ChristinaTromp
Copy link

@arthurattwell this script is no longer working for me in Chrome or Safari for equss or core, it always has previously. Does it still work for you?

@DioneMentis please can you try use this script? [You would copy the whole thing, generate equss, right-click and choose inspect, open the console and paste this in and press enter.]

@ChristinaTromp
Copy link

This worked for me when I tried to use it today, it took a minute to log in the console (it used to be instant) but it worked

@ChristinaTromp
Copy link

ChristinaTromp commented Jul 23, 2018

I had to look in the hidden 'info' section of the console, under the 'other' subsection:

screen shot 2018-07-23 at 11 22 58

@arthurattwell
Copy link
Author

I've neatened the script syntax and it now puts the yaml on your clipboard for instant pasting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment