219 lines
5.2 KiB
JavaScript
219 lines
5.2 KiB
JavaScript
function addPageNumbers() {
|
|
let pages = document.getElementsByTagName('section')
|
|
|
|
for (let i = 2; i <= pages.length; i++) {
|
|
let div = document.createElement('div')
|
|
div.classList.add('page-number')
|
|
div.textContent = i
|
|
pages[i - 1].id = 'page-' + i
|
|
pages[i - 1].appendChild(div)
|
|
}
|
|
}
|
|
|
|
function addTableOfContents() {
|
|
let pages = document.getElementsByTagName('section')
|
|
let hs = document.querySelectorAll('h1,h2,h3')
|
|
let ol = document.createElement('ol')
|
|
ol.classList.add('table-of-contents')
|
|
|
|
let prefix_counter = [0, 0, 0]
|
|
let page_counter = 2
|
|
let page = document.querySelector('section')
|
|
|
|
for (const h of hs) {
|
|
let level = {
|
|
'H1': 0,
|
|
'H2': 1,
|
|
'H3': 2,
|
|
}[h.tagName]
|
|
|
|
prefix_counter[level]++
|
|
for (let i = level + 1; i < prefix_counter.length; i++)
|
|
prefix_counter[i] = 0
|
|
|
|
let prefix = ''
|
|
for (let i = 0; i <= level; i++)
|
|
prefix += prefix_counter[i] + '.'
|
|
|
|
prefix = prefix.slice(0, prefix.length - 1)
|
|
|
|
let li = document.createElement('li')
|
|
let name = document.createElement('span')
|
|
let page_number = document.createElement('a')
|
|
|
|
name.innerHTML = prefix + ' — ' + h.innerHTML
|
|
name.style.paddingLeft = level * 15 + 'px'
|
|
h.innerHTML = name.innerHTML
|
|
|
|
let cur_page = h.closest('section')
|
|
while (page && page != cur_page) {
|
|
page = page.nextElementSibling
|
|
if (page.tagName == 'SECTION') {
|
|
page_counter++
|
|
}
|
|
}
|
|
page_number.href = '#page-' + page_counter
|
|
page_number.innerHTML = page_counter
|
|
|
|
li.append(name, page_number)
|
|
ol.appendChild(li)
|
|
}
|
|
|
|
let header = document.createElement('header')
|
|
header.innerText = 'Содержание'
|
|
let section = document.createElement('section')
|
|
section.classList.add('col')
|
|
pages[0].after(section)
|
|
pages[1].appendChild(header)
|
|
pages[1].appendChild(ol)
|
|
}
|
|
|
|
function addCaptions() {
|
|
const objs = document.querySelectorAll('img, table')
|
|
const obj_counter = {
|
|
'IMG': 1,
|
|
'TABLE': 1,
|
|
}
|
|
|
|
const counter_by_tag = {}
|
|
|
|
for (const obj of objs) {
|
|
const cap = document.createElement('caption')
|
|
|
|
const prefix = {
|
|
'IMG': 'Рисунок ',
|
|
'TABLE': 'Таблица ',
|
|
}[obj.tagName] + obj_counter[obj.tagName]
|
|
|
|
cap.innerHTML = prefix + ' — ' + {
|
|
'IMG': obj.alt,
|
|
'TABLE': obj.dataset.alt,
|
|
}[obj.tagName]
|
|
|
|
let div = document.createElement('div')
|
|
div.classList.add(...({
|
|
'IMG': ['col', 'y-center'],
|
|
'TABLE': ['colr', 'y-start'],
|
|
})[obj.tagName])
|
|
div.style.cssText = obj.style.cssText
|
|
if (obj.dataset.style) {
|
|
obj.style = obj.dataset.style
|
|
} else {
|
|
obj.style.cssText = 'width: 100%'
|
|
}
|
|
|
|
if (obj.dataset.tag) {
|
|
counter_by_tag[obj.dataset.tag] = obj_counter[obj.tagName]
|
|
div.id = 'tag-' + obj.dataset.tag
|
|
}
|
|
|
|
let prev = obj.previousSibling
|
|
obj.remove()
|
|
div.append(obj, cap)
|
|
prev.after(div)
|
|
obj_counter[obj.tagName]++
|
|
}
|
|
|
|
const refs = document.querySelectorAll('span[data-ref],a[data-ref]')
|
|
|
|
for (const ref of refs) {
|
|
switch (ref.tagName) {
|
|
case 'A':
|
|
ref.href = '#tag-' + ref.dataset.ref
|
|
case 'SPAN':
|
|
ref.innerHTML = counter_by_tag[ref.dataset.ref] ?? 'без номера'
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
function genTables() {
|
|
let tables = document.getElementsByTagName('table')
|
|
|
|
for (const table of tables) {
|
|
if (!table.dataset.gen)
|
|
continue
|
|
|
|
let row = document.createElement('tr')
|
|
let dot = document.createElement('td')
|
|
let value = ''
|
|
|
|
const gen = table.dataset.gen
|
|
for (let i = 0; i < gen.length;) {
|
|
const char = gen[i]
|
|
switch (char) {
|
|
case ',':
|
|
dot.innerHTML = value
|
|
value = ''
|
|
row.appendChild(dot)
|
|
dot = document.createElement('td')
|
|
i++
|
|
break
|
|
|
|
case ';':
|
|
dot.innerHTML = value
|
|
value = ''
|
|
row.appendChild(dot)
|
|
dot = document.createElement('td')
|
|
table.appendChild(row)
|
|
row = document.createElement('tr')
|
|
i++
|
|
break
|
|
|
|
case '$':
|
|
const args_end = gen.indexOf('$', i + 1)
|
|
const args = gen.slice(i + 1, args_end).split(',')
|
|
switch (args[0]) {
|
|
case 'C':
|
|
dot.colSpan = +args[1]
|
|
break
|
|
|
|
case 'R':
|
|
dot.rowSpan = +args[1]
|
|
break
|
|
|
|
case 'c':
|
|
dot.style.backgroundColor = {
|
|
'r': 'lightcoral',
|
|
'g': 'lightgreen',
|
|
'b': 'lightblue',
|
|
}[args[1]] ?? 'white'
|
|
break
|
|
}
|
|
i = args_end + 1
|
|
break
|
|
|
|
default:
|
|
value += char
|
|
i++
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function genMathML() {
|
|
TeXZilla.setSafeMode(true)
|
|
const maths = document.querySelectorAll('.tex')
|
|
|
|
for (const math of maths)
|
|
TeXZilla.filterElement(math)
|
|
}
|
|
|
|
function handleQueryParams() {
|
|
const params = new URLSearchParams(location.search)
|
|
if (params.has('printable')) {
|
|
const pages = document.querySelectorAll('section.landscape')
|
|
for (const page of pages) {
|
|
page.style.transform = 'rotate(90deg)'
|
|
}
|
|
}
|
|
}
|
|
|
|
addTableOfContents()
|
|
addPageNumbers()
|
|
addCaptions()
|
|
genTables()
|
|
genMathML()
|
|
handleQueryParams()
|