mirror of https://github.com/Qiskit/qiskit.org.git
Autogenerate textbook TOC (#103)
* Change to nuxt-ts to support TypeScript at build time * Add jest infrastructure * Automatize creation of content/education/textbook-toc.md for /education preview * Test the functionality
This commit is contained in:
parent
f7b0a47703
commit
c810752dc6
|
@ -7,6 +7,11 @@ module.exports = {
|
|||
'@nuxtjs'
|
||||
],
|
||||
rules: {
|
||||
// TODO: Remove when fixing:
|
||||
// https://github.com/typescript-eslint/typescript-eslint/issues/342
|
||||
// More info:
|
||||
// https://github.com/typescript-eslint/typescript-eslint/issues/342#issuecomment-484739065
|
||||
'no-undef': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'error'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
## Table of Contents
|
||||
|
||||
### Preface
|
||||
- Structure of this Textbook
|
||||
|
||||
### Chapter 0. Prerequisites
|
||||
- Python and Jupyter Notebooks
|
||||
- Qiskit
|
||||
- Exercises
|
||||
|
||||
- Linear Algebra
|
||||
### Chapter 1. Quantum States and Qubits
|
||||
- Introduction
|
||||
- The Atoms of Computation
|
||||
|
@ -15,8 +10,6 @@
|
|||
- Writing Down Qubit States
|
||||
- Pauli Matrices and the Bloch Sphere
|
||||
- States for Many Qubits
|
||||
- Exercises
|
||||
|
||||
### Chapter 2. Single-Qubit and Multi-Qubit Gates
|
||||
- Introduction
|
||||
- Quantum Gates
|
||||
|
@ -24,8 +17,6 @@
|
|||
- The Standard Gate Set
|
||||
- Proving Universality
|
||||
- Basic Circuit Identities
|
||||
- Exercises
|
||||
|
||||
### Chapter 3. Quantum Algorithms
|
||||
- Quantum Teleportation
|
||||
- Deutsch-Josza Algorithm
|
||||
|
@ -34,17 +25,14 @@
|
|||
- Quantum Fourier Transform
|
||||
- Quantum Phase Estimation
|
||||
- Grover's Algorithm
|
||||
- Exercises
|
||||
|
||||
### Chapter 4. Quantum Algorithms for Applications
|
||||
- Simulating Molecules using VQE
|
||||
- Solving Satisfiability Problems using Grover's Algorithm
|
||||
- Exercises
|
||||
|
||||
### Chapter 5. Investigating Quantum Hardware Using Qiskit
|
||||
- Calibrating Qubits with OpenPulse
|
||||
- Introduction to Quantum Error Correction using Repetition Codes
|
||||
- Measurement Error Mitigation
|
||||
- Randomized Benchmarking
|
||||
- Measuring Quantum Volume
|
||||
- Exercises
|
||||
### Chapter 6. Implementations of Recent Quantum Algorithms
|
||||
- Variational Quantum Linear Solver
|
|
@ -0,0 +1,16 @@
|
|||
import fs from 'fs'
|
||||
import { extractToc, formatTocLines } from './textbook-toc-utils'
|
||||
|
||||
/**
|
||||
* Extract the table of contents at `indexPath` and uses it to generate
|
||||
* a markdown TOC at `tocPath`, suitable for being rendered in `/education`.
|
||||
*
|
||||
* @param indexPath HTML file where the TOC is extracted from.
|
||||
* @param tocPath output Markdown file path where TOC is generated.
|
||||
*/
|
||||
export default function generateTextbookToc(indexPath: string, tocPath: string) {
|
||||
const indexContent = fs.readFileSync(indexPath, 'utf8')
|
||||
const toc = extractToc(indexContent)
|
||||
const mdTocLines = formatTocLines(toc)
|
||||
fs.writeFileSync(tocPath, mdTocLines.join('\n'))
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
type TocType = Array<[string, string[]]>
|
||||
|
||||
export { extractToc, formatTocLines, TocType }
|
||||
|
||||
function extractToc(indexContent: string): TocType {
|
||||
// Chapter titles are of form `Chapter X. Chapter title<`.
|
||||
const allChapters = (indexContent.match(/Chapter\s+\d+\.\s+[^<]+/g) || [])
|
||||
.map(entry => entry.trim())
|
||||
// Topic titles are of form `X.Y <a ...>Topic Title<`
|
||||
const allTopics = (indexContent.match(/(\d+.\d+\s+)<a[^>]+([^<]+)/g) || [])
|
||||
.map(entry => entry.replace(/<a[^>]+>/, '').trim())
|
||||
|
||||
return allChapters.reduce<TocType>((output, title, index) => {
|
||||
const chapters = getTopics(index, allTopics)
|
||||
output.push([title, chapters])
|
||||
return output
|
||||
}, [])
|
||||
|
||||
function getTopics(index: number, allTopics: string[]) {
|
||||
return allTopics.filter(topic => topic.startsWith(`${index}.`))
|
||||
}
|
||||
}
|
||||
|
||||
function formatTocLines(toc: TocType, header: string = 'Table of Contents'): string[] {
|
||||
return withHeader(
|
||||
header,
|
||||
toc.reduce<string[]>((output, [title, chapters]) => {
|
||||
output.push(formatTitle(title))
|
||||
output.push(...formatChapters(chapters))
|
||||
return output
|
||||
}, [])
|
||||
)
|
||||
|
||||
function withHeader(title: string, lines: string[]): string[] {
|
||||
lines.unshift(`## ${title}`)
|
||||
return lines
|
||||
}
|
||||
|
||||
function formatTitle(title: string): string {
|
||||
return `### ${title}`
|
||||
}
|
||||
|
||||
function formatChapters(chapters: string[]): string[] {
|
||||
return chapters
|
||||
.map(title => `- ${(title.match(/\s.+/) as string[])[0].trim()}`)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
// Created following:
|
||||
// https://github.com/Al-un/learn-nuxt-ts/blob/master/docs/06.test.md
|
||||
|
||||
module.exports = {
|
||||
moduleNameMapper: {
|
||||
'^@/(.*)$': '<rootDir>/$1',
|
||||
'^~/(.*)$': '<rootDir>/$1'
|
||||
},
|
||||
transform: {
|
||||
'^.+\\.ts?$': 'ts-jest',
|
||||
'.*\\.(vue)$': 'vue-jest'
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'js', 'vue', 'json'],
|
||||
testMatch: ['**/tests/**/*.spec.ts'],
|
||||
collectCoverageFrom: [
|
||||
'hooks/**/*.ts'
|
||||
]
|
||||
}
|
|
@ -5,6 +5,7 @@ import miLinkAttributes from 'markdown-it-link-attributes'
|
|||
import miAnchor from 'markdown-it-anchor'
|
||||
import uslug from 'uslug'
|
||||
import pkg from './package'
|
||||
import generateTextbookToc from './hooks/generate-textbook-toc'
|
||||
|
||||
const md = markdownIt({
|
||||
linkify: true,
|
||||
|
@ -162,5 +163,16 @@ export default {
|
|||
.map(filename => `/experiments/${path.parse(filename).name}`)
|
||||
return events.concat(experiments)
|
||||
})()
|
||||
},
|
||||
|
||||
hooks: {
|
||||
build: {
|
||||
before() {
|
||||
generateTextbookToc(
|
||||
'./static/textbook/index.html',
|
||||
'./content/education/textbook-toc.md'
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
17
package.json
17
package.json
|
@ -5,12 +5,12 @@
|
|||
"author": "IBM Q Community Team",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "nuxt",
|
||||
"dev-debug": "node --debug node_modules/.bin/nuxt",
|
||||
"test": "echo \"Error: no test specified\" && exit 0",
|
||||
"dev": "nuxt-ts",
|
||||
"dev-debug": "node --debug node_modules/.bin/nuxt-ts",
|
||||
"test": "jest",
|
||||
"build": "npm run generate",
|
||||
"start": "nuxt start",
|
||||
"generate": "nuxt generate",
|
||||
"start": "nuxt-ts start",
|
||||
"generate": "nuxt-ts generate",
|
||||
"lint": "eslint --ext .ts,.js,.vue --ignore-path .gitignore ."
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -22,9 +22,13 @@
|
|||
"@nuxt/typescript-build": "^0.1.11",
|
||||
"@nuxt/typescript-runtime": "^0.1.5",
|
||||
"@nuxtjs/eslint-config": "0.0.1",
|
||||
"@types/jest": "^24.0.20",
|
||||
"@types/markdown-it": "0.0.7",
|
||||
"@typescript-eslint/eslint-plugin": "^1.13.0",
|
||||
"@typescript-eslint/parser": "^1.13.0",
|
||||
"@vue/test-utils": "^1.0.0-beta.29",
|
||||
"babel-bridge": "^1.12.11",
|
||||
"babel-core": "^6.26.3",
|
||||
"d3": "^5.11.0",
|
||||
"datamaps": "github:delapuente/datamaps#0.5.10",
|
||||
"eslint": "^5.16.0",
|
||||
|
@ -36,13 +40,16 @@
|
|||
"eslint-plugin-standard": "^4.0.1",
|
||||
"eslint-plugin-vue": "^5.2.3",
|
||||
"frontmatter-markdown-loader": "^1.8.0",
|
||||
"jest": "^24.9.0",
|
||||
"markdown-it-anchor": "^5.2.4",
|
||||
"markdown-it-link-attributes": "^2.1.0",
|
||||
"node-sass": "^4.12.0",
|
||||
"nodemon": "^1.19.2",
|
||||
"sass-loader": "^8.0.0",
|
||||
"topojson": "^3.0.2",
|
||||
"ts-jest": "^24.1.0",
|
||||
"uslug": "^1.0.4",
|
||||
"vue-jest": "^3.0.5",
|
||||
"vue-property-decorator": "^8.2.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
import { extractToc, formatTocLines, TocType } from '~/hooks/textbook-toc-utils'
|
||||
|
||||
const sampleHTML = `<p><strong>Chapter 0. Title 0</strong><br /></p>
|
||||
<p> 0.0 <a href="./ch-prerequisites/python-and-jupyter-notebooks.html">Topic 0.0</a><br />
|
||||
0.1 <a href="./ch-prerequisites/qiskit.html">Topic 0.1</a><br />
|
||||
<p><strong>Chapter 1. Title 1</strong><br /></p>
|
||||
<p> 1.0 <a href="./ch-states/introduction.html">Topic 1.0</a><br />
|
||||
1.1 <a href="./ch-states/atoms-computation.html">Topic 1.1</a><br />`
|
||||
|
||||
const expectedToc: TocType = [
|
||||
['Chapter 0. Title 0', [
|
||||
'0.0 Topic 0.0',
|
||||
'0.1 Topic 0.1'
|
||||
]],
|
||||
['Chapter 1. Title 1', [
|
||||
'1.0 Topic 1.0',
|
||||
'1.1 Topic 1.1'
|
||||
]]
|
||||
]
|
||||
|
||||
describe('extractToc', () => {
|
||||
it('recognizes and matches chapters and topics', () => {
|
||||
expect(extractToc(sampleHTML)).toEqual(expectedToc)
|
||||
})
|
||||
})
|
||||
|
||||
describe('formatTocLines', () => {
|
||||
it('generates a simplified markdown version of the toc', () => {
|
||||
expect(formatTocLines(expectedToc, 'Title')).toEqual([
|
||||
'## Title',
|
||||
'### Chapter 0. Title 0',
|
||||
'- Topic 0.0',
|
||||
'- Topic 0.1',
|
||||
'### Chapter 1. Title 1',
|
||||
'- Topic 1.0',
|
||||
'- Topic 1.1'
|
||||
])
|
||||
})
|
||||
})
|
|
@ -26,7 +26,8 @@
|
|||
},
|
||||
"types": [
|
||||
"@types/node",
|
||||
"@nuxt/types"
|
||||
"@nuxt/types",
|
||||
"@types/jest"
|
||||
]
|
||||
},
|
||||
"exclude": [
|
||||
|
|
Loading…
Reference in New Issue