Compare commits

...

55 commits

Author SHA1 Message Date
leafee98 acba79eebc fix: failed to import copy-codeblock.js when different baseURL 2024-07-08 17:52:02 +08:00
leafee98 a1aec229c5 add copy button, adjust codeblock style, close #2 2024-07-08 17:38:26 +08:00
leafee98 36c140b28c latex only render post content, other than the whole body 2024-01-23 21:09:18 +08:00
leafee98 d647841898 examplesite: add breaklines to latex-support 2024-01-19 18:18:43 +08:00
leafee98 9aebccb590 properly use archetypes, add descriptions at front matter 2023-09-11 14:48:02 +08:00
leafee98 5aec7ac354 show description of posts in index page, or summary if no description 2023-09-11 14:34:59 +08:00
leafee98 ad98c7238d narrowing the page, max-width from 1320px to 1140 2023-07-06 15:24:10 +08:00
leafee98 dbf5a656c2 use <nav> in header 2023-07-06 15:15:04 +08:00
leafee98 e4e2844c3e add tags for SEO 2023-06-29 22:22:37 +08:00
leafee98 97c892077a update images 2023-05-28 22:30:32 +08:00
leafee98 6ac660eee2 refactor color, set paginate to 4 to show the pager
- Modify color of dark theme, so it will darker and less warm.
- Remove the color `--color-fav-x` and replace with colors those
  defined in dark or light
- set paginate to 4 to show the pager in example site.
2023-05-28 22:09:18 +08:00
leafee98 99ca8932e1 remove useless css variable color 2023-05-28 13:56:42 +08:00
leafee98 dca44e659f update README 2023-05-28 13:51:40 +08:00
leafee98 37de87ec41 update bottom banner theme repository URL 2023-04-07 11:06:14 +08:00
leafee98 7a9c80595f update README and theme.toml 2023-03-17 21:06:40 +08:00
leafee98 2edfe53c29 update READEME and images 2023-03-17 20:58:58 +08:00
leafee98 5fd2d18048 Side card "recent" is clickable to post/essay list 2023-03-17 20:28:38 +08:00
leafee98 0547c3d73d Respect browser's prefered color scheme now
- Use gruvbox highlight theme when dark
2023-03-15 17:58:49 +08:00
leafee98 10441a59a8 Fix: limit the max width of image in content, new essay
Fix the appear of image in content so it wouldn't overflow the content
card.

Note that the inline image cannot be displayed in the same line as text,
because the image is centered by display:block and set margin-x as auto.
2023-01-24 21:26:35 +08:00
leafee98 fcfd69e10e Ref: change fonts 2023-01-24 17:20:30 +08:00
leafee98 7dec5ad2cd Ref: use 1.5 line-height for single page content 2023-01-23 19:43:49 +08:00
leafee98 23149c6547 Fix: wrong usage of group selector 2023-01-23 15:20:36 +08:00
leafee98 ad3d615738 Fix: style of code in ul and li 2023-01-23 15:20:36 +08:00
leafee98 b591e1e2c0 Modify demo site's content: latex-support.md 2022-11-14 22:15:52 +08:00
leafee98 c40f6af959 Remove config for github pages since deployed by actions 2022-11-14 22:11:27 +08:00
Leafee 2824974ffa
Fix workflow
Miss a backslash after command
2022-11-14 22:07:37 +08:00
Leafee d11dd64eef
Fix workflow
Hugo changed its release binaries' name since v0.103.0
2022-11-14 22:05:38 +08:00
Leafee d2c54452d8
Use GitHub actions to build demo site 2022-11-14 21:58:08 +08:00
leafee98 7bf8488165 modify post latex-support 2022-09-20 10:51:30 +08:00
leafee98 4a4f832aec add LaTeX support 2022-09-20 10:41:42 +08:00
leafee98 9a0dd8b179 add license, theme.toml 2022-09-04 19:45:50 +08:00
leafee98 1fdfa26364 add screenshots 2022-09-04 19:31:06 +08:00
leafee98 7c400e3412 fix: wrong usage of relURL 2022-09-04 19:11:04 +08:00
leafee98 0e48c7d586 add config for github pages 2022-09-04 19:00:58 +08:00
leafee98 985756dd02 fix: error parsing host as site_id in remark42 2022-07-21 19:20:16 +08:00
leafee98 a71e469a23 fix: 'with' with a logic 'and', child variable evaluated 2022-05-18 22:44:17 +08:00
leafee98 0ce04d50c7 RSS of each section are always shown
the "Feed Of ALL" is removed and "Feed Of 'Section'" is always shown
2022-05-18 21:29:55 +08:00
leafee98 e2ca0c5332 toggle comments at front matter
Whether the comment show up was determined by if the page is under
mainSection, now it's determined by front matter and config.toml
2022-05-18 21:27:06 +08:00
leafee98 836128c866 _index.md's content is shown at list page 2022-05-18 19:45:04 +08:00
leafee98 23e6e10f43 wirte README to describe multi-section support 2022-05-18 14:14:53 +08:00
leafee98 e526a8d6ca allow whole site for spider at robots.txt 2022-05-18 13:51:15 +08:00
leafee98 5b7390b5c2 add multi-section support 2022-05-18 13:50:07 +08:00
leafee98 c078c22ea3 adjust template of taxonomy and term 2022-05-18 13:45:20 +08:00
leafee98 4c7fe1a56b use .Section other than .Title to get section name 2022-05-18 11:13:01 +08:00
leafee98 715a82f5ac multi RSS hyperlink base on section and taxonomy 2022-05-16 20:41:20 +08:00
leafee98 b343bac3f9 handle all manually wirte URL with relURL 2022-05-16 18:46:25 +08:00
leafee98 babe8865cb add RSS icon following feed hyperlink 2022-05-16 18:38:33 +08:00
leafee98 6526292b08 remove first row from footer 2022-05-16 18:37:34 +08:00
leafee98 473eefc015 output full content to RSS 2022-05-13 21:29:12 +08:00
leafee98 b46d6da8ba add feed support, place the hyperlink at footer 2022-05-13 20:12:07 +08:00
leafee98 dff69c5bd3 enable robots.txt by default
use CRLF in robots.txt
2022-05-10 21:34:51 +08:00
leafee98 3b58a1a279 fix: codeblock style inconsistency
- the size of codeblock is same with hightlight now
- the pre in .content will not be afftected by reamrk42 style anymore
2022-04-29 10:46:28 +08:00
leafee98 4e73d5d1eb add theme code 2022-04-27 21:54:00 +08:00
leafee98 f85c96600b add gitignore 2022-04-27 21:53:20 +08:00
leafee98 24a3c428ba Add exmaple site 2022-04-27 21:52:45 +08:00
134 changed files with 49969 additions and 1 deletions

71
.github/workflows/hugo.yml vendored Normal file
View file

@ -0,0 +1,71 @@
# Sample workflow for building and deploying a Hugo site to GitHub Pages
name: Deploy Hugo site to Pages
on:
# Runs on pushes targeting the default branch
push:
branches: ["main"]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow one concurrent deployment
concurrency:
group: "pages"
cancel-in-progress: true
# Default to bash
defaults:
run:
shell: bash
jobs:
# Build job
build:
runs-on: ubuntu-latest
env:
HUGO_VERSION: 0.105.0
steps:
- name: Install Hugo CLI
run: |
wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \
&& sudo dpkg -i ${{ runner.temp }}/hugo.deb
- name: Checkout
uses: actions/checkout@v3
with:
submodules: recursive
- name: Setup Pages
id: pages
uses: actions/configure-pages@v2
- name: Build with Hugo
env:
# For maximum backward compatibility with Hugo modules
HUGO_ENVIRONMENT: production
HUGO_ENV: production
run: |
hugo \
--source ./exampleSite \
--minify \
--baseURL "${{ steps.pages.outputs.base_url }}/"
- name: Upload artifact
uses: actions/upload-pages-artifact@v1
with:
path: ./exampleSite/public
# Deployment job
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
exampleSite/public/
exampleSite/resources/
exampleSite/.hugo_build.lock

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 leafee98
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,7 +1,37 @@
# hugo-theme-blank
# hugo-theme-flat
This is a theme I personally use.
## Features
- Dark theme support (auto switch by css media query)
- Muti-Section supports
- Side card to display recent updated sections
- Responsive layout
- Sub-menu support
## Multi Section Supports
If you use multi sections (with the concept from hugo), the RSS at bottom and *Recent* at side are ready for displaying those content. However, you will need to set up your menu at `config.toml` to point the hyperlink to proper destination.
If you want to re-order those sections, you need a `_index.md` at the directory of the section to set proper weight at front matter, just alike what was done at the exampleSite, see `/exampleSite/content/essays/_index.md`. See the predefined variable `weight` at [docs](https://gohugo.io/content-management/front-matter/#front-matter-variables).
**Note** that separating taxonomies according to different sections is not implemented yet. So better to only use taxonomies inside a specific section.
For a better understand, if you have to posts *A* and *B* in section *S1* and *S2*, both of the posts has the same tag *T1*, like the follow.
```
post A: section S1, tag T1, tag T2
post B: section S2, tag T2
```
When you open the index page of *T1*, there will be two posts, rathor than post *A* when you are in section *S1* and post *B* when you are in section *S2*.
```
tag T1: post A, post B
tag T2: post A
```
## Special Thanks
The wordpress theme [Allium](https://wordpress.org/themes/allium/), and [here](https://templatelens.com/allium/) is its home page. I like this theme very much when I'm using wordpress, but I don't have it on hugo, so I try my best to write a theme similar with it. There are many designs in this theme refers to it.

13
archetypes/default.md Normal file
View file

@ -0,0 +1,13 @@
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
tags: []
categories: []
weight: 50
show_comments: true
katex: false
draft: true
description: ""
---
<!--more-->

83
exampleSite/config.toml Normal file
View file

@ -0,0 +1,83 @@
title = "Flat theme"
theme = "hugo-theme-flat"
themesDir = "../.."
enableRobotsTXT = true
hasCJKLanguage = true
paginate = 4
baseURL = ""
# these values are hugo built in markup config
[markup.highlight]
anchorLineNos = false
codeFences = true
guessSyntax = false
hl_Lines = ''
lineAnchors = ''
lineNoStart = 1
lineNos = false
lineNumbersInTable = false
noClasses = false
noHl = false
style = 'monokailight'
tabWidth = 4
[params]
description = "Example site for hugo-theme-flat"
mainSections = ['posts']
## uncomment belows and set proper values to enable remark42
# [params.remark42]
# host=''
# site_id=''
# max_shown_comments=100
# theme='light'
# locale='en'
# show_email_subscription=false
# simple_view=true
# you can set multi row of footers like these
[[params.footer_rows]]
[[params.footer_rows.items]]
name = "Creative Commons Attribution 4.0 International"
url = "https://creativecommons.org/licenses/by/4.0/"
pre = "Copyright <a href=\"https://creativecommons.org/licenses/by/4.0/\">CC BY-4.0</a>"
[[params.footer_rows]]
[[params.footer_rows.items]]
name = "Hugo"
url = "https://gohugo.io"
pre = "Powered by <a href=\"https://gohugo.io\">Hugo</a>"
[[params.footer_rows.items]]
name = "theme flat"
url = "https://cgit.leafee98.com/hugo-theme-flat.git"
pre = "Theme <a href=\"https://git.leafee98.com/leafee98/hugo-theme-flat.git\">hugo-theme-flat</a>"
[[menus.main]]
name = "Posts"
url = "/posts/"
weight = 30
[[menus.main]]
name = "Essays"
url = "/essays/"
weight = 40
[[menus.main]]
pageref = "about"
name = "About"
weight = 80
# 2-level sub menus are supported
[[menus.main]]
name = "Services"
weight = 60
[[menus.main]]
parent = "Services"
name = "Service A"
url = "#"
[[menus.main]]
parent = "Services"
name = "Service B"
url = "#"

View file

@ -0,0 +1,40 @@
---
title: "About"
date: 2022-04-27T21:01:43+08:00
draft: false
---
## About this demo site
This is the *about page* of this theme. The content of this demo site is come from [hugo-theme-mini](https://github.com/nodejh/hugo-theme-mini/), whose license is [MIT](https://github.com/nodejh/hugo-theme-mini/blob/39be4727b355bc8cabd919c6684d79064690a5c6/LICENSE.md)
This site is built by hugo, which is a fast static site generator writen in go. You can go to its [offical site](https://gohugo.io) to get more information.
## CJK supported
This hugo theme support CJK language, but some right to left language may not act as expected. Let's just test CJK layout!
这一句话是用中文写的,一般情况下,中英文排版如果字体设置不当,显示出来的字号会有相当的差距,即便实际上的字号是相同的。这个问题暂时看来无法彻底解决,唯一能做的就是挑选合适的字体,使相同字号下,中英文在展示出来后肉眼感官大小差别不大。
Try another typography, which make English and Chinese lay down in a single line. The word *Chinese* in Chinese is "中文".
## What is hugo
Written in Go, Hugo is an open source static site generator available under the [Apache Licence 2.0.](https://github.com/gohugoio/hugo/blob/master/LICENSE) Hugo supports TOML, YAML and JSON data file types, Markdown and HTML content files and uses shortcodes to add rich content. Other notable features are taxonomies, multilingual mode, image processing, custom output formats, HTML/CSS/JS minification and support for Sass SCSS workflows.
Hugo makes use of a variety of open source projects including:
* https://github.com/yuin/goldmark
* https://github.com/alecthomas/chroma
* https://github.com/muesli/smartcrop
* https://github.com/spf13/cobra
* https://github.com/spf13/viper
Hugo is ideal for blogs, corporate websites, creative portfolios, online magazines, single page applications or even a website with thousands of pages.
Hugo is for people who want to hand code their own website without worrying about setting up complicated runtimes, dependencies and databases.
Websites built with Hugo are extremely fast, secure and can be deployed anywhere including, AWS, GitHub Pages, Heroku, Netlify and any other hosting provider.
Learn more and contribute on [GitHub](https://github.com/gohugoio).

View file

@ -0,0 +1,17 @@
---
title: "What Is Hugo"
date: 2022-05-16T21:57:50+08:00
tags: []
categories: []
draft: false
---
Hugo is a static site generator written in Go. Originally created by Steve Francia in 2013, Hugo has seen a great increase in both features and performance thanks to current lead developer Bjørn Erik Pedersen (since v0.14 in 2015[4]) and other contributors. Hugo is an open source project licensed under the Apache License 2.0.[5]
<!--more-->
Being able to generate most websites within seconds (at < 1 ms per page), Hugo's official website states it is "the worlds fastest framework for building websites". In July 2015, Netlify began providing Hugo hosting,[6] and in 2017, Smashing Magazine completed its redesign of their website, migrating from WordPress to a JAMstack solution with Hugo.[7]
> Source: https://en.wikipedia.org/wiki/Hugo_(software)
>
> License: [CC-BY-SA 3.0](https://en.wikipedia.org/wiki/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License)

View file

@ -0,0 +1,12 @@
---
title: "Essays"
date: 2022-05-18T11:19:08+08:00
tags: []
categories: []
weight: 70
draft: false
---
<!--more-->
*There are some short articles.*

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

View file

@ -0,0 +1,38 @@
---
title: "Add Picture In Blog"
date: 2023-01-24T20:04:07+08:00
tags: []
categories: []
weight: 50
show_comments: true
katex: false
draft: false
---
In this essay, we will talk about how to add a picture in blog.
<!--more-->
There are many ways to add a picture, the one to use pure markdown syntax is `![](./path/to/picture)`.
Now I will show you a BIG picture (3600x2180):
![Big picture](./TEIDE.JPG)
And a small picture (30x20):
![Small markdown mark](./markdown-30x20.png)
Here is a inline markdown mark ![Small markdown mark](./markdown-30x20.png).
## Some other things
**Note** that due to the *big picture* is from [Wikipedia][wikipedia] who use [CC-BY-SA 3.0][cc-by-sa-3] as license, so this essay also use [CC-BY-SA 3.0] as license.
The *big picture* is from <https://en.wikipedia.org/wiki/Image>.
The small markdown mark has been dedicated to the public domain.
[wikipedia]: https://wikipedia.org/ "Wikipedia"
[cc-by-sa-3]: https://en.wikipedia.org/wiki/Wikipedia:Text_of_the_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License "Creative Commons Attribution-ShareAlike License 3.0"

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

View file

@ -0,0 +1,10 @@
---
title: "Posts"
date: 2022-05-18T11:22:44+08:00
tags: []
categories: []
weight: 30
draft: false
---
<!--more-->

View file

@ -0,0 +1,47 @@
+++
author = "Hugo Authors"
title = "Emoji Support"
date = "2019-03-05"
description = "Guide to emoji usage in Hugo"
tags = [
"emoji",
]
+++
Emoji can be enabled in a Hugo project in a number of ways.
<!--more-->
The [`emojify`](https://gohugo.io/functions/emojify/) function can be called directly in templates or [Inline Shortcodes](https://gohugo.io/templates/shortcode-templates/#inline-shortcodes).
To enable emoji globally, set `enableEmoji` to `true` in your site's [configuration](https://gohugo.io/getting-started/configuration/) and then you can type emoji shorthand codes directly in content files; e.g.
<p><span class="nowrap"><span class="emojify">🙈</span> <code>:see_no_evil:</code></span> <span class="nowrap"><span class="emojify">🙉</span> <code>:hear_no_evil:</code></span> <span class="nowrap"><span class="emojify">🙊</span> <code>:speak_no_evil:</code></span></p>
<br>
The [Emoji cheat sheet](http://www.emoji-cheat-sheet.com/) is a useful reference for emoji shorthand codes.
***
**N.B.** The above steps enable Unicode Standard emoji characters and sequences in Hugo, however the rendering of these glyphs depends on the browser and the platform. To style the emoji you can either use a third party emoji font or a font stack; e.g.
{{< highlight html >}}
.emoji {
font-family: Apple Color Emoji, Segoe UI Emoji, NotoColorEmoji, Segoe UI Symbol, Android Emoji, EmojiSymbols;
}
{{< /highlight >}}
{{< css.inline >}}
<style>
.emojify {
font-family: Apple Color Emoji, Segoe UI Emoji, NotoColorEmoji, Segoe UI Symbol, Android Emoji, EmojiSymbols;
font-size: 2rem;
vertical-align: middle;
}
@media screen and (max-width:650px) {
.nowrap {
display: block;
margin: 25px 0;
}
}
</style>
{{< /css.inline >}}

View file

@ -0,0 +1,30 @@
---
title: "Latex Support"
date: 2022-09-20T09:36:26+08:00
tags: []
categories: []
weight: 50
show_comments: true
katex: true
draft: false
---
This article contians some test for latex support.
Currently the lib used for rendering LaTeX is [\\(\KaTeX\\)](https://katex.org/)
<!--more-->
$$
\pi=\int_{-\infty}^\infty\frac{dx}{1+x^2}
$$
## The code which render the above
```
This article contians some test for latex support.
Currently the lib used for rendering LaTeX is [\\(\KaTeX\\)](https://katex.org/)
$$
\pi=\int_{-\infty}^\infty\frac{dx}{1+x^2}
$$
```

View file

@ -0,0 +1,148 @@
+++
author = "Hugo Authors"
title = "Markdown Syntax Guide"
date = "2019-03-11"
description = "Sample article showcasing basic Markdown syntax and formatting for HTML elements."
tags = [
"markdown",
"css",
"html",
]
categories = [
"themes",
"syntax",
]
series = ["Themes Guide"]
aliases = ["migrate-from-jekyl"]
+++
This article offers a sample of basic Markdown syntax that can be used in Hugo content files, also it shows whether basic HTML elements are decorated with CSS in a Hugo theme.
<!--more-->
## Headings
The following HTML `<h1>`—`<h6>` elements represent six levels of section headings. `<h1>` is the highest section level while `<h6>` is the lowest.
# H1
## H2
### H3
#### H4
##### H5
###### H6
## Paragraph
Xerum, quo qui aut unt expliquam qui dolut labo. Aque venitatiusda cum, voluptionse latur sitiae dolessi aut parist aut dollo enim qui voluptate ma dolestendit peritin re plis aut quas inctum laceat est volestemque commosa as cus endigna tectur, offic to cor sequas etum rerum idem sintibus eiur? Quianimin porecus evelectur, cum que nis nust voloribus ratem aut omnimi, sitatur? Quiatem. Nam, omnis sum am facea corem alique molestrunt et eos evelece arcillit ut aut eos eos nus, sin conecerem erum fuga. Ri oditatquam, ad quibus unda veliamenimin cusam et facea ipsamus es exerum sitate dolores editium rerore eost, temped molorro ratiae volorro te reribus dolorer sperchicium faceata tiustia prat.
Itatur? Quiatae cullecum rem ent aut odis in re eossequodi nonsequ idebis ne sapicia is sinveli squiatum, core et que aut hariosam ex eat.
## Blockquotes
The blockquote element represents content that is quoted from another source, optionally with a citation which must be within a `footer` or `cite` element, and optionally with in-line changes such as annotations and abbreviations.
#### Blockquote without attribution
> Tiam, ad mint andaepu dandae nostion secatur sequo quae.
> **Note** that you can use *Markdown syntax* within a blockquote.
#### Blockquote with attribution
> Don't communicate by sharing memory, share memory by communicating.<br>
> — <cite>Rob Pike[^1]</cite>
[^1]: The above quote is excerpted from Rob Pike's [talk](https://www.youtube.com/watch?v=PAAkCSZUG1c) during Gopherfest, November 18, 2015.
## Tables
Tables aren't part of the core Markdown spec, but Hugo supports supports them out-of-the-box.
Name | Age
--------|------
Bob | 27
Alice | 23
#### Inline Markdown within tables
| Italics | Bold | Code |
| -------- | -------- | ------ |
| *italics* | **bold** | `code` |
## Code Blocks
#### Code block with backticks
```html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Example HTML5 Document</title>
</head>
<body>
<p>Test</p>
</body>
</html>
```
#### Code block indented with four spaces
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Example HTML5 Document</title>
</head>
<body>
<p>Test</p>
</body>
</html>
#### Code block with Hugo's internal highlight shortcode
{{< highlight html >}}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Example HTML5 Document</title>
</head>
<body>
<p>Test</p>
</body>
</html>
{{< /highlight >}}
## List Types
#### Ordered List
1. First item
2. Second item
3. Third item
#### Unordered List
* List item
* Another item
* And another item
#### Nested list
* Fruit
* Apple
* Orange
* Banana
* Dairy
* Milk
* Cheese
## Other Elements — abbr, sub, sup, kbd, mark
<abbr title="Graphics Interchange Format">GIF</abbr> is a bitmap image format.
H<sub>2</sub>O
X<sup>n</sup> + Y<sup>n</sup> = Z<sup>n</sup>
Press <kbd><kbd>CTRL</kbd>+<kbd>ALT</kbd>+<kbd>Delete</kbd></kbd> to end the session.
Most <mark>salamanders</mark> are nocturnal, and hunt for insects, worms, and other small creatures.

View file

@ -0,0 +1,49 @@
---
author: Hugo Authors
title: Math Typesetting
date: 2019-03-08
description: A brief guide to setup KaTeX
math: true
---
Mathematical notation in a Hugo project can be enabled by using third party JavaScript libraries.
<!--more-->
In this example we will be using [KaTeX](https://katex.org/)
- Create a partial under `/layouts/partials/math.html`
- Within this partial reference the [Auto-render Extension](https://katex.org/docs/autorender.html) or host these scripts locally.
- Include the partial in your templates like so:
```bash
{{ if or .Params.math .Site.Params.math }}
{{ partial "math.html" . }}
{{ end }}
```
- To enable KaTex globally set the parameter `math` to `true` in a project's configuration
- To enable KaTex on a per page basis include the parameter `math: true` in content files
**Note:** Use the online reference of [Supported TeX Functions](https://katex.org/docs/supported.html)
{{< math.inline >}}
{{ if or .Page.Params.math .Site.Params.math }}
<!-- KaTeX -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.css" integrity="sha384-zB1R0rpPzHqg7Kpt0Aljp8JPLqbXI3bhnPWROx27a9N0Ll6ZP/+DiW/UqRcLbRjq" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.js" integrity="sha384-y23I5Q6l+B6vatafAwxRu/0oK/79VlbSz7Q9aiSZUvyWYIYsd+qj+o24G5ZU2zJz" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/contrib/auto-render.min.js" integrity="sha384-kWPLUVMOks5AQFrykwIup5lo0m3iMkkHrD0uJ4H5cjeGihAutqP0yW0J6dpFiVkI" crossorigin="anonymous" onload="renderMathInElement(document.body);"></script>
{{ end }}
{{</ math.inline >}}
### Examples
{{< math.inline >}}
<p>
Inline math: \(\varphi = \dfrac{1+\sqrt5}{2}= 1.6180339887…\)
</p>
{{</ math.inline >}}
Block math:
$$
\varphi = 1+\frac{1} {1+\frac{1} {1+\frac{1} {1+\cdots} } }
$$

View file

@ -0,0 +1,45 @@
+++
author = "Hugo Authors"
title = "Placeholder Text"
date = "2019-03-09"
description = "Lorem Ipsum Dolor Si Amet"
tags = [
"markdown",
"text",
]
+++
Lorem est tota propiore conpellat pectoribus de pectora summo. <!--more-->Redit teque digerit hominumque toris verebor lumina non cervice subde tollit usus habet Arctonque, furores quas nec ferunt. Quoque montibus nunc caluere tempus inhospita parcite confusaque translucet patri vestro qui optatis lumine cognoscere flos nubis! Fronde ipsamque patulos Dryopen deorum.
1. Exierant elisi ambit vivere dedere
2. Duce pollice
3. Eris modo
4. Spargitque ferrea quos palude
Rursus nulli murmur; hastile inridet ut ab gravi sententia! Nomine potitus silentia flumen, sustinet placuit petis in dilapsa erat sunt. Atria tractus malis.
1. Comas hunc haec pietate fetum procerum dixit
2. Post torum vates letum Tiresia
3. Flumen querellas
4. Arcanaque montibus omnes
5. Quidem et
# Vagus elidunt
<svg class="canon" xmlns="http://www.w3.org/2000/svg" overflow="visible" viewBox="0 0 496 373" height="373" width="496"><g fill="none"><path stroke="#000" stroke-width=".75" d="M.599 372.348L495.263 1.206M.312.633l494.95 370.853M.312 372.633L247.643.92M248.502.92l246.76 370.566M330.828 123.869V1.134M330.396 1.134L165.104 124.515"></path><path stroke="#ED1C24" stroke-width=".75" d="M275.73 41.616h166.224v249.05H275.73zM54.478 41.616h166.225v249.052H54.478z"></path><path stroke="#000" stroke-width=".75" d="M.479.375h495v372h-495zM247.979.875v372"></path><ellipse cx="498.729" cy="177.625" rx=".75" ry="1.25"></ellipse><ellipse cx="247.229" cy="377.375" rx=".75" ry="1.25"></ellipse></g></svg>
[The Van de Graaf Canon](https://en.wikipedia.org/wiki/Canons_of_page_construction#Van_de_Graaf_canon)
## Mane refeci capiebant unda mulcebat
Victa caducifer, malo vulnere contra dicere aurato, ludit regale, voca! Retorsit colit est profanae esse virescere furit nec; iaculi matertera et visa est, viribus. Divesque creatis, tecta novat collumque vulnus est, parvas. **Faces illo pepulere** tempus adest. Tendit flamma, ab opes virum sustinet, sidus sequendo urbis.
Iubar proles corpore raptos vero auctor imperium; sed et huic: manus caeli Lelegas tu lux. Verbis obstitit intus oblectamina fixis linguisque ausus sperare Echionides cornuaque tenent clausit possit. Omnia putatur. Praeteritae refert ausus; ferebant e primus lora nutat, vici quae mea ipse. Et iter nil spectatae vulnus haerentia iuste et exercebat, sui et.
Eurytus Hector, materna ipsumque ut Politen, nec, nate, ignari, vernum cohaesit sequitur. Vel **mitis temploque** vocatus, inque alis, *oculos nomen* non silvis corpore coniunx ne displicet illa. Crescunt non unus, vidit visa quantum inmiti flumina mortis facto sic: undique a alios vincula sunt iactata abdita! Suspenderat ego fuit tendit: luna, ante urbem Propoetides **parte**.
{{< css.inline >}}
<style>
.canon { background: white; width: 100%; height: auto; }
</style>
{{< /css.inline >}}

View file

@ -0,0 +1,35 @@
+++
author = "Hugo Authors"
title = "Rich Content"
date = "2019-03-10"
description = "A brief description of Hugo Shortcodes"
tags = [
"shortcodes",
"privacy",
]
draft = true
+++
Hugo ships with several [Built-in Shortcodes](https://gohugo.io/content-management/shortcodes/#use-hugos-built-in-shortcodes) for rich content, along with a [Privacy Config](https://gohugo.io/about/hugo-and-gdpr/) and a set of Simple Shortcodes that enable static and no-JS versions of various social media embeds.
<!--more-->
---
## YouTube Privacy Enhanced Shortcode
{{< youtube ZJthWmvUzzc >}}
<br>
---
## Twitter Simple Shortcode
{{< twitter_simple 1085870671291310081 >}}
<br>
---
## Vimeo Simple Shortcode
{{< vimeo_simple 48912912 >}}

View file

@ -0,0 +1,84 @@
+++
author = "Test"
title = "Code Content"
date = "2021-03-10"
description = "A brief description of Hugo Shortcodes"
tags = [
"shortcodes",
"privacy",
]
draft = true
+++
## t1
aaaa
Test [aaa](http://example.com) text.
### t1.1
aaaa
### t1.2
aaaa
#### t1.2.1
aaaa
#### t1.2.2
aaaa
## t2
aaaa
## t3
1. One<br><br>
/```
testing
some
code
/```
2. Two<br><br>
3. Three<br><br>
超宽显示 `var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";var a = "text";` 超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示超宽显示 `var a = "text";`
```
2021-08-02 17:51:23.718 ERROR org.apache.flink.runtime.entrypoint.ClusterEntrypoint [] - Fatal error occurred in the cluster entrypoint.
org.apache.flink.util.FlinkException: Application failed unexpectedly.
at org.apache.flink.client.deployment.application.ApplicationDispatcherBootstrap.lambda$runApplicationAndShutdownClusterAsync$0(ApplicationDispatcherBootstrap.java:170) ~[flink-dist_2.12-1.13.1.jar:1.13.1]
at java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:836) ~[?:1.8.0_292]
at java.util.concurrent.CompletableFuture$UniHandle.tryFire(CompletableFuture.java:811) ~[?:1.8.0_292]
at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:488) ~[?:1.8.0_292]
at java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:1990) ~[?:1.8.0_292]
at org.apache.flink.client.deployment.application.ApplicationDispatcherBootstrap.runApplicationEntryPoint(ApplicationDispatcherBootstrap.java:257) ~[flink-dist_2.12-1.13.1.jar:1.13.1]
at org.apache.flink.client.deployment.application.ApplicationDispatcherBootstrap.lambda$runApplicationAsync$1(ApplicationDispatcherBootstrap.java:212) ~[flink-dist_2.12-1.13.1.jar:1.13.1]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_292]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_292]
at org.apache.flink.runtime.concurrent.akka.ActorSystemScheduledExecutorAdapter$ScheduledFutureTask.run(ActorSystemScheduledExecutorAdapter.java:159) [flink-dist_2.12-1.13.1.jar:1.13.1]
at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:40) [flink-dist_2.12-1.13.1.jar:1.13.1]
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(ForkJoinExecutorConfigurator.scala:44) [flink-dist_2.12-1.13.1.jar:1.13.1]
at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) [flink-dist_2.12-1.13.1.jar:1.13.1]
at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) [flink-dist_2.12-1.13.1.jar:1.13.1]
at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) [flink-dist_2.12-1.13.1.jar:1.13.1]
```
```
test
test
test
```

BIN
images/screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 KiB

BIN
images/tn.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

View file

@ -0,0 +1,4 @@
<div class="mermaid">
{{- .Inner | safeHTML }}
</div>
{{ .Page.Store.Set "hasMermaid" true }}

View file

@ -0,0 +1 @@
<h{{ .Level }} id="{{ .Anchor | safeURL }}">{{ .Text | safeHTML }} <a href="#{{ .Anchor | safeURL }}" class="anchor">🔗</a></h{{ .Level }}>

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
{{ partial "head.html" . }}
</head>
<body>
{{ partial "header.html" . }}
<main class="main-wrapper">
<div class="main">
{{ block "main" . }}{{ end }}
</div>
<div class="side">
{{ range .Site.Sections }}
{{ partial "side-recent.html" . }}
{{ end }}
{{ partial "side-categories.html" . }}
{{ partial "side-tags.html" . }}
</div>
</main>
{{ partial "footer.html" . }}
</body>
</html>

View file

@ -0,0 +1,39 @@
{{ define "main" }}
<div>
{{ if trim .Content " \n" }}
<div class="content archive-hint">{{ .Content }}</div>
{{ end }}
<section id="archive">
{{ range .Data.Pages.GroupByDate "2006" }}
<div class="group">
<h3 class="key">
{{ .Key }}
</h3>
{{ range .Pages }}
<div class="value">
<time class="date" datetime="{{ .PublishDate }}">{{ .PublishDate.Format "01/02" }}</time>
<div class="title">
<a href="{{ .Permalink }}">{{ .Title }}</a>
{{ with .Params.tags }}
{{ range . }}
<a class="tags" href="{{ "tags/" | relURL }}{{ . | urlize }}">{{ . }}</a>
{{ end }}
{{ end }}
</div>
</div>
{{ end }}
</div>
{{ end }}
</section>
</div>
{{ end }}

45
layouts/_default/rss.xml Normal file
View file

@ -0,0 +1,45 @@
{{- $pctx := . -}}
{{- if .IsHome -}}{{ $pctx = .Site }}{{- end -}}
{{- $pages := slice -}}
{{- if or $.IsHome -}}
{{/* remove page at top level from RSS, for exmaple "about" page */}}
{{- $pages = where $pctx.RegularPages "Type" "ne" "page" -}}
{{- else if $.IsSection -}}
{{- $pages = $pctx.RegularPages -}}
{{- else -}}
{{- $pages = $pctx.Pages -}}
{{- end -}}
{{- $limit := .Site.Config.Services.RSS.Limit -}}
{{- if ge $limit 1 -}}
{{- $pages = $pages | first $limit -}}
{{- end -}}
{{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>{{ if eq .Title .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}{{ end }}</title>
<link>{{ .Permalink }}</link>
<description>Recent content {{ if ne .Title .Site.Title }}{{ with .Title }}in {{.}} {{ end }}{{ end }}on {{ .Site.Title }}</description>
<generator>Hugo -- gohugo.io</generator>{{ with .Site.LanguageCode }}
<language>{{.}}</language>{{end}}{{ with .Site.Author.email }}
<managingEditor>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</managingEditor>{{end}}{{ with .Site.Author.email }}
<webMaster>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</webMaster>{{end}}{{ with .Site.Copyright }}
<copyright>{{.}}</copyright>{{end}}{{ if not .Date.IsZero }}
<lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>{{ end }}
{{- with .OutputFormats.Get "RSS" -}}
{{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
{{- end -}}
{{ range $pages }}
<item>
<title>{{ .Title }}</title>
<link>{{ .Permalink }}</link>
<pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
{{ with .Site.Author.email }}<author>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</author>{{end}}
<guid>{{ .Permalink }}</guid>
<description>{{ .Content | html }}</description>
</item>
{{ end }}
</channel>
</rss>

View file

@ -0,0 +1,48 @@
{{ define "main" }}
<section class="single">
<h1 class="title">{{ .Title }}</h1>
<div class="tip">
<time datetime="{{ .PublishDate }}">{{ .PublishDate.Format "2006/01/02" }}</time>
<span class="split">·</span>
<span> {{ .WordCount }} words </span>
<span class="split">·</span>
<span>
{{ .ReadingTime }} minutes to read
</span>
</div>
<div class="taxonomies">
{{ with .Params.categories }}
<div>
Categories:
{{ range . }}
<a href="{{ "categories/" | relURL }}{{ . | urlize }}">{{ . }}</a>
{{ end }}
</div>
{{ end }}
{{ with .Params.tags }}
<div>
Tags:
{{ range . }}
<a href="{{ "tags/" | relURL }}{{ . | urlize }}">{{ . }}</a>
{{ end }}
</div>
{{ end }}
</div>
<hr />
<div class="content">
{{ .Content }}
</div>
{{ with and .Site.Params.remark42 .Params.show_comments }}
<hr />
{{ partial "comment.html" . }}
{{ end }}
</section>
{{ end }}

View file

@ -0,0 +1,14 @@
{{ define "main" }}
<section id="tags">
{{ $data := .Data }}
{{ range $key, $value := .Data.Terms.ByCount }}
{{ if $value.Name}}
<span class="tag">
<a href="{{ $value.Name | urlize }}">
{{ $value.Name }} <span>({{ $value.Count }})</span>
</a>
</span>
{{ end }}
{{ end }}
</section>
{{ end }}

View file

@ -0,0 +1,39 @@
{{ define "main" }}
<div>
{{ if trim .Content " \n" }}
<div class="content archive-hint">{{ .Content }}</div>
{{ end }}
<section id="archive">
{{ range .Data.Pages.GroupByDate "2006" }}
<div class="group">
<h3 class="key">
{{ .Key }}
</h3>
{{ range .Pages }}
<div class="value">
<time class="date" datetime="{{ .PublishDate }}">{{ .PublishDate.Format "01/02" }}</time>
<div class="title">
<a href="{{ .Permalink }}">{{ .Title }}</a>
{{ with .Params.tags }}
{{ range . }}
<a class="tags" href="{{ "tags/" | relURL }}{{ . | urlize }}">{{ . }}</a>
{{ end }}
{{ end }}
</div>
</div>
{{ end }}
</div>
{{ end }}
</section>
</div>
{{ end }}

48
layouts/index.html Normal file
View file

@ -0,0 +1,48 @@
{{ define "main" }}
<div class="max-wrapper">
<div id="list-page">
{{ $pages := where .Site.RegularPages "Type" "in" .Site.Params.mainSections }}
{{ $paginator := .Paginate $pages }}
{{ range $paginator.Pages }}
<section class="list-item">
<h1 class="title"><a href="{{ .RelPermalink }}">{{ .Title }}</a></h1>
<div class="tips">
<div class="date">
<time datetime="{{ .PublishDate }}">{{ .PublishDate.Format "2006/01/02" }}</time>
</div>
{{ with .Params.Categories }}
<div class="categories">
<span>Categories:</span>
{{ range first 2 . }}
<a href="{{ "categories/" | relURL }}{{ . | urlize }}">{{ . }}</a>
{{ end }}
</div>
{{ end }}
{{ with .Params.Tags }}
<div class="tags">
<span>Tags:</span>
{{ range first 5 . }}
<a href="{{ "tags/" | relURL }}{{ . | urlize }}">{{ . }}</a>
{{ end }}
</div>
{{ end }}
</div>
<div class="summary">
{{ with .Description }}
{{ . }}
{{ else }}
{{ .Summary }}
{{ end }}
</div>
</section>
{{ end }}
</div>
{{ partial "pagination.html" . }}
</div>
{{ end }}

View file

@ -0,0 +1 @@
<div class="commenting" id="remark42"></div>

View file

@ -0,0 +1,35 @@
<footer class="footer">
<div class="footer-row">
{{ range .Site.Sections }}
{{ $section := . }}
{{ with .OutputFormats.Get "rss" }}
<a class="footer-item" href="{{ .Permalink }}">
Feed of {{ $section.Section | humanize }}
<i class="icofont-rss"></i>
</a>
{{ end }}
{{ end }}
{{ if not (or .IsHome .IsSection) }}
{{ $term := . }}
{{ with .OutputFormats.Get "rss" }}
<a class="footer-item" href="{{ .Permalink }}">
Feed of "{{ $term.Title }}"
<i class="icofont-rss"></i>
</a>
{{ end }}
{{ end }}
</div>
{{ range .Site.Params.footer_rows }}
<div class="footer-row">
{{ range .items }}
{{ with .pre }}
<span class="footer-item">{{ . | safeHTML }}</span>
{{ else }}
<a class="footer-item" href="{{ .url }}">{{ .name }}</a>
{{ end }}
{{ end }}
</div>
{{ end }}
</footer>

View file

@ -0,0 +1,80 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,minimum-scale=1">
{{ $title := .Site.Title -}}
{{ if .Params.Title -}}
{{ $title = printf "%s | %s" .Params.Title $title -}}
{{ end -}}
{{ $description := "" -}}
{{ if .IsHome -}}
{{ with .Site.Params.description }}{{ $description = . }}{{ end -}}
{{ else if .IsPage -}}
{{ if .Description -}}
{{ $description = .Description -}}
{{ else -}}
{{ $description = .Summary -}}
{{ end -}}
{{ end }}
<title>{{ $title }}</title>
<link rel="canonical" href="{{ .Permalink }}">
{{ if $description -}}
<meta name="description" content="{{ $description }}" />
{{ end -}}
<meta property="og:type" content="article" />
<meta property="og:title" content="{{ $title }}" />
<meta property="og:url" content="{{ .Permalink }}" />
{{ if $description -}}
<meta property="og:description" content="{{ $description }}" />
{{ end -}}
{{ range .AlternativeOutputFormats -}}
{{ printf `<link rel="%s" type="%s" href="%s" title="%s" />` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }}
{{ end -}}
{{/* load mermaid if any mermaid code block */}}
{{ if .Page.Store.Get "hasMermaid" }}
<script src="{{ "js/meraid-9.0.0.min.js" | relURL }}"></script>
<script>mermaid.initialize({ startOnLoad: true });</script>
{{ end }}
{{/* load katex if enabled on front matter */}}
{{ if .Params.katex }}
<link rel="stylesheet" href="{{ "lib/katex/katex.min.css" | relURL }}">
<!-- The loading of KaTeX is deferred to speed up page rendering -->
<script defer src="{{ "lib/katex/katex.min.js" | relURL }}"></script>
<!-- To automatically render math in text elements, include the auto-render extension: -->
<script defer src="{{ "lib/katex/contrib/auto-render.min.js" | relURL }}"
onload="renderMathInElement(document.querySelector('body .single .content'));"></script>
{{ end }}
{{ with and .Site.Params.remark42 .Params.show_comments }}
{{ $remark42 := $.Site.Params.remark42 }}
<script>
var remark_config = {
host: '{{ $remark42.host }}',
site_id: '{{ $remark42.site_id }}',
components: ['embed', 'last-comments'],
max_shown_comments: {{ $remark42.max_shown_comments }},
theme: '{{ $remark42.theme }}',
page_title: '{{ $remark42.Title }}',
locale: '{{ $remark42.locale }}',
show_email_subscription: {{ $remark42.show_email_subscription }},
simple_view: {{ $remark42.simple_view }}
};
!function(e,n){for(var o=0;o<e.length;o++){var r=n.createElement("script"),c=".js",d=n.head||n.body;"noModule"in r?(r.type="module",c=".mjs"):r.async=!0,r.defer=!0,r.src=remark_config.host+"/web/"+e[o]+c,d.appendChild(r)}}(remark_config.components||["embed"],document);
</script>
{{ end }}
<link rel="stylesheet" href="{{ "lib/icofont/icofont.min.css" | relURL }}" />
<link rel="stylesheet" href="{{ "css/syntax.css" | relURL }}" />
<link rel="stylesheet" href="{{ "css/style.css" | relURL }}" />
<script src="{{ "js/copy-code-block.js" | relURL }}"></script>
<link rel="shortcut icon" href="{{ "images/favicon.ico" | relURL }}" type="image/x-icon" />

View file

@ -0,0 +1,22 @@
<header class="header-wrapper">
<div class="header">
<a class="site-title" href="{{ .Site.BaseURL }}">{{ .Site.Title }}</a>
<nav class="menu">
{{ range .Site.Menus.main }}
<div class="menu-item">
{{ if not .Children }}
<a href="{{ .URL }}">{{ .Name }}</a>
{{ else }}
<a>{{ .Name }}↓</a>
<nav class="sub-menu">
{{ range .Children }}
<div class="menu-item"><a href="{{ .URL }}">{{ .Name }}</a></div>
{{ end }}
</nav>
{{ end }}
</div>
{{ end }}
</nav>
</div>
</header>

View file

@ -0,0 +1,31 @@
{{ $pag := $.Paginator }}
<nav class="pagination">
{{ $size := 2 }}
{{ $current := $pag.PageNumber}}
{{ $total := $pag.TotalPages}}
{{ $prev := 0 }}
{{ range $pag.Pagers }}
{{ if or ( and ( ge .PageNumber (sub $current $size) )
( le .PageNumber (add $current $size) )
)
(or (eq .PageNumber 1)
(eq .PageNumber $total)
)
}}
{{ if not (eq .PageNumber (add $prev 1) ) }}
<span>··</span>
{{ end }}
{{ $prev = .PageNumber }}
{{ if eq .PageNumber $current }}
<a class="enabled current" href="{{ .URL }}">{{ .PageNumber }}</a>
{{ else }}
<a class="enabled" href="{{ .URL }}">{{ .PageNumber }}</a>
{{ end }}
{{ end }}
{{ end }}
</nav>

View file

@ -0,0 +1,12 @@
<div class="side-categories">
<h2>Categories</h2>
<hr />
<ul>
{{ range $key, $_ := .Site.Taxonomies.categories }}
<li>
<a href="{{ "categories/" | relURL }}{{ $key | urlize }}">{{ $key }}({{ .Count }})</a>
</li>
{{ end }}
</ul>
</div>

View file

@ -0,0 +1,14 @@
<div class="side-recent">
<h2 class="side-title">
<a href="{{ .RelPermalink }}">Recent {{ .Section | humanize }}</a>
</h2>
<hr />
<ul>
{{ range first 5 .RegularPages.ByDate.Reverse }}
<li>
<a href="{{ .RelPermalink }}">{{ .Title }}</a>
</li>
{{ end }}
</ul>
</div>

View file

@ -0,0 +1,12 @@
<div class="side-tags">
<h2>Tags</h2>
<hr />
<ul>
{{ range .Site.Taxonomies.tags.Alphabetical }}
<li>
<a href="{{ "tags/" | relURL }}{{ .Name | urlize }}">{{ .Name }} ({{ .Count }})</a>
</li>
{{ end }}
</ul>
</div>

4
layouts/robots.txt Normal file
View file

@ -0,0 +1,4 @@
User-agent: *
Allow: *
Sitemap: {{ .Site.BaseURL }}sitemap.xml

727
static/css/style.css Normal file
View file

@ -0,0 +1,727 @@
/* defines light color */
:root {
--color-light-bg-page: #EBEBEB;
--color-light-bg-content: #F4F4F4;
--color-light-bg-block: #EBEBEB;
--color-light-bg-shadow: #E0E0E0;
--color-light-fg-font-normal: #4E403E;
--color-light-fg-font-hover: #555555;
--color-light-fg-font-quote: #57606A;
--color-light-fg-tiny-line: #e0e0e0;
--color-light-fg-marker-quote: #BFBFBF;
--color-light-fg-font-hyper: #4E403E;
--color-light-fg-font-hyper-hover: #DE629E;
--color-light-fg-hyperlink: #DE629E;
--color-light-fg-hyperlink-hover: #CB3E50;
--color-light-bg-pager-normal: #D4D4D4;
--color-light-bg-pager-current: #E4E4E4;
--color-light-bg-pager-hover: #ECECEC;
}
/* defines dark color */
:root {
--color-dark-bg-page: #202124;
--color-dark-bg-content: #262628;
--color-dark-bg-block: #2B2B2B;
--color-dark-bg-shadow: #505050;
--color-dark-fg-font-normal: #C2C2B6;
--color-dark-fg-font-hover: #D2D2D3;
--color-dark-fg-font-quote: #8B8680;
--color-dark-fg-tiny-line: #3B3B3B;
--color-dark-fg-marker-quote: #6F6B66;
--color-dark-fg-font-hyper: #C2C2B6;
--color-dark-fg-font-hyper-hover: #DE629E;
--color-dark-fg-hyperlink: #DE629E;
--color-dark-fg-hyperlink-hover: #CB3E50;
--color-dark-bg-pager-normal: #303030;
--color-dark-bg-pager-current: #3A3A3E;
--color-dark-bg-pager-hover: #444446;
}
:root {
--color-bg-page: var(--color-light-bg-page);
--color-bg-content: var(--color-light-bg-content);
--color-bg-block: var(--color-light-bg-block);
--color-bg-shadow: var(--color-light-bg-shadow);
--color-fg-font-normal: var(--color-light-fg-font-normal);
--color-fg-font-hover: var(--color-light-fg-font-hover);
--color-fg-font-quote: var(--color-light-fg-font-quote);
--color-fg-tiny-line: var(--color-light-fg-tiny-line);
--color-fg-marker-quote: var(--color-light-fg-marker-quote);
--color-fg-font-hyper: var(--color-light-fg-font-hyper);
--color-fg-font-hyper-hover: var(--color-light-fg-font-hyper-hover);
--color-fg-hyperlink: var(--color-light-fg-hyperlink);
--color-fg-hyperlink-hover: var(--color-light-fg-hyperlink-hover);
--color-bg-pager-normal: var(--color-light-bg-pager-normal);
--color-bg-pager-current: var(--color-light-bg-pager-current);
--color-bg-pager-hover: var(--color-light-bg-pager-hover);
}
@media (prefers-color-scheme: dark) {
:root {
--color-bg-page: var(--color-dark-bg-page);
--color-bg-content: var(--color-dark-bg-content);
--color-bg-block: var(--color-dark-bg-block);
--color-bg-shadow: var(--color-dark-bg-shadow);
--color-fg-font-normal: var(--color-dark-fg-font-normal);
--color-fg-font-hover: var(--color-dark-fg-font-hover);
--color-fg-font-quote: var(--color-dark-fg-font-quote);
--color-fg-tiny-line: var(--color-dark-fg-tiny-line);
--color-fg-marker-quote: var(--color-dark-fg-marker-quote);
--color-fg-font-hyper: var(--color-dark-fg-font-hyper);
--color-fg-font-hyper-hover: var(--color-dark-fg-font-hyper-hover);
--color-fg-hyperlink: var(--color-dark-fg-hyperlink);
--color-fg-hyperlink-hover: var(--color-dark-fg-hyperlink-hover);
--color-bg-pager-normal: var(--color-dark-bg-pager-normal);
--color-bg-pager-current: var(--color-dark-bg-pager-current);
--color-bg-pager-hover: var(--color-dark-bg-pager-hover);
}
}
:root {
--fonts-sans-en: "Noto Sans", "Droid Sans", "Calibri", "Arial";
--fonts-sans-zh: "WenQuanYi Zen Hei", "WenQuanYi Micro Hei",
"Noto Sans CJK", "Microsoft YaHei", "PingFang SC";
--fonts-sans: var(--fonts-sans-en), var(--fonts-sans-zh), sans-serif;
--fonts-serif-en: "Noto Serif", "Times New Roman";
--fonts-serif-zh: "Noto Serif CJK", SimSun, STSong;
--fonts-serif: var(--fonts-serif-en), var(--fonts-serif-zh), serif;
--fonts-mono-en: "DejaVu Sans Mono", "Noto Sans Mono", "Consolas", "Courier";
--fonts-mono-zh: "Noto Sans Mono CJK", "WenQuanYi Zen Hei Mono", "WenQuanYi Micro Hei Mono";
--fonts-mono: var(--fonts-mono-en), var(--fonts-mono-zh), monospace;
--len-0: 0.00rem;
--len-1: 0.25rem;
--len-2: 0.50rem;
--len-3: 1.00rem;
--len-4: 1.50rem;
--len-5: 3.00rem;
--font-size-0: 0.8125rem;
--font-size-1: 0.875rem;
--font-size-2: 1.000rem;
--font-size-3: 1.125rem;
--font-size-4: 1.250rem;
--font-size-5: 1.500rem;
--font-size-6: 2.000rem;
}
*, ::before, ::after {
font-family: inherit;
box-sizing: border-box;
}
html {
font-family: var(--fonts-sans);
font-size: 16px;
color: var(--color-fg-font-normal);
}
/**************************************************************/
/* approximately set up the layout of header, footer and main */
/**************************************************************/
body {
display: flex;
flex-direction: column;
min-height: 100vh;
margin: 0;
align-items: center;
background-color: var(--color-bg-page);
}
/* set up padding and margin of some main elements */
.main-wrapper {
margin-top: var(--len-5);
margin-bottom: var(--len-5);
}
.main-wrapper { display: flex; flex-wrap: wrap; }
.main-wrapper > * { height: fit-content; }
.main { padding: var(--len-4); }
.side { padding-left: var(--len-4); }
.main { flex: 0 0 72%; width: 72%; }
.side { flex: 0 0 28%; width: 28%; }
/* mobile layout: place side to bottom */
@media (max-width: 991px) {
.main { padding: var(--len-4); }
.side { padding-left: 0; padding-top: var(--len-4); }
.main { flex: 0 0 100%; width: 100%; }
.side { flex: 0 0 100%; width: 100%; }
}
/* set light background */
.header-wrapper,
.footer,
.main,
.side-recent,
.side-categories,
.side-tags
{
background-color: var(--color-bg-content);
}
/* place header in the center of header-wrapper */
.header-wrapper {
display: flex;
justify-content: center;
}
/* let footer stay at bottom of screen */
.footer {
margin-top: auto;
margin-bottom: 0;
}
/********** set up break point **********/
.main-wrapper, .header { max-width: 1140px; }
@media (max-width: 1199px) { .main-wrapper, .header { max-width: 960px; } }
@media (max-width: 991px) { .main-wrapper, .header { max-width: 720px; } }
@media (max-width: 767px) { .main-wrapper, .header { max-width: 540px; } }
@media (max-width: 575px) { .main-wrapper, .header { max-width: none; } }
/* size the element who has breakpoint limitation */
/* .header, .main-wrapper, .main { width: 100vw; } */
/* .header-wrapper, .footer { width: 100vw; } */
.header-wrapper, .footer { width: 100vw;}
.main-wrapper { width: calc(100vw - 2 * var(--len-3));}
/************************/
/* set up header layout */
/************************/
.header {
padding: var(--len-3);
width: 100%;
}
/* place title and menus horizonally */
.header {
display: flex;
flex-wrap: wrap;
align-content: center;
justify-content: space-between;
}
.header .menu { justify-content: center; align-items: center; }
.header .site-title { text-align: center; }
@media (max-width: 767px) {
.header .site-title {
padding-top: var(--len-4);
flex: 0 0 100%;
}
.header .menu {
flex-wrap: wrap;
flex: 0 0 100%;
margin-top: var(--len-3);
padding-top: var(--len-3);
border-top: 1px solid var(--color-fg-tiny-line);
}
}
/* setup hyper link style */
.header .site-title {
text-decoration: none;
font-family: var(--fonts-serif);
font-size: var(--font-size-6);
font-weight: bold;
}
/********** set up menus layout **********/
/* menus and submenus, hover to display, and setup animation */
.header .menu-item .sub-menu { visibility: hidden; opacity: 0; transition: opacity 0.25s, visibility 0.25s; }
.header .menu-item:hover .sub-menu { visibility: visible; opacity: 1; }
.header .sub-menu { position: absolute; }
/* menu direction */
.header .menu {
display: flex;
align-items: center;
}
.header .sub-menu {
display: flex;
flex-direction: column;
align-items: flex-start;
}
/* set up spacing of menu items in menu and sub-menu */
.header .menu > * { margin-right: var(--len-3); }
.header .menu > *:last-child { margin-right: 0; }
.header .sub-menu > * { margin-bottom: var(--len-2); }
.header .sub-menu > *:last-child { margin-bottom: 0; }
/* beautify sub menu style */
.header .sub-menu {
background-color: var(--color-bg-content);
padding: var(--len-2) var(--len-4);
box-shadow: var(--color-bg-shadow) 0px 0px 3px 1px;
border-radius: 3px;
}
/* beautify menu item */
.header .menu-item {
font-family: var(--fonts-serif);
font-size: var(--font-size-3);
font-weight: bold;
}
.header a { color: var(--color-fg-font-normal); text-decoration: none; }
.header a:hover { color: var(--color-fg-font-hover); }
/************************/
/* set up footer layout */
/************************/
.footer {
padding: var(--len-4) 0;
font-size: var(--font-size-1);
}
.footer > * {
margin-top: var(--len-2);
margin-bottom: var(--len-2);
}
/* credit, license and social layout */
.footer .footer-row { display: flex; justify-content: center; }
.footer .footer-item { margin-right: var(--len-3); }
.footer .footer-item:last-child { margin-right: 0; }
/* beautify hyper link style */
.footer { color: var(--color-fg-font-normal) }
.footer a { color: var(--color-fg-hyperlink); text-decoration: none; }
.footer a:hover { color: var(--color-fg-hyperlink-hover); }
/**********************************/
/* set up home page's list layout */
/**********************************/
.list-item .tips {
display: flex;
flex-wrap: wrap;
justify-content: start;
align-items: flex-start;
font-size: var(--font-size-1);
color: var(--color-fg-font-quote);
}
.list-item .tips > * { margin-right: var(--len-3); }
.list-item .tips > *:last-child { margin-right: 0; }
.list-item .title a { text-decoration: none; color: var(--color-fg-font-normal); }
.list-item .title a:hover { color: var(--color-fg-font-hover); }
.list-item .tips a { text-decoration: none; color: var(--color-fg-hyperlink); }
.list-item .tips a:hover { color: var(--color-fg-hyperlink-hover); }
.list-item .title { margin: var(--len-2) 0 var(--len-3) 0; }
.list-item .tags > *,
.list-item .categories > *
{ margin: 0 var(--len-1); }
.list-item .summary > * { margin: 0; }
.list-item .title { margin: 0 0 var(--len-2) 0; }
.list-item .tips { margin: 0 0 var(--len-3) 0; }
.list-item { border-bottom: 1px solid var(--color-fg-tiny-line); }
.list-item:last-child { border-bottom: 0; }
.list-item:first-child { padding-top: 0;}
.list-item { padding: var(--len-3) 0; }
.list-item:last-child { padding-bottom: 0;}
/**********************/
/* set up side layout */
/**********************/
.side h2 { margin: 0; }
.side ul { list-style: none; margin: 0; padding: 0; }
.side li { margin-bottom: var(--len-3); }
.side li:last-child { margin-bottom: 0; }
.side hr {
border: none;
height: 1px;
background-color: var(--color-bg-content);
margin: var(--len-2) 0;
}
.side > * { padding: var(--len-4); }
.side > * { margin-bottom: var(--len-3); }
.side > *:last-child { margin-bottom: 0; }
.side a { color: var(--color-fg-font-normal); text-decoration: none; }
.side a:hover { color: var(--color-fg-hyperlink); }
/* horizontally place tags */
.side .side-tags li { display: inline-block; margin: var(--len-1) var(--len-1); }
/*****************************/
/* set up single post layout */
/*****************************/
.single {
display: flex;
flex-direction: column;
align-items: center;
}
.single a { text-decoration: none; color: var(--color-fg-hyperlink); }
.single a:hover { color: var(--color-fg-hyperlink-hover); }
.single .title,
.single .tip,
.single .taxonomies,
.single .content
{ width: 100%; }
.single .taxonomies { margin-top: var(--len-1); }
.single > hr {
border: none;
background-color: var(--color-fg-tiny-line);
height: 1px;
width: 90%;
margin: var(--len-3) 0;
}
.single .title,
.single .tip,
.single .taxonomies
{ text-align: center; }
.single .tip,
.single .taxonomies
{ color: var(--color-fg-font-normal)}
.single .taxonomies > * { display: inline-block; }
.single .taxonomies > * { margin-right: var(--len-3); }
.single .taxonomies > *:last-child { margin-right: 0; }
.single .title {
margin: var(--len-2) 0 var(--len-3) 0;
font-size: var(--font-size-6);
}
/***** set up content style *****/
.content {
line-height: 1.5;
}
.content code {
font-family: var(--fonts-mono);
background-color: var(--color-bg-block);
padding: 0 2px;
border: 1px solid var(--color-fg-tiny-line);
border-radius: 2px;
line-height: inherit;
word-wrap: break-word;
}
/* keep in style with highlighting */
.content pre {
background-color: var(--color-bg-block);
border-radius: 3px;
/* The copy button with absolute position need this.
* https://developer.mozilla.org/en-US/docs/Web/CSS/position
* https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
*/
position: relative;
}
.content pre code {
display: block;
padding: var(--len-3);
border: none;
background-color: unset;
overflow: auto;
width: 100%;
}
.content blockquote {
margin-top: 5px;
margin-bottom: 5px;
padding-left: 1em;
margin-left: 0px;
border-left: 3px solid var(--color-fg-marker-quote);
color: var(--color-fg-font-quote);
}
.content hr {
border: none;
height: 2px;
background-color: var(--color-fg-tiny-line);
width: 80%;
margin: var(--len-2) auto;
}
.content table {
width: 100%;
margin: 40px 0;
border-collapse: collapse;
line-height: 1.5em;
}
.content th,
.content td {
text-align: left;
padding-right: 20px;
vertical-align: top;
}
.content table td,
.content table td {
border-spacing: none;
border-style: solid;
padding: 10px 15px;
border-width: 1px 0 0 0;
}
.content thead th,
.content thead th {
text-align: left;
padding: 10px 15px;
height: 20px;
font-weight: bold;
color: #444;
cursor: default;
white-space: nowrap;
border: 1px solid #dadadc;
}
.content tr>td {
border: 1px solid #dadadc;
}
.content tr:nth-child(odd)>td {
background: #fcfcfc;
}
.content h1,
.content h2,
.content h3 {
font-weight: bold;
}
.content p,
.content pre {
word-break: normal;
overflow-wrap: anywhere;
}
.content img {
max-width: 92%;
display: block;
margin-left: auto;
margin-right: auto;
}
.content .anchor {
visibility: hidden;
}
.content h1:hover a,
.content h2:hover a,
.content h3:hover a,
.content h4:hover a
{ visibility: visible }
.highlight pre {
overflow-x: auto;
}
.highlight {
max-width: 100%;
overflow-x: auto;
}
/* the copy button added by /js/copy-code-button.js */
pre .copyCodeButton {
position: absolute;
top: var(--len-1);
right: var(--len-3);
font-family: var(--fonts-mono);
color: var(--color-fg-hyperlink);
cursor: pointer;
visibility: hidden;
}
pre:hover .copyCodeButton {
visibility: visible;
}
pre .copyCodeButton:hover {
color: var(--color-fg-hyperlink-hover);
}
/**************************/
/* setup list page layout */
/**************************/
#archive {
padding-left: var(--len-3);
}
#archive .group {
margin: var(--len-4) auto;
}
#archive .group .key {
font-size: var(--font-size-4);
margin-bottom: var(--len-2);
}
#archive .group .value {
display: block;
font-size: var(--font-size-2);
margin-bottom: 12px;
}
#archive .group .value { text-indent: -60px; padding-left: 60px; }
#archive .group .value * { text-indent: 0; }
#archive .group .value .date { display: inline-block; width: 60px; }
#archive .group .value .title { display: inline; }
#archive .group .value .date { color: var(--color-fg-font-normal); }
#archive .group .value a { text-decoration: none; }
#archive .group .value a { color: var(--color-fg-font-hyper); }
#archive .group .value a:hover { color: var(--color-fg-font-hyper-hover); }
#archive .group .value .tags {
display: inline-block;
margin-left: 7px;
}
#archive .group .value .tags {
background: var(--color-bg-block);
border-radius: 2px;
padding: 4px 7px;
font-size: var(--font-size-1);
margin-right: 3px;
}
/**********************/
/* setup terms layout */
/**********************/
#tags {
max-width: 700px;
margin: 48px auto 0 auto;
padding: 0 12px;
text-align: center;
}
#tags .tag {
display: inline-block;
margin: 7px 7px;
}
@media (max-width: 700px) {
#tags {
margin: 0 auto 0 auto;
}
#tags .tag {
display: inline-block;
margin: 4px 5px;
}
}
#tags .tag a {
background: #f2f2f2;
padding: 4px 7px;
color: #757575;
color: #404040;
font-size: 14px;
margin-right: 3px;
}
#tags .tag a:hover {
color: #0366d6;
}
/***************************/
/* setup pagination layout */
/***************************/
.pagination {
width: 100%;
text-align: center;
padding-top: var(--len-5);
}
.pagination a {
display: inline-block;
font-size: var(--font-size-2);
border-radius: var(--len-5);
width: var(--len-5);
height: var(--len-5);
line-height: var(--len-5);
text-align: center;
vertical-align: middle;
text-decoration: none;
color: var(--color-fg-font-normal);
background-color: var(--color-bg-pager-normal);
transition: background-color 0.25s;
}
.pagination a:hover {
background-color: var(--color-bg-pager-hover);
}
.pagination a.current {
background-color: var(--color-bg-pager-current);
pointer-events: none;
color: var(--color-fg-font-normal);
cursor: default;
}
/***************************/
/* setup commenting layout */
/***************************/
.commenting {
width: 85%;
}
/**********/
/** misc **/
/**********/
.archive-hint {
padding-left: var(--len-4);
color: var(--color-fg-font-quote);
}
.max-wrapper {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}

177
static/css/syntax.css Normal file
View file

@ -0,0 +1,177 @@
@media (prefers-color-scheme: light) {
/* Background */ .bg { color: #272822; }
/* PreWrapper */ .chroma { color: #272822; }
/* Other */ .chroma .x { }
/* Error */ .chroma .err { color: #960050; background-color: #1e0010 }
/* CodeLine */ .chroma .cl { }
/* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
/* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; }
/* LineHighlight */ .chroma .hl { background-color: #ffffcc }
/* LineNumbersTable */ .chroma .lnt { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
/* LineNumbers */ .chroma .ln { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
/* Line */ .chroma .line { display: flex; }
/* Keyword */ .chroma .k { color: #00a8c8 }
/* KeywordConstant */ .chroma .kc { color: #00a8c8 }
/* KeywordDeclaration */ .chroma .kd { color: #00a8c8 }
/* KeywordNamespace */ .chroma .kn { color: #f92672 }
/* KeywordPseudo */ .chroma .kp { color: #00a8c8 }
/* KeywordReserved */ .chroma .kr { color: #00a8c8 }
/* KeywordType */ .chroma .kt { color: #00a8c8 }
/* Name */ .chroma .n { color: #111111 }
/* NameAttribute */ .chroma .na { color: #75af00 }
/* NameBuiltin */ .chroma .nb { color: #111111 }
/* NameBuiltinPseudo */ .chroma .bp { color: #111111 }
/* NameClass */ .chroma .nc { color: #75af00 }
/* NameConstant */ .chroma .no { color: #00a8c8 }
/* NameDecorator */ .chroma .nd { color: #75af00 }
/* NameEntity */ .chroma .ni { color: #111111 }
/* NameException */ .chroma .ne { color: #75af00 }
/* NameFunction */ .chroma .nf { color: #75af00 }
/* NameFunctionMagic */ .chroma .fm { color: #111111 }
/* NameLabel */ .chroma .nl { color: #111111 }
/* NameNamespace */ .chroma .nn { color: #111111 }
/* NameOther */ .chroma .nx { color: #75af00 }
/* NameProperty */ .chroma .py { color: #111111 }
/* NameTag */ .chroma .nt { color: #f92672 }
/* NameVariable */ .chroma .nv { color: #111111 }
/* NameVariableClass */ .chroma .vc { color: #111111 }
/* NameVariableGlobal */ .chroma .vg { color: #111111 }
/* NameVariableInstance */ .chroma .vi { color: #111111 }
/* NameVariableMagic */ .chroma .vm { color: #111111 }
/* Literal */ .chroma .l { color: #ae81ff }
/* LiteralDate */ .chroma .ld { color: #d88200 }
/* LiteralString */ .chroma .s { color: #d88200 }
/* LiteralStringAffix */ .chroma .sa { color: #d88200 }
/* LiteralStringBacktick */ .chroma .sb { color: #d88200 }
/* LiteralStringChar */ .chroma .sc { color: #d88200 }
/* LiteralStringDelimiter */ .chroma .dl { color: #d88200 }
/* LiteralStringDoc */ .chroma .sd { color: #d88200 }
/* LiteralStringDouble */ .chroma .s2 { color: #d88200 }
/* LiteralStringEscape */ .chroma .se { color: #8045ff }
/* LiteralStringHeredoc */ .chroma .sh { color: #d88200 }
/* LiteralStringInterpol */ .chroma .si { color: #d88200 }
/* LiteralStringOther */ .chroma .sx { color: #d88200 }
/* LiteralStringRegex */ .chroma .sr { color: #d88200 }
/* LiteralStringSingle */ .chroma .s1 { color: #d88200 }
/* LiteralStringSymbol */ .chroma .ss { color: #d88200 }
/* LiteralNumber */ .chroma .m { color: #ae81ff }
/* LiteralNumberBin */ .chroma .mb { color: #ae81ff }
/* LiteralNumberFloat */ .chroma .mf { color: #ae81ff }
/* LiteralNumberHex */ .chroma .mh { color: #ae81ff }
/* LiteralNumberInteger */ .chroma .mi { color: #ae81ff }
/* LiteralNumberIntegerLong */ .chroma .il { color: #ae81ff }
/* LiteralNumberOct */ .chroma .mo { color: #ae81ff }
/* Operator */ .chroma .o { color: #f92672 }
/* OperatorWord */ .chroma .ow { color: #f92672 }
/* Punctuation */ .chroma .p { color: #111111 }
/* Comment */ .chroma .c { color: #75715e }
/* CommentHashbang */ .chroma .ch { color: #75715e }
/* CommentMultiline */ .chroma .cm { color: #75715e }
/* CommentSingle */ .chroma .c1 { color: #75715e }
/* CommentSpecial */ .chroma .cs { color: #75715e }
/* CommentPreproc */ .chroma .cp { color: #75715e }
/* CommentPreprocFile */ .chroma .cpf { color: #75715e }
/* Generic */ .chroma .g { }
/* GenericDeleted */ .chroma .gd { }
/* GenericEmph */ .chroma .ge { font-style: italic }
/* GenericError */ .chroma .gr { }
/* GenericHeading */ .chroma .gh { }
/* GenericInserted */ .chroma .gi { }
/* GenericOutput */ .chroma .go { }
/* GenericPrompt */ .chroma .gp { }
/* GenericStrong */ .chroma .gs { font-weight: bold }
/* GenericSubheading */ .chroma .gu { }
/* GenericTraceback */ .chroma .gt { }
/* GenericUnderline */ .chroma .gl { }
/* TextWhitespace */ .chroma .w { }
}
/* use monokai highlight theme in dark */
@media (prefers-color-scheme: dark) {
/* Background */ .bg { color: #f8f8f2; background-color: #272822; }
/* PreWrapper */ .chroma { color: #f8f8f2; background-color: #272822; }
/* Other */ .chroma .x { }
/* Error */ .chroma .err { color: #960050; background-color: #1e0010 }
/* CodeLine */ .chroma .cl { }
/* LineLink */ .chroma .lnlinks { outline: none; text-decoration: none; color: inherit }
/* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
/* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; }
/* LineHighlight */ .chroma .hl { background-color: #ffffcc }
/* LineNumbersTable */ .chroma .lnt { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
/* LineNumbers */ .chroma .ln { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
/* Line */ .chroma .line { display: flex; }
/* Keyword */ .chroma .k { color: #66d9ef }
/* KeywordConstant */ .chroma .kc { color: #66d9ef }
/* KeywordDeclaration */ .chroma .kd { color: #66d9ef }
/* KeywordNamespace */ .chroma .kn { color: #f92672 }
/* KeywordPseudo */ .chroma .kp { color: #66d9ef }
/* KeywordReserved */ .chroma .kr { color: #66d9ef }
/* KeywordType */ .chroma .kt { color: #66d9ef }
/* Name */ .chroma .n { }
/* NameAttribute */ .chroma .na { color: #a6e22e }
/* NameBuiltin */ .chroma .nb { }
/* NameBuiltinPseudo */ .chroma .bp { }
/* NameClass */ .chroma .nc { color: #a6e22e }
/* NameConstant */ .chroma .no { color: #66d9ef }
/* NameDecorator */ .chroma .nd { color: #a6e22e }
/* NameEntity */ .chroma .ni { }
/* NameException */ .chroma .ne { color: #a6e22e }
/* NameFunction */ .chroma .nf { color: #a6e22e }
/* NameFunctionMagic */ .chroma .fm { }
/* NameLabel */ .chroma .nl { }
/* NameNamespace */ .chroma .nn { }
/* NameOther */ .chroma .nx { color: #a6e22e }
/* NameProperty */ .chroma .py { }
/* NameTag */ .chroma .nt { color: #f92672 }
/* NameVariable */ .chroma .nv { }
/* NameVariableClass */ .chroma .vc { }
/* NameVariableGlobal */ .chroma .vg { }
/* NameVariableInstance */ .chroma .vi { }
/* NameVariableMagic */ .chroma .vm { }
/* Literal */ .chroma .l { color: #ae81ff }
/* LiteralDate */ .chroma .ld { color: #e6db74 }
/* LiteralString */ .chroma .s { color: #e6db74 }
/* LiteralStringAffix */ .chroma .sa { color: #e6db74 }
/* LiteralStringBacktick */ .chroma .sb { color: #e6db74 }
/* LiteralStringChar */ .chroma .sc { color: #e6db74 }
/* LiteralStringDelimiter */ .chroma .dl { color: #e6db74 }
/* LiteralStringDoc */ .chroma .sd { color: #e6db74 }
/* LiteralStringDouble */ .chroma .s2 { color: #e6db74 }
/* LiteralStringEscape */ .chroma .se { color: #ae81ff }
/* LiteralStringHeredoc */ .chroma .sh { color: #e6db74 }
/* LiteralStringInterpol */ .chroma .si { color: #e6db74 }
/* LiteralStringOther */ .chroma .sx { color: #e6db74 }
/* LiteralStringRegex */ .chroma .sr { color: #e6db74 }
/* LiteralStringSingle */ .chroma .s1 { color: #e6db74 }
/* LiteralStringSymbol */ .chroma .ss { color: #e6db74 }
/* LiteralNumber */ .chroma .m { color: #ae81ff }
/* LiteralNumberBin */ .chroma .mb { color: #ae81ff }
/* LiteralNumberFloat */ .chroma .mf { color: #ae81ff }
/* LiteralNumberHex */ .chroma .mh { color: #ae81ff }
/* LiteralNumberInteger */ .chroma .mi { color: #ae81ff }
/* LiteralNumberIntegerLong */ .chroma .il { color: #ae81ff }
/* LiteralNumberOct */ .chroma .mo { color: #ae81ff }
/* Operator */ .chroma .o { color: #f92672 }
/* OperatorWord */ .chroma .ow { color: #f92672 }
/* Punctuation */ .chroma .p { }
/* Comment */ .chroma .c { color: #75715e }
/* CommentHashbang */ .chroma .ch { color: #75715e }
/* CommentMultiline */ .chroma .cm { color: #75715e }
/* CommentSingle */ .chroma .c1 { color: #75715e }
/* CommentSpecial */ .chroma .cs { color: #75715e }
/* CommentPreproc */ .chroma .cp { color: #75715e }
/* CommentPreprocFile */ .chroma .cpf { color: #75715e }
/* Generic */ .chroma .g { }
/* GenericDeleted */ .chroma .gd { color: #f92672 }
/* GenericEmph */ .chroma .ge { font-style: italic }
/* GenericError */ .chroma .gr { }
/* GenericHeading */ .chroma .gh { }
/* GenericInserted */ .chroma .gi { color: #a6e22e }
/* GenericOutput */ .chroma .go { }
/* GenericPrompt */ .chroma .gp { }
/* GenericStrong */ .chroma .gs { font-weight: bold }
/* GenericSubheading */ .chroma .gu { color: #75715e }
/* GenericTraceback */ .chroma .gt { }
/* GenericUnderline */ .chroma .gl { }
/* TextWhitespace */ .chroma .w { }
}

View file

@ -0,0 +1,36 @@
/*
* Every codeblock has "pre > code" structure, some highlighted codeblocks have
* "div.highlight > pre.chroma > code" structure. So, use the simple CSS selector
* to query all codeblocks.
*/
document.addEventListener("DOMContentLoaded",
() => {
var codeblocks = document.querySelectorAll(".single .content pre code");
console.log("codeblocks length:", codeblocks.length);
codeblocks.forEach(
(codeblock) => {
let elementPre = codeblock.parentElement;
let button = document.createElement("div");
button.classList.add("copyCodeButton");
button.innerHTML = "copy";
button.addEventListener("click",
() => {
navigator.clipboard.writeText(codeblock.textContent);
button.innerHTML = "copied!";
setTimeout(
() => { button.innerHTML = "copy"; },
1000
);
}
);
elementPre.appendChild(button);
}
);
}
);

3
static/js/mermaid-9.0.0.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,96 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Examples | IcoFont</title>
<link rel="stylesheet" type="text/css" href="./icofont.min.css">
<style type="text/css">
body {
margin: 0;
padding: 0;
background: #F6F6F9;
}
.header {
border-bottom: 1px solid #DCDCE1;
padding: 10px 0;
margin-bottom: 10px;
}
.container {
width: 980px;
margin: 0 auto;
}
.ico-title {
font-size: 2em;
}
.iconlist {
margin: 0;
padding: 0;
list-style: none;
text-align: center;
width: 100%;
display: flex;
flex-wrap: wrap;
flex-direction: row;
}
.iconlist li {
position: relative;
margin: 5px;
width: 150px;
cursor: pointer;
}
.iconlist li .icon-holder {
position: relative;
text-align: center;
border-radius: 3px;
overflow: hidden;
padding-bottom: 5px;
background: #ffffff;
border: 1px solid #E4E5EA;
transition: all 0.2s linear 0s;
}
.iconlist li .icon-holder:hover {
background: #00C3DA;
color: #ffffff;
}
.iconlist li .icon-holder:hover .icon i {
color: #ffffff;
}
.iconlist li .icon-holder .icon {
padding: 20px;
text-align: center;
}
.iconlist li .icon-holder .icon i {
font-size: 3em;
color: #1F1142;
}
.iconlist li .icon-holder span {
font-size: 14px;
display: block;
margin-top: 5px;
border-radius: 3px;
}
</style>
</head>
<body>
<div class="header">
<div class="container">
<h1 class="ico-title"> IcoFont Icons </h1>
</div>
</div>
<div class="container">
<ul class="iconlist">
<li>
<div class="icon-holder">
<div class="icon">
<i class="icofont-rss"></i>
</div>
<span> rss </span>
</div>
</li>
</ul>
</div>
</body>
</html>

Binary file not shown.

View file

@ -0,0 +1,11 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<font id="icofont" horiz-adv-x="1000" >
<font-face font-family="IcoFont" font-weight="400" font-style="Regular" units-per-em="1000" ascent="850" descent="-150" />
<missing-glyph horiz-adv-x="1000" />
<glyph glyph-name="rss" horiz-adv-x="1000" unicode="&#xed64;" d="M64 323c109 0 212-43 288-120 77-78 120-181 120-290h168c0 318-258 577-576 577l0-167z m1 297c388 0 703-317 703-707h168c0 482-391 875-871 875l0-168z m232-590c0-65-52-117-117-117-64 0-116 52-116 117s52 116 116 116c65 0 117-52 117-116z" />
</font>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 707 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,287 @@
/*!
* @package IcoFont
* @version 1.0.1
* @author IcoFont https://icofont.com
* @copyright Copyright (c) 2015 - 2022 IcoFont
* @license - https://icofont.com/license/
*/
@font-face
{
font-family: "IcoFont";
font-weight: normal;
font-style: "Regular";
src: url("./fonts/icofont.woff2") format("woff2"),
url("./fonts/icofont.woff") format("woff");
}
[class^="icofont-"], [class*=" icofont-"]
{
font-family: 'IcoFont' !important;
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
white-space: nowrap;
word-wrap: normal;
direction: ltr;
line-height: 1;
/* Better Font Rendering =========== */
-webkit-font-feature-settings: "liga";
-webkit-font-smoothing: antialiased;
}
.icofont-rss:before
{
content: "\ed64";
}
.icofont-xs
{
font-size: .5em;
}
.icofont-sm
{
font-size: .75em;
}
.icofont-md
{
font-size: 1.25em;
}
.icofont-lg
{
font-size: 1.5em;
}
.icofont-1x
{
font-size: 1em;
}
.icofont-2x
{
font-size: 2em;
}
.icofont-3x
{
font-size: 3em;
}
.icofont-4x
{
font-size: 4em;
}
.icofont-5x
{
font-size: 5em;
}
.icofont-6x
{
font-size: 6em;
}
.icofont-7x
{
font-size: 7em;
}
.icofont-8x
{
font-size: 8em;
}
.icofont-9x
{
font-size: 9em;
}
.icofont-10x
{
font-size: 10em;
}
.icofont-fw
{
text-align: center;
width: 1.25em;
}
.icofont-ul
{
list-style-type: none;
padding-left: 0;
margin-left: 0;
}
.icofont-ul > li
{
position: relative;
line-height: 2em;
}
.icofont-ul > li .icofont
{
display: inline-block;
vertical-align: middle;
}
.icofont-border
{
border: solid 0.08em #f1f1f1;
border-radius: .1em;
padding: .2em .25em .15em;
}
.icofont-pull-left
{
float: left;
}
.icofont-pull-right
{
float: right;
}
.icofont.icofont-pull-left
{
margin-right: .3em;
}
.icofont.icofont-pull-right
{
margin-left: .3em;
}
.icofont-spin
{
-webkit-animation: icofont-spin 2s infinite linear;
animation: icofont-spin 2s infinite linear;
display: inline-block;
}
.icofont-pulse
{
-webkit-animation: icofont-spin 1s infinite steps(8);
animation: icofont-spin 1s infinite steps(8);
display: inline-block;
}
@-webkit-keyframes icofont-spin
{
0%
{
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100%
{
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes icofont-spin
{
0%
{
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100%
{
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
.icofont-rotate-90
{
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
}
.icofont-rotate-180
{
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";
-webkit-transform: rotate(180deg);
transform: rotate(180deg);
}
.icofont-rotate-270
{
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";
-webkit-transform: rotate(270deg);
transform: rotate(270deg);
}
.icofont-flip-horizontal
{
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";
-webkit-transform: scale(-1, 1);
transform: scale(-1, 1);
}
.icofont-flip-vertical
{
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
-webkit-transform: scale(1, -1);
transform: scale(1, -1);
}
.icofont-flip-horizontal.icofont-flip-vertical
{
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
-webkit-transform: scale(-1, -1);
transform: scale(-1, -1);
}
:root .icofont-rotate-90,
:root .icofont-rotate-180,
:root .icofont-rotate-270,
:root .icofont-flip-horizontal,
:root .icofont-flip-vertical
{
-webkit-filter: none;
filter: none;
display: inline-block;
}
.icofont-inverse
{
color: #fff;
}
.sr-only
{
border: 0;
clip: rect(0, 0, 0, 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
.sr-only-focusable:active,
.sr-only-focusable:focus
{
clip: auto;
height: auto;
margin: 0;
overflow: visible;
position: static;
width: auto;
}

7
static/lib/icofont/icofont.min.css vendored Normal file
View file

@ -0,0 +1,7 @@
/*!
* @package IcoFont
* @version 1.0.1
* @author IcoFont https://icofont.com
* @copyright Copyright (c) 2015 - 2022 IcoFont
* @license - https://icofont.com/license/
*/@font-face{font-family:IcoFont;font-weight:400;font-style:Regular;src:url(fonts/icofont.woff2) format("woff2"),url(fonts/icofont.woff) format("woff")}[class*=" icofont-"],[class^=icofont-]{font-family:IcoFont!important;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;white-space:nowrap;word-wrap:normal;direction:ltr;line-height:1;-webkit-font-feature-settings:"liga";-webkit-font-smoothing:antialiased}.icofont-rss:before{content:"\ed64"}.icofont-xs{font-size:.5em}.icofont-sm{font-size:.75em}.icofont-md{font-size:1.25em}.icofont-lg{font-size:1.5em}.icofont-1x{font-size:1em}.icofont-2x{font-size:2em}.icofont-3x{font-size:3em}.icofont-4x{font-size:4em}.icofont-5x{font-size:5em}.icofont-6x{font-size:6em}.icofont-7x{font-size:7em}.icofont-8x{font-size:8em}.icofont-9x{font-size:9em}.icofont-10x{font-size:10em}.icofont-fw{text-align:center;width:1.25em}.icofont-ul{list-style-type:none;padding-left:0;margin-left:0}.icofont-ul>li{position:relative;line-height:2em}.icofont-ul>li .icofont{display:inline-block;vertical-align:middle}.icofont-border{border:solid .08em #f1f1f1;border-radius:.1em;padding:.2em .25em .15em}.icofont-pull-left{float:left}.icofont-pull-right{float:right}.icofont.icofont-pull-left{margin-right:.3em}.icofont.icofont-pull-right{margin-left:.3em}.icofont-spin{-webkit-animation:icofont-spin 2s infinite linear;animation:icofont-spin 2s infinite linear;display:inline-block}.icofont-pulse{-webkit-animation:icofont-spin 1s infinite steps(8);animation:icofont-spin 1s infinite steps(8);display:inline-block}@-webkit-keyframes icofont-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes icofont-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.icofont-rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.icofont-rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.icofont-rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.icofont-flip-horizontal{-webkit-transform:scale(-1,1);transform:scale(-1,1)}.icofont-flip-vertical{-webkit-transform:scale(1,-1);transform:scale(1,-1)}.icofont-flip-horizontal.icofont-flip-vertical{-webkit-transform:scale(-1,-1);transform:scale(-1,-1)}:root .icofont-flip-horizontal,:root .icofont-flip-vertical,:root .icofont-rotate-180,:root .icofont-rotate-270,:root .icofont-rotate-90{-webkit-filter:none;filter:none;display:inline-block}.icofont-inverse{color:#fff}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}

119
static/lib/katex/README.md Normal file
View file

@ -0,0 +1,119 @@
# [<img src="https://katex.org/img/katex-logo-black.svg" width="130" alt="KaTeX">](https://katex.org/)
[![npm](https://img.shields.io/npm/v/katex.svg)](https://www.npmjs.com/package/katex)
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
[![CI](https://github.com/KaTeX/KaTeX/workflows/CI/badge.svg?branch=main&event=push)](https://github.com/KaTeX/KaTeX/actions?query=workflow%3ACI)
[![codecov](https://codecov.io/gh/KaTeX/KaTeX/branch/main/graph/badge.svg)](https://codecov.io/gh/KaTeX/KaTeX)
[![Discussions](https://img.shields.io/badge/Discussions-join-brightgreen)](https://github.com/KaTeX/KaTeX/discussions)
[![jsDelivr](https://data.jsdelivr.com/v1/package/npm/katex/badge?style=rounded)](https://www.jsdelivr.com/package/npm/katex)
![katex.min.js size](https://img.badgesize.io/https://unpkg.com/katex/dist/katex.min.js?compression=gzip)
[![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/KaTeX/KaTeX)
[![Financial Contributors on Open Collective](https://opencollective.com/katex/all/badge.svg?label=financial+contributors)](https://opencollective.com/katex)
KaTeX is a fast, easy-to-use JavaScript library for TeX math rendering on the web.
* **Fast:** KaTeX renders its math synchronously and doesn't need to reflow the page. See how it compares to a competitor in [this speed test](https://www.intmath.com/cg5/katex-mathjax-comparison.php).
* **Print quality:** KaTeX's layout is based on Donald Knuth's TeX, the gold standard for math typesetting.
* **Self contained:** KaTeX has no dependencies and can easily be bundled with your website resources.
* **Server side rendering:** KaTeX produces the same output regardless of browser or environment, so you can pre-render expressions using Node.js and send them as plain HTML.
KaTeX is compatible with all major browsers, including Chrome, Safari, Firefox, Opera, Edge, and IE 11.
KaTeX supports much (but not all) of LaTeX and many LaTeX packages. See the [list of supported functions](https://katex.org/docs/supported.html).
Try out KaTeX [on the demo page](https://katex.org/#demo)!
## Getting started
### Starter template
```html
<!DOCTYPE html>
<!-- KaTeX requires the use of the HTML5 doctype. Without it, KaTeX may not render properly -->
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.2/dist/katex.min.css" integrity="sha384-bYdxxUwYipFNohQlHt0bjN/LCpueqWz13HufFEV1SUatKs1cm4L6fFgCi1jT643X" crossorigin="anonymous">
<!-- The loading of KaTeX is deferred to speed up page rendering -->
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.2/dist/katex.min.js" integrity="sha384-Qsn9KnoKISj6dI8g7p1HBlNpVx0I8p1SvlwOldgi3IorMle61nQy4zEahWYtljaz" crossorigin="anonymous"></script>
<!-- To automatically render math in text elements, include the auto-render extension: -->
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.2/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"
onload="renderMathInElement(document.body);"></script>
</head>
...
</html>
```
You can also [download KaTeX](https://github.com/KaTeX/KaTeX/releases) and host it yourself.
For details on how to configure auto-render extension, refer to [the documentation](https://katex.org/docs/autorender.html).
### API
Call `katex.render` to render a TeX expression directly into a DOM element.
For example:
```js
katex.render("c = \\pm\\sqrt{a^2 + b^2}", element, {
throwOnError: false
});
```
Call `katex.renderToString` to generate an HTML string of the rendered math,
e.g., for server-side rendering. For example:
```js
var html = katex.renderToString("c = \\pm\\sqrt{a^2 + b^2}", {
throwOnError: false
});
// '<span class="katex">...</span>'
```
Make sure to include the CSS and font files in both cases.
If you are doing all rendering on the server, there is no need to include the
JavaScript on the client.
The examples above use the `throwOnError: false` option, which renders invalid
inputs as the TeX source code in red (by default), with the error message as
hover text. For other available options, see the
[API documentation](https://katex.org/docs/api.html),
[options documentation](https://katex.org/docs/options.html), and
[handling errors documentation](https://katex.org/docs/error.html).
## Demo and Documentation
Learn more about using KaTeX [on the website](https://katex.org)!
## Contributors
### Code Contributors
This project exists thanks to all the people who contribute code. If you'd like to help, see [our guide to contributing code](CONTRIBUTING.md).
<a href="https://github.com/KaTeX/KaTeX/graphs/contributors"><img src="https://contributors-svg.opencollective.com/katex/contributors.svg?width=890&button=false" alt="Code contributors" /></a>
### Financial Contributors
Become a financial contributor and help us sustain our community.
#### Individuals
<a href="https://opencollective.com/katex"><img src="https://opencollective.com/katex/individuals.svg?width=890" alt="Contribute on Open Collective"></a>
#### Organizations
Support this project with your organization. Your logo will show up here with a link to your website.
<a href="https://opencollective.com/katex/organization/0/website"><img src="https://opencollective.com/katex/organization/0/avatar.svg" alt="Organization 1"></a>
<a href="https://opencollective.com/katex/organization/1/website"><img src="https://opencollective.com/katex/organization/1/avatar.svg" alt="Organization 2"></a>
<a href="https://opencollective.com/katex/organization/2/website"><img src="https://opencollective.com/katex/organization/2/avatar.svg" alt="Organization 3"></a>
<a href="https://opencollective.com/katex/organization/3/website"><img src="https://opencollective.com/katex/organization/3/avatar.svg" alt="Organization 4"></a>
<a href="https://opencollective.com/katex/organization/4/website"><img src="https://opencollective.com/katex/organization/4/avatar.svg" alt="Organization 5"></a>
<a href="https://opencollective.com/katex/organization/5/website"><img src="https://opencollective.com/katex/organization/5/avatar.svg" alt="Organization 6"></a>
<a href="https://opencollective.com/katex/organization/6/website"><img src="https://opencollective.com/katex/organization/6/avatar.svg" alt="Organization 7"></a>
<a href="https://opencollective.com/katex/organization/7/website"><img src="https://opencollective.com/katex/organization/7/avatar.svg" alt="Organization 8"></a>
<a href="https://opencollective.com/katex/organization/8/website"><img src="https://opencollective.com/katex/organization/8/avatar.svg" alt="Organization 9"></a>
<a href="https://opencollective.com/katex/organization/9/website"><img src="https://opencollective.com/katex/organization/9/avatar.svg" alt="Organization 10"></a>
## License
KaTeX is licensed under the [MIT License](https://opensource.org/licenses/MIT).

View file

@ -0,0 +1,349 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("katex"));
else if(typeof define === 'function' && define.amd)
define(["katex"], factory);
else if(typeof exports === 'object')
exports["renderMathInElement"] = factory(require("katex"));
else
root["renderMathInElement"] = factory(root["katex"]);
})((typeof self !== 'undefined' ? self : this), function(__WEBPACK_EXTERNAL_MODULE__771__) {
return /******/ (function() { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ 771:
/***/ (function(module) {
module.exports = __WEBPACK_EXTERNAL_MODULE__771__;
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/compat get default export */
/******/ !function() {
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function() { return module['default']; } :
/******/ function() { return module; };
/******/ __webpack_require__.d(getter, { a: getter });
/******/ return getter;
/******/ };
/******/ }();
/******/
/******/ /* webpack/runtime/define property getters */
/******/ !function() {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = function(exports, definition) {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ }();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ !function() {
/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
/******/ }();
/******/
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
!function() {
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
"default": function() { return /* binding */ auto_render; }
});
// EXTERNAL MODULE: external "katex"
var external_katex_ = __webpack_require__(771);
var external_katex_default = /*#__PURE__*/__webpack_require__.n(external_katex_);
;// CONCATENATED MODULE: ./contrib/auto-render/splitAtDelimiters.js
/* eslint no-constant-condition:0 */
var findEndOfMath = function findEndOfMath(delimiter, text, startIndex) {
// Adapted from
// https://github.com/Khan/perseus/blob/master/src/perseus-markdown.jsx
var index = startIndex;
var braceLevel = 0;
var delimLength = delimiter.length;
while (index < text.length) {
var character = text[index];
if (braceLevel <= 0 && text.slice(index, index + delimLength) === delimiter) {
return index;
} else if (character === "\\") {
index++;
} else if (character === "{") {
braceLevel++;
} else if (character === "}") {
braceLevel--;
}
index++;
}
return -1;
};
var escapeRegex = function escapeRegex(string) {
return string.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
};
var amsRegex = /^\\begin{/;
var splitAtDelimiters = function splitAtDelimiters(text, delimiters) {
var index;
var data = [];
var regexLeft = new RegExp("(" + delimiters.map(function (x) {
return escapeRegex(x.left);
}).join("|") + ")");
while (true) {
index = text.search(regexLeft);
if (index === -1) {
break;
}
if (index > 0) {
data.push({
type: "text",
data: text.slice(0, index)
});
text = text.slice(index); // now text starts with delimiter
} // ... so this always succeeds:
var i = delimiters.findIndex(function (delim) {
return text.startsWith(delim.left);
});
index = findEndOfMath(delimiters[i].right, text, delimiters[i].left.length);
if (index === -1) {
break;
}
var rawData = text.slice(0, index + delimiters[i].right.length);
var math = amsRegex.test(rawData) ? rawData : text.slice(delimiters[i].left.length, index);
data.push({
type: "math",
data: math,
rawData: rawData,
display: delimiters[i].display
});
text = text.slice(index + delimiters[i].right.length);
}
if (text !== "") {
data.push({
type: "text",
data: text
});
}
return data;
};
/* harmony default export */ var auto_render_splitAtDelimiters = (splitAtDelimiters);
;// CONCATENATED MODULE: ./contrib/auto-render/auto-render.js
/* eslint no-console:0 */
/* Note: optionsCopy is mutated by this method. If it is ever exposed in the
* API, we should copy it before mutating.
*/
var renderMathInText = function renderMathInText(text, optionsCopy) {
var data = auto_render_splitAtDelimiters(text, optionsCopy.delimiters);
if (data.length === 1 && data[0].type === 'text') {
// There is no formula in the text.
// Let's return null which means there is no need to replace
// the current text node with a new one.
return null;
}
var fragment = document.createDocumentFragment();
for (var i = 0; i < data.length; i++) {
if (data[i].type === "text") {
fragment.appendChild(document.createTextNode(data[i].data));
} else {
var span = document.createElement("span");
var math = data[i].data; // Override any display mode defined in the settings with that
// defined by the text itself
optionsCopy.displayMode = data[i].display;
try {
if (optionsCopy.preProcess) {
math = optionsCopy.preProcess(math);
}
external_katex_default().render(math, span, optionsCopy);
} catch (e) {
if (!(e instanceof (external_katex_default()).ParseError)) {
throw e;
}
optionsCopy.errorCallback("KaTeX auto-render: Failed to parse `" + data[i].data + "` with ", e);
fragment.appendChild(document.createTextNode(data[i].rawData));
continue;
}
fragment.appendChild(span);
}
}
return fragment;
};
var renderElem = function renderElem(elem, optionsCopy) {
for (var i = 0; i < elem.childNodes.length; i++) {
var childNode = elem.childNodes[i];
if (childNode.nodeType === 3) {
// Text node
// Concatenate all sibling text nodes.
// Webkit browsers split very large text nodes into smaller ones,
// so the delimiters may be split across different nodes.
var textContentConcat = childNode.textContent;
var sibling = childNode.nextSibling;
var nSiblings = 0;
while (sibling && sibling.nodeType === Node.TEXT_NODE) {
textContentConcat += sibling.textContent;
sibling = sibling.nextSibling;
nSiblings++;
}
var frag = renderMathInText(textContentConcat, optionsCopy);
if (frag) {
// Remove extra text nodes
for (var j = 0; j < nSiblings; j++) {
childNode.nextSibling.remove();
}
i += frag.childNodes.length - 1;
elem.replaceChild(frag, childNode);
} else {
// If the concatenated text does not contain math
// the siblings will not either
i += nSiblings;
}
} else if (childNode.nodeType === 1) {
(function () {
// Element node
var className = ' ' + childNode.className + ' ';
var shouldRender = optionsCopy.ignoredTags.indexOf(childNode.nodeName.toLowerCase()) === -1 && optionsCopy.ignoredClasses.every(function (x) {
return className.indexOf(' ' + x + ' ') === -1;
});
if (shouldRender) {
renderElem(childNode, optionsCopy);
}
})();
} // Otherwise, it's something else, and ignore it.
}
};
var renderMathInElement = function renderMathInElement(elem, options) {
if (!elem) {
throw new Error("No element provided to render");
}
var optionsCopy = {}; // Object.assign(optionsCopy, option)
for (var option in options) {
if (options.hasOwnProperty(option)) {
optionsCopy[option] = options[option];
}
} // default options
optionsCopy.delimiters = optionsCopy.delimiters || [{
left: "$$",
right: "$$",
display: true
}, {
left: "\\(",
right: "\\)",
display: false
}, // LaTeX uses $…$, but it ruins the display of normal `$` in text:
// {left: "$", right: "$", display: false},
// $ must come after $$
// Render AMS environments even if outside $$…$$ delimiters.
{
left: "\\begin{equation}",
right: "\\end{equation}",
display: true
}, {
left: "\\begin{align}",
right: "\\end{align}",
display: true
}, {
left: "\\begin{alignat}",
right: "\\end{alignat}",
display: true
}, {
left: "\\begin{gather}",
right: "\\end{gather}",
display: true
}, {
left: "\\begin{CD}",
right: "\\end{CD}",
display: true
}, {
left: "\\[",
right: "\\]",
display: true
}];
optionsCopy.ignoredTags = optionsCopy.ignoredTags || ["script", "noscript", "style", "textarea", "pre", "code", "option"];
optionsCopy.ignoredClasses = optionsCopy.ignoredClasses || [];
optionsCopy.errorCallback = optionsCopy.errorCallback || console.error; // Enable sharing of global macros defined via `\gdef` between different
// math elements within a single call to `renderMathInElement`.
optionsCopy.macros = optionsCopy.macros || {};
renderElem(elem, optionsCopy);
};
/* harmony default export */ var auto_render = (renderMathInElement);
}();
__webpack_exports__ = __webpack_exports__["default"];
/******/ return __webpack_exports__;
/******/ })()
;
});

View file

@ -0,0 +1 @@
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("katex")):"function"==typeof define&&define.amd?define(["katex"],t):"object"==typeof exports?exports.renderMathInElement=t(require("katex")):e.renderMathInElement=t(e.katex)}("undefined"!=typeof self?self:this,(function(e){return function(){"use strict";var t={771:function(t){t.exports=e}},r={};function n(e){var i=r[e];if(void 0!==i)return i.exports;var a=r[e]={exports:{}};return t[e](a,a.exports,n),a.exports}n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,{a:t}),t},n.d=function(e,t){for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)};var i={};return function(){n.d(i,{default:function(){return s}});var e=n(771),t=n.n(e),r=function(e,t,r){for(var n=r,i=0,a=e.length;n<t.length;){var o=t[n];if(i<=0&&t.slice(n,n+a)===e)return n;"\\"===o?n++:"{"===o?i++:"}"===o&&i--,n++}return-1},a=/^\\begin{/,o=function(e,t){for(var n,i=[],o=new RegExp("("+t.map((function(e){return e.left.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&")})).join("|")+")");-1!==(n=e.search(o));){n>0&&(i.push({type:"text",data:e.slice(0,n)}),e=e.slice(n));var l=t.findIndex((function(t){return e.startsWith(t.left)}));if(-1===(n=r(t[l].right,e,t[l].left.length)))break;var d=e.slice(0,n+t[l].right.length),s=a.test(d)?d:e.slice(t[l].left.length,n);i.push({type:"math",data:s,rawData:d,display:t[l].display}),e=e.slice(n+t[l].right.length)}return""!==e&&i.push({type:"text",data:e}),i},l=function(e,r){var n=o(e,r.delimiters);if(1===n.length&&"text"===n[0].type)return null;for(var i=document.createDocumentFragment(),a=0;a<n.length;a++)if("text"===n[a].type)i.appendChild(document.createTextNode(n[a].data));else{var l=document.createElement("span"),d=n[a].data;r.displayMode=n[a].display;try{r.preProcess&&(d=r.preProcess(d)),t().render(d,l,r)}catch(e){if(!(e instanceof t().ParseError))throw e;r.errorCallback("KaTeX auto-render: Failed to parse `"+n[a].data+"` with ",e),i.appendChild(document.createTextNode(n[a].rawData));continue}i.appendChild(l)}return i},d=function e(t,r){for(var n=0;n<t.childNodes.length;n++){var i=t.childNodes[n];if(3===i.nodeType){for(var a=i.textContent,o=i.nextSibling,d=0;o&&o.nodeType===Node.TEXT_NODE;)a+=o.textContent,o=o.nextSibling,d++;var s=l(a,r);if(s){for(var f=0;f<d;f++)i.nextSibling.remove();n+=s.childNodes.length-1,t.replaceChild(s,i)}else n+=d}else 1===i.nodeType&&function(){var t=" "+i.className+" ";-1===r.ignoredTags.indexOf(i.nodeName.toLowerCase())&&r.ignoredClasses.every((function(e){return-1===t.indexOf(" "+e+" ")}))&&e(i,r)}()}},s=function(e,t){if(!e)throw new Error("No element provided to render");var r={};for(var n in t)t.hasOwnProperty(n)&&(r[n]=t[n]);r.delimiters=r.delimiters||[{left:"$$",right:"$$",display:!0},{left:"\\(",right:"\\)",display:!1},{left:"\\begin{equation}",right:"\\end{equation}",display:!0},{left:"\\begin{align}",right:"\\end{align}",display:!0},{left:"\\begin{alignat}",right:"\\end{alignat}",display:!0},{left:"\\begin{gather}",right:"\\end{gather}",display:!0},{left:"\\begin{CD}",right:"\\end{CD}",display:!0},{left:"\\[",right:"\\]",display:!0}],r.ignoredTags=r.ignoredTags||["script","noscript","style","textarea","pre","code","option"],r.ignoredClasses=r.ignoredClasses||[],r.errorCallback=r.errorCallback||console.error,r.macros=r.macros||{},d(e,r)}}(),i=i.default}()}));

View file

@ -0,0 +1,244 @@
import katex from '../katex.mjs';
/* eslint no-constant-condition:0 */
var findEndOfMath = function findEndOfMath(delimiter, text, startIndex) {
// Adapted from
// https://github.com/Khan/perseus/blob/master/src/perseus-markdown.jsx
var index = startIndex;
var braceLevel = 0;
var delimLength = delimiter.length;
while (index < text.length) {
var character = text[index];
if (braceLevel <= 0 && text.slice(index, index + delimLength) === delimiter) {
return index;
} else if (character === "\\") {
index++;
} else if (character === "{") {
braceLevel++;
} else if (character === "}") {
braceLevel--;
}
index++;
}
return -1;
};
var escapeRegex = function escapeRegex(string) {
return string.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
};
var amsRegex = /^\\begin{/;
var splitAtDelimiters = function splitAtDelimiters(text, delimiters) {
var index;
var data = [];
var regexLeft = new RegExp("(" + delimiters.map(x => escapeRegex(x.left)).join("|") + ")");
while (true) {
index = text.search(regexLeft);
if (index === -1) {
break;
}
if (index > 0) {
data.push({
type: "text",
data: text.slice(0, index)
});
text = text.slice(index); // now text starts with delimiter
} // ... so this always succeeds:
var i = delimiters.findIndex(delim => text.startsWith(delim.left));
index = findEndOfMath(delimiters[i].right, text, delimiters[i].left.length);
if (index === -1) {
break;
}
var rawData = text.slice(0, index + delimiters[i].right.length);
var math = amsRegex.test(rawData) ? rawData : text.slice(delimiters[i].left.length, index);
data.push({
type: "math",
data: math,
rawData,
display: delimiters[i].display
});
text = text.slice(index + delimiters[i].right.length);
}
if (text !== "") {
data.push({
type: "text",
data: text
});
}
return data;
};
/* eslint no-console:0 */
/* Note: optionsCopy is mutated by this method. If it is ever exposed in the
* API, we should copy it before mutating.
*/
var renderMathInText = function renderMathInText(text, optionsCopy) {
var data = splitAtDelimiters(text, optionsCopy.delimiters);
if (data.length === 1 && data[0].type === 'text') {
// There is no formula in the text.
// Let's return null which means there is no need to replace
// the current text node with a new one.
return null;
}
var fragment = document.createDocumentFragment();
for (var i = 0; i < data.length; i++) {
if (data[i].type === "text") {
fragment.appendChild(document.createTextNode(data[i].data));
} else {
var span = document.createElement("span");
var math = data[i].data; // Override any display mode defined in the settings with that
// defined by the text itself
optionsCopy.displayMode = data[i].display;
try {
if (optionsCopy.preProcess) {
math = optionsCopy.preProcess(math);
}
katex.render(math, span, optionsCopy);
} catch (e) {
if (!(e instanceof katex.ParseError)) {
throw e;
}
optionsCopy.errorCallback("KaTeX auto-render: Failed to parse `" + data[i].data + "` with ", e);
fragment.appendChild(document.createTextNode(data[i].rawData));
continue;
}
fragment.appendChild(span);
}
}
return fragment;
};
var renderElem = function renderElem(elem, optionsCopy) {
for (var i = 0; i < elem.childNodes.length; i++) {
var childNode = elem.childNodes[i];
if (childNode.nodeType === 3) {
// Text node
// Concatenate all sibling text nodes.
// Webkit browsers split very large text nodes into smaller ones,
// so the delimiters may be split across different nodes.
var textContentConcat = childNode.textContent;
var sibling = childNode.nextSibling;
var nSiblings = 0;
while (sibling && sibling.nodeType === Node.TEXT_NODE) {
textContentConcat += sibling.textContent;
sibling = sibling.nextSibling;
nSiblings++;
}
var frag = renderMathInText(textContentConcat, optionsCopy);
if (frag) {
// Remove extra text nodes
for (var j = 0; j < nSiblings; j++) {
childNode.nextSibling.remove();
}
i += frag.childNodes.length - 1;
elem.replaceChild(frag, childNode);
} else {
// If the concatenated text does not contain math
// the siblings will not either
i += nSiblings;
}
} else if (childNode.nodeType === 1) {
(function () {
// Element node
var className = ' ' + childNode.className + ' ';
var shouldRender = optionsCopy.ignoredTags.indexOf(childNode.nodeName.toLowerCase()) === -1 && optionsCopy.ignoredClasses.every(x => className.indexOf(' ' + x + ' ') === -1);
if (shouldRender) {
renderElem(childNode, optionsCopy);
}
})();
} // Otherwise, it's something else, and ignore it.
}
};
var renderMathInElement = function renderMathInElement(elem, options) {
if (!elem) {
throw new Error("No element provided to render");
}
var optionsCopy = {}; // Object.assign(optionsCopy, option)
for (var option in options) {
if (options.hasOwnProperty(option)) {
optionsCopy[option] = options[option];
}
} // default options
optionsCopy.delimiters = optionsCopy.delimiters || [{
left: "$$",
right: "$$",
display: true
}, {
left: "\\(",
right: "\\)",
display: false
}, // LaTeX uses $…$, but it ruins the display of normal `$` in text:
// {left: "$", right: "$", display: false},
// $ must come after $$
// Render AMS environments even if outside $$…$$ delimiters.
{
left: "\\begin{equation}",
right: "\\end{equation}",
display: true
}, {
left: "\\begin{align}",
right: "\\end{align}",
display: true
}, {
left: "\\begin{alignat}",
right: "\\end{alignat}",
display: true
}, {
left: "\\begin{gather}",
right: "\\end{gather}",
display: true
}, {
left: "\\begin{CD}",
right: "\\end{CD}",
display: true
}, {
left: "\\[",
right: "\\]",
display: true
}];
optionsCopy.ignoredTags = optionsCopy.ignoredTags || ["script", "noscript", "style", "textarea", "pre", "code", "option"];
optionsCopy.ignoredClasses = optionsCopy.ignoredClasses || [];
optionsCopy.errorCallback = optionsCopy.errorCallback || console.error; // Enable sharing of global macros defined via `\gdef` between different
// math elements within a single call to `renderMathInElement`.
optionsCopy.macros = optionsCopy.macros || {};
renderElem(elem, optionsCopy);
};
export { renderMathInElement as default };

View file

@ -0,0 +1,130 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else {
var a = factory();
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})((typeof self !== 'undefined' ? self : this), function() {
return /******/ (function() { // webpackBootstrap
/******/ "use strict";
var __webpack_exports__ = {};
;// CONCATENATED MODULE: ./contrib/copy-tex/katex2tex.js
// Set these to how you want inline and display math to be delimited.
var defaultCopyDelimiters = {
inline: ['$', '$'],
// alternative: ['\(', '\)']
display: ['$$', '$$'] // alternative: ['\[', '\]']
}; // Replace .katex elements with their TeX source (<annotation> element).
// Modifies fragment in-place. Useful for writing your own 'copy' handler,
// as in copy-tex.js.
function katexReplaceWithTex(fragment, copyDelimiters) {
if (copyDelimiters === void 0) {
copyDelimiters = defaultCopyDelimiters;
}
// Remove .katex-html blocks that are preceded by .katex-mathml blocks
// (which will get replaced below).
var katexHtml = fragment.querySelectorAll('.katex-mathml + .katex-html');
for (var i = 0; i < katexHtml.length; i++) {
var element = katexHtml[i];
if (element.remove) {
element.remove();
} else if (element.parentNode) {
element.parentNode.removeChild(element);
}
} // Replace .katex-mathml elements with their annotation (TeX source)
// descendant, with inline delimiters.
var katexMathml = fragment.querySelectorAll('.katex-mathml');
for (var _i = 0; _i < katexMathml.length; _i++) {
var _element = katexMathml[_i];
var texSource = _element.querySelector('annotation');
if (texSource) {
if (_element.replaceWith) {
_element.replaceWith(texSource);
} else if (_element.parentNode) {
_element.parentNode.replaceChild(texSource, _element);
}
texSource.innerHTML = copyDelimiters.inline[0] + texSource.innerHTML + copyDelimiters.inline[1];
}
} // Switch display math to display delimiters.
var displays = fragment.querySelectorAll('.katex-display annotation');
for (var _i2 = 0; _i2 < displays.length; _i2++) {
var _element2 = displays[_i2];
_element2.innerHTML = copyDelimiters.display[0] + _element2.innerHTML.substr(copyDelimiters.inline[0].length, _element2.innerHTML.length - copyDelimiters.inline[0].length - copyDelimiters.inline[1].length) + copyDelimiters.display[1];
}
return fragment;
}
/* harmony default export */ var katex2tex = (katexReplaceWithTex);
;// CONCATENATED MODULE: ./contrib/copy-tex/copy-tex.js
// Return <div class="katex"> element containing node, or null if not found.
function closestKatex(node) {
// If node is a Text Node, for example, go up to containing Element,
// where we can apply the `closest` method.
var element = node instanceof Element ? node : node.parentElement;
return element && element.closest('.katex');
} // Global copy handler to modify behavior on/within .katex elements.
document.addEventListener('copy', function (event) {
var selection = window.getSelection();
if (selection.isCollapsed || !event.clipboardData) {
return; // default action OK if selection is empty or unchangeable
}
var clipboardData = event.clipboardData;
var range = selection.getRangeAt(0); // When start point is within a formula, expand to entire formula.
var startKatex = closestKatex(range.startContainer);
if (startKatex) {
range.setStartBefore(startKatex);
} // Similarly, when end point is within a formula, expand to entire formula.
var endKatex = closestKatex(range.endContainer);
if (endKatex) {
range.setEndAfter(endKatex);
}
var fragment = range.cloneContents();
if (!fragment.querySelector('.katex-mathml')) {
return; // default action OK if no .katex-mathml elements
}
var htmlContents = Array.prototype.map.call(fragment.childNodes, function (el) {
return el instanceof Text ? el.textContent : el.outerHTML;
}).join(''); // Preserve usual HTML copy/paste behavior.
clipboardData.setData('text/html', htmlContents); // Rewrite plain-text version.
clipboardData.setData('text/plain', katex2tex(fragment).textContent); // Prevent normal copy handling.
event.preventDefault();
});
__webpack_exports__ = __webpack_exports__["default"];
/******/ return __webpack_exports__;
/******/ })()
;
});

View file

@ -0,0 +1 @@
!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var r in n)("object"==typeof exports?exports:e)[r]=n[r]}}("undefined"!=typeof self?self:this,(function(){return function(){"use strict";var e={},t={inline:["$","$"],display:["$$","$$"]};var n=function(e,n){void 0===n&&(n=t);for(var r=e.querySelectorAll(".katex-mathml + .katex-html"),a=0;a<r.length;a++){var o=r[a];o.remove?o.remove():o.parentNode&&o.parentNode.removeChild(o)}for(var i=e.querySelectorAll(".katex-mathml"),l=0;l<i.length;l++){var f=i[l],c=f.querySelector("annotation");c&&(f.replaceWith?f.replaceWith(c):f.parentNode&&f.parentNode.replaceChild(c,f),c.innerHTML=n.inline[0]+c.innerHTML+n.inline[1])}for(var d=e.querySelectorAll(".katex-display annotation"),s=0;s<d.length;s++){var p=d[s];p.innerHTML=n.display[0]+p.innerHTML.substr(n.inline[0].length,p.innerHTML.length-n.inline[0].length-n.inline[1].length)+n.display[1]}return e};function r(e){var t=e instanceof Element?e:e.parentElement;return t&&t.closest(".katex")}return document.addEventListener("copy",(function(e){var t=window.getSelection();if(!t.isCollapsed&&e.clipboardData){var a=e.clipboardData,o=t.getRangeAt(0),i=r(o.startContainer);i&&o.setStartBefore(i);var l=r(o.endContainer);l&&o.setEndAfter(l);var f=o.cloneContents();if(f.querySelector(".katex-mathml")){var c=Array.prototype.map.call(f.childNodes,(function(e){return e instanceof Text?e.textContent:e.outerHTML})).join("");a.setData("text/html",c),a.setData("text/plain",n(f).textContent),e.preventDefault()}}})),e=e.default}()}));

View file

@ -0,0 +1,105 @@
// Set these to how you want inline and display math to be delimited.
var defaultCopyDelimiters = {
inline: ['$', '$'],
// alternative: ['\(', '\)']
display: ['$$', '$$'] // alternative: ['\[', '\]']
}; // Replace .katex elements with their TeX source (<annotation> element).
// Modifies fragment in-place. Useful for writing your own 'copy' handler,
// as in copy-tex.js.
function katexReplaceWithTex(fragment, copyDelimiters) {
if (copyDelimiters === void 0) {
copyDelimiters = defaultCopyDelimiters;
}
// Remove .katex-html blocks that are preceded by .katex-mathml blocks
// (which will get replaced below).
var katexHtml = fragment.querySelectorAll('.katex-mathml + .katex-html');
for (var i = 0; i < katexHtml.length; i++) {
var element = katexHtml[i];
if (element.remove) {
element.remove();
} else if (element.parentNode) {
element.parentNode.removeChild(element);
}
} // Replace .katex-mathml elements with their annotation (TeX source)
// descendant, with inline delimiters.
var katexMathml = fragment.querySelectorAll('.katex-mathml');
for (var _i = 0; _i < katexMathml.length; _i++) {
var _element = katexMathml[_i];
var texSource = _element.querySelector('annotation');
if (texSource) {
if (_element.replaceWith) {
_element.replaceWith(texSource);
} else if (_element.parentNode) {
_element.parentNode.replaceChild(texSource, _element);
}
texSource.innerHTML = copyDelimiters.inline[0] + texSource.innerHTML + copyDelimiters.inline[1];
}
} // Switch display math to display delimiters.
var displays = fragment.querySelectorAll('.katex-display annotation');
for (var _i2 = 0; _i2 < displays.length; _i2++) {
var _element2 = displays[_i2];
_element2.innerHTML = copyDelimiters.display[0] + _element2.innerHTML.substr(copyDelimiters.inline[0].length, _element2.innerHTML.length - copyDelimiters.inline[0].length - copyDelimiters.inline[1].length) + copyDelimiters.display[1];
}
return fragment;
}
function closestKatex(node) {
// If node is a Text Node, for example, go up to containing Element,
// where we can apply the `closest` method.
var element = node instanceof Element ? node : node.parentElement;
return element && element.closest('.katex');
} // Global copy handler to modify behavior on/within .katex elements.
document.addEventListener('copy', function (event) {
var selection = window.getSelection();
if (selection.isCollapsed || !event.clipboardData) {
return; // default action OK if selection is empty or unchangeable
}
var clipboardData = event.clipboardData;
var range = selection.getRangeAt(0); // When start point is within a formula, expand to entire formula.
var startKatex = closestKatex(range.startContainer);
if (startKatex) {
range.setStartBefore(startKatex);
} // Similarly, when end point is within a formula, expand to entire formula.
var endKatex = closestKatex(range.endContainer);
if (endKatex) {
range.setEndAfter(endKatex);
}
var fragment = range.cloneContents();
if (!fragment.querySelector('.katex-mathml')) {
return; // default action OK if no .katex-mathml elements
}
var htmlContents = Array.prototype.map.call(fragment.childNodes, el => el instanceof Text ? el.textContent : el.outerHTML).join(''); // Preserve usual HTML copy/paste behavior.
clipboardData.setData('text/html', htmlContents); // Rewrite plain-text version.
clipboardData.setData('text/plain', katexReplaceWithTex(fragment).textContent); // Prevent normal copy handling.
event.preventDefault();
});

View file

@ -0,0 +1,112 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("katex"));
else if(typeof define === 'function' && define.amd)
define(["katex"], factory);
else {
var a = typeof exports === 'object' ? factory(require("katex")) : factory(root["katex"]);
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})((typeof self !== 'undefined' ? self : this), function(__WEBPACK_EXTERNAL_MODULE__771__) {
return /******/ (function() { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ 771:
/***/ (function(module) {
module.exports = __WEBPACK_EXTERNAL_MODULE__771__;
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/compat get default export */
/******/ !function() {
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function() { return module['default']; } :
/******/ function() { return module; };
/******/ __webpack_require__.d(getter, { a: getter });
/******/ return getter;
/******/ };
/******/ }();
/******/
/******/ /* webpack/runtime/define property getters */
/******/ !function() {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = function(exports, definition) {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ }();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ !function() {
/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
/******/ }();
/******/
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
!function() {
/* harmony import */ var katex__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(771);
/* harmony import */ var katex__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(katex__WEBPACK_IMPORTED_MODULE_0__);
var scripts = document.body.getElementsByTagName("script");
scripts = Array.prototype.slice.call(scripts);
scripts.forEach(function (script) {
if (!script.type || !script.type.match(/math\/tex/i)) {
return -1;
}
var display = script.type.match(/mode\s*=\s*display(;|\s|\n|$)/) != null;
var katexElement = document.createElement(display ? "div" : "span");
katexElement.setAttribute("class", display ? "equation" : "inline-equation");
try {
katex__WEBPACK_IMPORTED_MODULE_0___default().render(script.text, katexElement, {
displayMode: display
});
} catch (err) {
//console.error(err); linter doesn't like this
katexElement.textContent = script.text;
}
script.parentNode.replaceChild(katexElement, script);
});
}();
__webpack_exports__ = __webpack_exports__["default"];
/******/ return __webpack_exports__;
/******/ })()
;
});

View file

@ -0,0 +1 @@
!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("katex"));else if("function"==typeof define&&define.amd)define(["katex"],t);else{var r="object"==typeof exports?t(require("katex")):t(e.katex);for(var n in r)("object"==typeof exports?exports:e)[n]=r[n]}}("undefined"!=typeof self?self:this,(function(e){return function(){"use strict";var t={771:function(t){t.exports=e}},r={};function n(e){var o=r[e];if(void 0!==o)return o.exports;var i=r[e]={exports:{}};return t[e](i,i.exports,n),i.exports}n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,{a:t}),t},n.d=function(e,t){for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)};var o,i,a,u={};return o=n(771),i=n.n(o),a=document.body.getElementsByTagName("script"),(a=Array.prototype.slice.call(a)).forEach((function(e){if(!e.type||!e.type.match(/math\/tex/i))return-1;var t=null!=e.type.match(/mode\s*=\s*display(;|\s|\n|$)/),r=document.createElement(t?"div":"span");r.setAttribute("class",t?"equation":"inline-equation");try{i().render(e.text,r,{displayMode:t})}catch(t){r.textContent=e.text}e.parentNode.replaceChild(r,e)})),u=u.default}()}));

View file

@ -0,0 +1,24 @@
import katex from '../katex.mjs';
var scripts = document.body.getElementsByTagName("script");
scripts = Array.prototype.slice.call(scripts);
scripts.forEach(function (script) {
if (!script.type || !script.type.match(/math\/tex/i)) {
return -1;
}
var display = script.type.match(/mode\s*=\s*display(;|\s|\n|$)/) != null;
var katexElement = document.createElement(display ? "div" : "span");
katexElement.setAttribute("class", display ? "equation" : "inline-equation");
try {
katex.render(script.text, katexElement, {
displayMode: display
});
} catch (err) {
//console.error(err); linter doesn't like this
katexElement.textContent = script.text;
}
script.parentNode.replaceChild(katexElement, script);
});

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,881 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("katex"));
else if(typeof define === 'function' && define.amd)
define(["katex"], factory);
else {
var a = typeof exports === 'object' ? factory(require("katex")) : factory(root["katex"]);
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})((typeof self !== 'undefined' ? self : this), function(__WEBPACK_EXTERNAL_MODULE__771__) {
return /******/ (function() { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ 771:
/***/ (function(module) {
module.exports = __WEBPACK_EXTERNAL_MODULE__771__;
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/compat get default export */
/******/ !function() {
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function() { return module['default']; } :
/******/ function() { return module; };
/******/ __webpack_require__.d(getter, { a: getter });
/******/ return getter;
/******/ };
/******/ }();
/******/
/******/ /* webpack/runtime/define property getters */
/******/ !function() {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = function(exports, definition) {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ }();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ !function() {
/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
/******/ }();
/******/
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
!function() {
/* harmony import */ var katex__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(771);
/* harmony import */ var katex__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(katex__WEBPACK_IMPORTED_MODULE_0__);
/**
* renderA11yString returns a readable string.
*
* In some cases the string will have the proper semantic math
* meaning,:
* renderA11yString("\\frac{1}{2}"")
* -> "start fraction, 1, divided by, 2, end fraction"
*
* However, other cases do not:
* renderA11yString("f(x) = x^2")
* -> "f, left parenthesis, x, right parenthesis, equals, x, squared"
*
* The commas in the string aim to increase ease of understanding
* when read by a screenreader.
*/
// NOTE: since we're importing types here these files won't actually be
// included in the build.
// $FlowIgnore: we import the types directly anyways
var stringMap = {
"(": "left parenthesis",
")": "right parenthesis",
"[": "open bracket",
"]": "close bracket",
"\\{": "left brace",
"\\}": "right brace",
"\\lvert": "open vertical bar",
"\\rvert": "close vertical bar",
"|": "vertical bar",
"\\uparrow": "up arrow",
"\\Uparrow": "up arrow",
"\\downarrow": "down arrow",
"\\Downarrow": "down arrow",
"\\updownarrow": "up down arrow",
"\\leftarrow": "left arrow",
"\\Leftarrow": "left arrow",
"\\rightarrow": "right arrow",
"\\Rightarrow": "right arrow",
"\\langle": "open angle",
"\\rangle": "close angle",
"\\lfloor": "open floor",
"\\rfloor": "close floor",
"\\int": "integral",
"\\intop": "integral",
"\\lim": "limit",
"\\ln": "natural log",
"\\log": "log",
"\\sin": "sine",
"\\cos": "cosine",
"\\tan": "tangent",
"\\cot": "cotangent",
"\\sum": "sum",
"/": "slash",
",": "comma",
".": "point",
"-": "negative",
"+": "plus",
"~": "tilde",
":": "colon",
"?": "question mark",
"'": "apostrophe",
"\\%": "percent",
" ": "space",
"\\ ": "space",
"\\$": "dollar sign",
"\\angle": "angle",
"\\degree": "degree",
"\\circ": "circle",
"\\vec": "vector",
"\\triangle": "triangle",
"\\pi": "pi",
"\\prime": "prime",
"\\infty": "infinity",
"\\alpha": "alpha",
"\\beta": "beta",
"\\gamma": "gamma",
"\\omega": "omega",
"\\theta": "theta",
"\\sigma": "sigma",
"\\lambda": "lambda",
"\\tau": "tau",
"\\Delta": "delta",
"\\delta": "delta",
"\\mu": "mu",
"\\rho": "rho",
"\\nabla": "del",
"\\ell": "ell",
"\\ldots": "dots",
// TODO: add entries for all accents
"\\hat": "hat",
"\\acute": "acute"
};
var powerMap = {
"prime": "prime",
"degree": "degrees",
"circle": "degrees",
"2": "squared",
"3": "cubed"
};
var openMap = {
"|": "open vertical bar",
".": ""
};
var closeMap = {
"|": "close vertical bar",
".": ""
};
var binMap = {
"+": "plus",
"-": "minus",
"\\pm": "plus minus",
"\\cdot": "dot",
"*": "times",
"/": "divided by",
"\\times": "times",
"\\div": "divided by",
"\\circ": "circle",
"\\bullet": "bullet"
};
var relMap = {
"=": "equals",
"\\approx": "approximately equals",
"≠": "does not equal",
"\\geq": "is greater than or equal to",
"\\ge": "is greater than or equal to",
"\\leq": "is less than or equal to",
"\\le": "is less than or equal to",
">": "is greater than",
"<": "is less than",
"\\leftarrow": "left arrow",
"\\Leftarrow": "left arrow",
"\\rightarrow": "right arrow",
"\\Rightarrow": "right arrow",
":": "colon"
};
var accentUnderMap = {
"\\underleftarrow": "left arrow",
"\\underrightarrow": "right arrow",
"\\underleftrightarrow": "left-right arrow",
"\\undergroup": "group",
"\\underlinesegment": "line segment",
"\\utilde": "tilde"
};
var buildString = function buildString(str, type, a11yStrings) {
if (!str) {
return;
}
var ret;
if (type === "open") {
ret = str in openMap ? openMap[str] : stringMap[str] || str;
} else if (type === "close") {
ret = str in closeMap ? closeMap[str] : stringMap[str] || str;
} else if (type === "bin") {
ret = binMap[str] || str;
} else if (type === "rel") {
ret = relMap[str] || str;
} else {
ret = stringMap[str] || str;
} // If the text to add is a number and there is already a string
// in the list and the last string is a number then we should
// combine them into a single number
if (/^\d+$/.test(ret) && a11yStrings.length > 0 && // TODO(kevinb): check that the last item in a11yStrings is a string
// I think we might be able to drop the nested arrays, which would make
// this easier to type
// $FlowFixMe
/^\d+$/.test(a11yStrings[a11yStrings.length - 1])) {
a11yStrings[a11yStrings.length - 1] += ret;
} else if (ret) {
a11yStrings.push(ret);
}
};
var buildRegion = function buildRegion(a11yStrings, callback) {
var regionStrings = [];
a11yStrings.push(regionStrings);
callback(regionStrings);
};
var handleObject = function handleObject(tree, a11yStrings, atomType) {
// Everything else is assumed to be an object...
switch (tree.type) {
case "accent":
{
buildRegion(a11yStrings, function (a11yStrings) {
buildA11yStrings(tree.base, a11yStrings, atomType);
a11yStrings.push("with");
buildString(tree.label, "normal", a11yStrings);
a11yStrings.push("on top");
});
break;
}
case "accentUnder":
{
buildRegion(a11yStrings, function (a11yStrings) {
buildA11yStrings(tree.base, a11yStrings, atomType);
a11yStrings.push("with");
buildString(accentUnderMap[tree.label], "normal", a11yStrings);
a11yStrings.push("underneath");
});
break;
}
case "accent-token":
{
// Used internally by accent symbols.
break;
}
case "atom":
{
var text = tree.text;
switch (tree.family) {
case "bin":
{
buildString(text, "bin", a11yStrings);
break;
}
case "close":
{
buildString(text, "close", a11yStrings);
break;
}
// TODO(kevinb): figure out what should be done for inner
case "inner":
{
buildString(tree.text, "inner", a11yStrings);
break;
}
case "open":
{
buildString(text, "open", a11yStrings);
break;
}
case "punct":
{
buildString(text, "punct", a11yStrings);
break;
}
case "rel":
{
buildString(text, "rel", a11yStrings);
break;
}
default:
{
tree.family;
throw new Error("\"" + tree.family + "\" is not a valid atom type");
}
}
break;
}
case "color":
{
var color = tree.color.replace(/katex-/, "");
buildRegion(a11yStrings, function (regionStrings) {
regionStrings.push("start color " + color);
buildA11yStrings(tree.body, regionStrings, atomType);
regionStrings.push("end color " + color);
});
break;
}
case "color-token":
{
// Used by \color, \colorbox, and \fcolorbox but not directly rendered.
// It's a leaf node and has no children so just break.
break;
}
case "delimsizing":
{
if (tree.delim && tree.delim !== ".") {
buildString(tree.delim, "normal", a11yStrings);
}
break;
}
case "genfrac":
{
buildRegion(a11yStrings, function (regionStrings) {
// genfrac can have unbalanced delimiters
var leftDelim = tree.leftDelim,
rightDelim = tree.rightDelim; // NOTE: Not sure if this is a safe assumption
// hasBarLine true -> fraction, false -> binomial
if (tree.hasBarLine) {
regionStrings.push("start fraction");
leftDelim && buildString(leftDelim, "open", regionStrings);
buildA11yStrings(tree.numer, regionStrings, atomType);
regionStrings.push("divided by");
buildA11yStrings(tree.denom, regionStrings, atomType);
rightDelim && buildString(rightDelim, "close", regionStrings);
regionStrings.push("end fraction");
} else {
regionStrings.push("start binomial");
leftDelim && buildString(leftDelim, "open", regionStrings);
buildA11yStrings(tree.numer, regionStrings, atomType);
regionStrings.push("over");
buildA11yStrings(tree.denom, regionStrings, atomType);
rightDelim && buildString(rightDelim, "close", regionStrings);
regionStrings.push("end binomial");
}
});
break;
}
case "hbox":
{
buildA11yStrings(tree.body, a11yStrings, atomType);
break;
}
case "kern":
{
// No op: we don't attempt to present kerning information
// to the screen reader.
break;
}
case "leftright":
{
buildRegion(a11yStrings, function (regionStrings) {
buildString(tree.left, "open", regionStrings);
buildA11yStrings(tree.body, regionStrings, atomType);
buildString(tree.right, "close", regionStrings);
});
break;
}
case "leftright-right":
{
// TODO: double check that this is a no-op
break;
}
case "lap":
{
buildA11yStrings(tree.body, a11yStrings, atomType);
break;
}
case "mathord":
{
buildString(tree.text, "normal", a11yStrings);
break;
}
case "op":
{
var body = tree.body,
name = tree.name;
if (body) {
buildA11yStrings(body, a11yStrings, atomType);
} else if (name) {
buildString(name, "normal", a11yStrings);
}
break;
}
case "op-token":
{
// Used internally by operator symbols.
buildString(tree.text, atomType, a11yStrings);
break;
}
case "ordgroup":
{
buildA11yStrings(tree.body, a11yStrings, atomType);
break;
}
case "overline":
{
buildRegion(a11yStrings, function (a11yStrings) {
a11yStrings.push("start overline");
buildA11yStrings(tree.body, a11yStrings, atomType);
a11yStrings.push("end overline");
});
break;
}
case "pmb":
{
a11yStrings.push("bold");
break;
}
case "phantom":
{
a11yStrings.push("empty space");
break;
}
case "raisebox":
{
buildA11yStrings(tree.body, a11yStrings, atomType);
break;
}
case "rule":
{
a11yStrings.push("rectangle");
break;
}
case "sizing":
{
buildA11yStrings(tree.body, a11yStrings, atomType);
break;
}
case "spacing":
{
a11yStrings.push("space");
break;
}
case "styling":
{
// We ignore the styling and just pass through the contents
buildA11yStrings(tree.body, a11yStrings, atomType);
break;
}
case "sqrt":
{
buildRegion(a11yStrings, function (regionStrings) {
var body = tree.body,
index = tree.index;
if (index) {
var indexString = flatten(buildA11yStrings(index, [], atomType)).join(",");
if (indexString === "3") {
regionStrings.push("cube root of");
buildA11yStrings(body, regionStrings, atomType);
regionStrings.push("end cube root");
return;
}
regionStrings.push("root");
regionStrings.push("start index");
buildA11yStrings(index, regionStrings, atomType);
regionStrings.push("end index");
return;
}
regionStrings.push("square root of");
buildA11yStrings(body, regionStrings, atomType);
regionStrings.push("end square root");
});
break;
}
case "supsub":
{
var base = tree.base,
sub = tree.sub,
sup = tree.sup;
var isLog = false;
if (base) {
buildA11yStrings(base, a11yStrings, atomType);
isLog = base.type === "op" && base.name === "\\log";
}
if (sub) {
var regionName = isLog ? "base" : "subscript";
buildRegion(a11yStrings, function (regionStrings) {
regionStrings.push("start " + regionName);
buildA11yStrings(sub, regionStrings, atomType);
regionStrings.push("end " + regionName);
});
}
if (sup) {
buildRegion(a11yStrings, function (regionStrings) {
var supString = flatten(buildA11yStrings(sup, [], atomType)).join(",");
if (supString in powerMap) {
regionStrings.push(powerMap[supString]);
return;
}
regionStrings.push("start superscript");
buildA11yStrings(sup, regionStrings, atomType);
regionStrings.push("end superscript");
});
}
break;
}
case "text":
{
// TODO: handle other fonts
if (tree.font === "\\textbf") {
buildRegion(a11yStrings, function (regionStrings) {
regionStrings.push("start bold text");
buildA11yStrings(tree.body, regionStrings, atomType);
regionStrings.push("end bold text");
});
break;
}
buildRegion(a11yStrings, function (regionStrings) {
regionStrings.push("start text");
buildA11yStrings(tree.body, regionStrings, atomType);
regionStrings.push("end text");
});
break;
}
case "textord":
{
buildString(tree.text, atomType, a11yStrings);
break;
}
case "smash":
{
buildA11yStrings(tree.body, a11yStrings, atomType);
break;
}
case "enclose":
{
// TODO: create a map for these.
// TODO: differentiate between a body with a single atom, e.g.
// "cancel a" instead of "start cancel, a, end cancel"
if (/cancel/.test(tree.label)) {
buildRegion(a11yStrings, function (regionStrings) {
regionStrings.push("start cancel");
buildA11yStrings(tree.body, regionStrings, atomType);
regionStrings.push("end cancel");
});
break;
} else if (/box/.test(tree.label)) {
buildRegion(a11yStrings, function (regionStrings) {
regionStrings.push("start box");
buildA11yStrings(tree.body, regionStrings, atomType);
regionStrings.push("end box");
});
break;
} else if (/sout/.test(tree.label)) {
buildRegion(a11yStrings, function (regionStrings) {
regionStrings.push("start strikeout");
buildA11yStrings(tree.body, regionStrings, atomType);
regionStrings.push("end strikeout");
});
break;
} else if (/phase/.test(tree.label)) {
buildRegion(a11yStrings, function (regionStrings) {
regionStrings.push("start phase angle");
buildA11yStrings(tree.body, regionStrings, atomType);
regionStrings.push("end phase angle");
});
break;
}
throw new Error("KaTeX-a11y: enclose node with " + tree.label + " not supported yet");
}
case "vcenter":
{
buildA11yStrings(tree.body, a11yStrings, atomType);
break;
}
case "vphantom":
{
throw new Error("KaTeX-a11y: vphantom not implemented yet");
}
case "hphantom":
{
throw new Error("KaTeX-a11y: hphantom not implemented yet");
}
case "operatorname":
{
buildA11yStrings(tree.body, a11yStrings, atomType);
break;
}
case "array":
{
throw new Error("KaTeX-a11y: array not implemented yet");
}
case "raw":
{
throw new Error("KaTeX-a11y: raw not implemented yet");
}
case "size":
{
// Although there are nodes of type "size" in the parse tree, they have
// no semantic meaning and should be ignored.
break;
}
case "url":
{
throw new Error("KaTeX-a11y: url not implemented yet");
}
case "tag":
{
throw new Error("KaTeX-a11y: tag not implemented yet");
}
case "verb":
{
buildString("start verbatim", "normal", a11yStrings);
buildString(tree.body, "normal", a11yStrings);
buildString("end verbatim", "normal", a11yStrings);
break;
}
case "environment":
{
throw new Error("KaTeX-a11y: environment not implemented yet");
}
case "horizBrace":
{
buildString("start " + tree.label.slice(1), "normal", a11yStrings);
buildA11yStrings(tree.base, a11yStrings, atomType);
buildString("end " + tree.label.slice(1), "normal", a11yStrings);
break;
}
case "infix":
{
// All infix nodes are replace with other nodes.
break;
}
case "includegraphics":
{
throw new Error("KaTeX-a11y: includegraphics not implemented yet");
}
case "font":
{
// TODO: callout the start/end of specific fonts
// TODO: map \BBb{N} to "the naturals" or something like that
buildA11yStrings(tree.body, a11yStrings, atomType);
break;
}
case "href":
{
throw new Error("KaTeX-a11y: href not implemented yet");
}
case "cr":
{
// This is used by environments.
throw new Error("KaTeX-a11y: cr not implemented yet");
}
case "underline":
{
buildRegion(a11yStrings, function (a11yStrings) {
a11yStrings.push("start underline");
buildA11yStrings(tree.body, a11yStrings, atomType);
a11yStrings.push("end underline");
});
break;
}
case "xArrow":
{
throw new Error("KaTeX-a11y: xArrow not implemented yet");
}
case "cdlabel":
{
throw new Error("KaTeX-a11y: cdlabel not implemented yet");
}
case "cdlabelparent":
{
throw new Error("KaTeX-a11y: cdlabelparent not implemented yet");
}
case "mclass":
{
// \neq and \ne are macros so we let "htmlmathml" render the mathmal
// side of things and extract the text from that.
var _atomType = tree.mclass.slice(1); // $FlowFixMe: drop the leading "m" from the values in mclass
buildA11yStrings(tree.body, a11yStrings, _atomType);
break;
}
case "mathchoice":
{
// TODO: track which which style we're using, e.g. dispaly, text, etc.
// default to text style if even that may not be the correct style
buildA11yStrings(tree.text, a11yStrings, atomType);
break;
}
case "htmlmathml":
{
buildA11yStrings(tree.mathml, a11yStrings, atomType);
break;
}
case "middle":
{
buildString(tree.delim, atomType, a11yStrings);
break;
}
case "internal":
{
// internal nodes are never included in the parse tree
break;
}
case "html":
{
buildA11yStrings(tree.body, a11yStrings, atomType);
break;
}
default:
tree.type;
throw new Error("KaTeX a11y un-recognized type: " + tree.type);
}
};
var buildA11yStrings = function buildA11yStrings(tree, a11yStrings, atomType) {
if (a11yStrings === void 0) {
a11yStrings = [];
}
if (tree instanceof Array) {
for (var i = 0; i < tree.length; i++) {
buildA11yStrings(tree[i], a11yStrings, atomType);
}
} else {
handleObject(tree, a11yStrings, atomType);
}
return a11yStrings;
};
var flatten = function flatten(array) {
var result = [];
array.forEach(function (item) {
if (item instanceof Array) {
result = result.concat(flatten(item));
} else {
result.push(item);
}
});
return result;
};
var renderA11yString = function renderA11yString(text, settings) {
var tree = katex__WEBPACK_IMPORTED_MODULE_0___default().__parse(text, settings);
var a11yStrings = buildA11yStrings(tree, [], "normal");
return flatten(a11yStrings).join(", ");
};
/* harmony default export */ __webpack_exports__["default"] = (renderA11yString);
}();
__webpack_exports__ = __webpack_exports__["default"];
/******/ return __webpack_exports__;
/******/ })()
;
});

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,800 @@
import katex from '../katex.mjs';
/**
* renderA11yString returns a readable string.
*
* In some cases the string will have the proper semantic math
* meaning,:
* renderA11yString("\\frac{1}{2}"")
* -> "start fraction, 1, divided by, 2, end fraction"
*
* However, other cases do not:
* renderA11yString("f(x) = x^2")
* -> "f, left parenthesis, x, right parenthesis, equals, x, squared"
*
* The commas in the string aim to increase ease of understanding
* when read by a screenreader.
*/
var stringMap = {
"(": "left parenthesis",
")": "right parenthesis",
"[": "open bracket",
"]": "close bracket",
"\\{": "left brace",
"\\}": "right brace",
"\\lvert": "open vertical bar",
"\\rvert": "close vertical bar",
"|": "vertical bar",
"\\uparrow": "up arrow",
"\\Uparrow": "up arrow",
"\\downarrow": "down arrow",
"\\Downarrow": "down arrow",
"\\updownarrow": "up down arrow",
"\\leftarrow": "left arrow",
"\\Leftarrow": "left arrow",
"\\rightarrow": "right arrow",
"\\Rightarrow": "right arrow",
"\\langle": "open angle",
"\\rangle": "close angle",
"\\lfloor": "open floor",
"\\rfloor": "close floor",
"\\int": "integral",
"\\intop": "integral",
"\\lim": "limit",
"\\ln": "natural log",
"\\log": "log",
"\\sin": "sine",
"\\cos": "cosine",
"\\tan": "tangent",
"\\cot": "cotangent",
"\\sum": "sum",
"/": "slash",
",": "comma",
".": "point",
"-": "negative",
"+": "plus",
"~": "tilde",
":": "colon",
"?": "question mark",
"'": "apostrophe",
"\\%": "percent",
" ": "space",
"\\ ": "space",
"\\$": "dollar sign",
"\\angle": "angle",
"\\degree": "degree",
"\\circ": "circle",
"\\vec": "vector",
"\\triangle": "triangle",
"\\pi": "pi",
"\\prime": "prime",
"\\infty": "infinity",
"\\alpha": "alpha",
"\\beta": "beta",
"\\gamma": "gamma",
"\\omega": "omega",
"\\theta": "theta",
"\\sigma": "sigma",
"\\lambda": "lambda",
"\\tau": "tau",
"\\Delta": "delta",
"\\delta": "delta",
"\\mu": "mu",
"\\rho": "rho",
"\\nabla": "del",
"\\ell": "ell",
"\\ldots": "dots",
// TODO: add entries for all accents
"\\hat": "hat",
"\\acute": "acute"
};
var powerMap = {
"prime": "prime",
"degree": "degrees",
"circle": "degrees",
"2": "squared",
"3": "cubed"
};
var openMap = {
"|": "open vertical bar",
".": ""
};
var closeMap = {
"|": "close vertical bar",
".": ""
};
var binMap = {
"+": "plus",
"-": "minus",
"\\pm": "plus minus",
"\\cdot": "dot",
"*": "times",
"/": "divided by",
"\\times": "times",
"\\div": "divided by",
"\\circ": "circle",
"\\bullet": "bullet"
};
var relMap = {
"=": "equals",
"\\approx": "approximately equals",
"≠": "does not equal",
"\\geq": "is greater than or equal to",
"\\ge": "is greater than or equal to",
"\\leq": "is less than or equal to",
"\\le": "is less than or equal to",
">": "is greater than",
"<": "is less than",
"\\leftarrow": "left arrow",
"\\Leftarrow": "left arrow",
"\\rightarrow": "right arrow",
"\\Rightarrow": "right arrow",
":": "colon"
};
var accentUnderMap = {
"\\underleftarrow": "left arrow",
"\\underrightarrow": "right arrow",
"\\underleftrightarrow": "left-right arrow",
"\\undergroup": "group",
"\\underlinesegment": "line segment",
"\\utilde": "tilde"
};
var buildString = (str, type, a11yStrings) => {
if (!str) {
return;
}
var ret;
if (type === "open") {
ret = str in openMap ? openMap[str] : stringMap[str] || str;
} else if (type === "close") {
ret = str in closeMap ? closeMap[str] : stringMap[str] || str;
} else if (type === "bin") {
ret = binMap[str] || str;
} else if (type === "rel") {
ret = relMap[str] || str;
} else {
ret = stringMap[str] || str;
} // If the text to add is a number and there is already a string
// in the list and the last string is a number then we should
// combine them into a single number
if (/^\d+$/.test(ret) && a11yStrings.length > 0 && // TODO(kevinb): check that the last item in a11yStrings is a string
// I think we might be able to drop the nested arrays, which would make
// this easier to type
// $FlowFixMe
/^\d+$/.test(a11yStrings[a11yStrings.length - 1])) {
a11yStrings[a11yStrings.length - 1] += ret;
} else if (ret) {
a11yStrings.push(ret);
}
};
var buildRegion = (a11yStrings, callback) => {
var regionStrings = [];
a11yStrings.push(regionStrings);
callback(regionStrings);
};
var handleObject = (tree, a11yStrings, atomType) => {
// Everything else is assumed to be an object...
switch (tree.type) {
case "accent":
{
buildRegion(a11yStrings, a11yStrings => {
buildA11yStrings(tree.base, a11yStrings, atomType);
a11yStrings.push("with");
buildString(tree.label, "normal", a11yStrings);
a11yStrings.push("on top");
});
break;
}
case "accentUnder":
{
buildRegion(a11yStrings, a11yStrings => {
buildA11yStrings(tree.base, a11yStrings, atomType);
a11yStrings.push("with");
buildString(accentUnderMap[tree.label], "normal", a11yStrings);
a11yStrings.push("underneath");
});
break;
}
case "accent-token":
{
// Used internally by accent symbols.
break;
}
case "atom":
{
var {
text
} = tree;
switch (tree.family) {
case "bin":
{
buildString(text, "bin", a11yStrings);
break;
}
case "close":
{
buildString(text, "close", a11yStrings);
break;
}
// TODO(kevinb): figure out what should be done for inner
case "inner":
{
buildString(tree.text, "inner", a11yStrings);
break;
}
case "open":
{
buildString(text, "open", a11yStrings);
break;
}
case "punct":
{
buildString(text, "punct", a11yStrings);
break;
}
case "rel":
{
buildString(text, "rel", a11yStrings);
break;
}
default:
{
tree.family;
throw new Error("\"" + tree.family + "\" is not a valid atom type");
}
}
break;
}
case "color":
{
var color = tree.color.replace(/katex-/, "");
buildRegion(a11yStrings, regionStrings => {
regionStrings.push("start color " + color);
buildA11yStrings(tree.body, regionStrings, atomType);
regionStrings.push("end color " + color);
});
break;
}
case "color-token":
{
// Used by \color, \colorbox, and \fcolorbox but not directly rendered.
// It's a leaf node and has no children so just break.
break;
}
case "delimsizing":
{
if (tree.delim && tree.delim !== ".") {
buildString(tree.delim, "normal", a11yStrings);
}
break;
}
case "genfrac":
{
buildRegion(a11yStrings, regionStrings => {
// genfrac can have unbalanced delimiters
var {
leftDelim,
rightDelim
} = tree; // NOTE: Not sure if this is a safe assumption
// hasBarLine true -> fraction, false -> binomial
if (tree.hasBarLine) {
regionStrings.push("start fraction");
leftDelim && buildString(leftDelim, "open", regionStrings);
buildA11yStrings(tree.numer, regionStrings, atomType);
regionStrings.push("divided by");
buildA11yStrings(tree.denom, regionStrings, atomType);
rightDelim && buildString(rightDelim, "close", regionStrings);
regionStrings.push("end fraction");
} else {
regionStrings.push("start binomial");
leftDelim && buildString(leftDelim, "open", regionStrings);
buildA11yStrings(tree.numer, regionStrings, atomType);
regionStrings.push("over");
buildA11yStrings(tree.denom, regionStrings, atomType);
rightDelim && buildString(rightDelim, "close", regionStrings);
regionStrings.push("end binomial");
}
});
break;
}
case "hbox":
{
buildA11yStrings(tree.body, a11yStrings, atomType);
break;
}
case "kern":
{
// No op: we don't attempt to present kerning information
// to the screen reader.
break;
}
case "leftright":
{
buildRegion(a11yStrings, regionStrings => {
buildString(tree.left, "open", regionStrings);
buildA11yStrings(tree.body, regionStrings, atomType);
buildString(tree.right, "close", regionStrings);
});
break;
}
case "leftright-right":
{
// TODO: double check that this is a no-op
break;
}
case "lap":
{
buildA11yStrings(tree.body, a11yStrings, atomType);
break;
}
case "mathord":
{
buildString(tree.text, "normal", a11yStrings);
break;
}
case "op":
{
var {
body,
name
} = tree;
if (body) {
buildA11yStrings(body, a11yStrings, atomType);
} else if (name) {
buildString(name, "normal", a11yStrings);
}
break;
}
case "op-token":
{
// Used internally by operator symbols.
buildString(tree.text, atomType, a11yStrings);
break;
}
case "ordgroup":
{
buildA11yStrings(tree.body, a11yStrings, atomType);
break;
}
case "overline":
{
buildRegion(a11yStrings, function (a11yStrings) {
a11yStrings.push("start overline");
buildA11yStrings(tree.body, a11yStrings, atomType);
a11yStrings.push("end overline");
});
break;
}
case "pmb":
{
a11yStrings.push("bold");
break;
}
case "phantom":
{
a11yStrings.push("empty space");
break;
}
case "raisebox":
{
buildA11yStrings(tree.body, a11yStrings, atomType);
break;
}
case "rule":
{
a11yStrings.push("rectangle");
break;
}
case "sizing":
{
buildA11yStrings(tree.body, a11yStrings, atomType);
break;
}
case "spacing":
{
a11yStrings.push("space");
break;
}
case "styling":
{
// We ignore the styling and just pass through the contents
buildA11yStrings(tree.body, a11yStrings, atomType);
break;
}
case "sqrt":
{
buildRegion(a11yStrings, regionStrings => {
var {
body,
index
} = tree;
if (index) {
var indexString = flatten(buildA11yStrings(index, [], atomType)).join(",");
if (indexString === "3") {
regionStrings.push("cube root of");
buildA11yStrings(body, regionStrings, atomType);
regionStrings.push("end cube root");
return;
}
regionStrings.push("root");
regionStrings.push("start index");
buildA11yStrings(index, regionStrings, atomType);
regionStrings.push("end index");
return;
}
regionStrings.push("square root of");
buildA11yStrings(body, regionStrings, atomType);
regionStrings.push("end square root");
});
break;
}
case "supsub":
{
var {
base,
sub,
sup
} = tree;
var isLog = false;
if (base) {
buildA11yStrings(base, a11yStrings, atomType);
isLog = base.type === "op" && base.name === "\\log";
}
if (sub) {
var regionName = isLog ? "base" : "subscript";
buildRegion(a11yStrings, function (regionStrings) {
regionStrings.push("start " + regionName);
buildA11yStrings(sub, regionStrings, atomType);
regionStrings.push("end " + regionName);
});
}
if (sup) {
buildRegion(a11yStrings, function (regionStrings) {
var supString = flatten(buildA11yStrings(sup, [], atomType)).join(",");
if (supString in powerMap) {
regionStrings.push(powerMap[supString]);
return;
}
regionStrings.push("start superscript");
buildA11yStrings(sup, regionStrings, atomType);
regionStrings.push("end superscript");
});
}
break;
}
case "text":
{
// TODO: handle other fonts
if (tree.font === "\\textbf") {
buildRegion(a11yStrings, function (regionStrings) {
regionStrings.push("start bold text");
buildA11yStrings(tree.body, regionStrings, atomType);
regionStrings.push("end bold text");
});
break;
}
buildRegion(a11yStrings, function (regionStrings) {
regionStrings.push("start text");
buildA11yStrings(tree.body, regionStrings, atomType);
regionStrings.push("end text");
});
break;
}
case "textord":
{
buildString(tree.text, atomType, a11yStrings);
break;
}
case "smash":
{
buildA11yStrings(tree.body, a11yStrings, atomType);
break;
}
case "enclose":
{
// TODO: create a map for these.
// TODO: differentiate between a body with a single atom, e.g.
// "cancel a" instead of "start cancel, a, end cancel"
if (/cancel/.test(tree.label)) {
buildRegion(a11yStrings, function (regionStrings) {
regionStrings.push("start cancel");
buildA11yStrings(tree.body, regionStrings, atomType);
regionStrings.push("end cancel");
});
break;
} else if (/box/.test(tree.label)) {
buildRegion(a11yStrings, function (regionStrings) {
regionStrings.push("start box");
buildA11yStrings(tree.body, regionStrings, atomType);
regionStrings.push("end box");
});
break;
} else if (/sout/.test(tree.label)) {
buildRegion(a11yStrings, function (regionStrings) {
regionStrings.push("start strikeout");
buildA11yStrings(tree.body, regionStrings, atomType);
regionStrings.push("end strikeout");
});
break;
} else if (/phase/.test(tree.label)) {
buildRegion(a11yStrings, function (regionStrings) {
regionStrings.push("start phase angle");
buildA11yStrings(tree.body, regionStrings, atomType);
regionStrings.push("end phase angle");
});
break;
}
throw new Error("KaTeX-a11y: enclose node with " + tree.label + " not supported yet");
}
case "vcenter":
{
buildA11yStrings(tree.body, a11yStrings, atomType);
break;
}
case "vphantom":
{
throw new Error("KaTeX-a11y: vphantom not implemented yet");
}
case "hphantom":
{
throw new Error("KaTeX-a11y: hphantom not implemented yet");
}
case "operatorname":
{
buildA11yStrings(tree.body, a11yStrings, atomType);
break;
}
case "array":
{
throw new Error("KaTeX-a11y: array not implemented yet");
}
case "raw":
{
throw new Error("KaTeX-a11y: raw not implemented yet");
}
case "size":
{
// Although there are nodes of type "size" in the parse tree, they have
// no semantic meaning and should be ignored.
break;
}
case "url":
{
throw new Error("KaTeX-a11y: url not implemented yet");
}
case "tag":
{
throw new Error("KaTeX-a11y: tag not implemented yet");
}
case "verb":
{
buildString("start verbatim", "normal", a11yStrings);
buildString(tree.body, "normal", a11yStrings);
buildString("end verbatim", "normal", a11yStrings);
break;
}
case "environment":
{
throw new Error("KaTeX-a11y: environment not implemented yet");
}
case "horizBrace":
{
buildString("start " + tree.label.slice(1), "normal", a11yStrings);
buildA11yStrings(tree.base, a11yStrings, atomType);
buildString("end " + tree.label.slice(1), "normal", a11yStrings);
break;
}
case "infix":
{
// All infix nodes are replace with other nodes.
break;
}
case "includegraphics":
{
throw new Error("KaTeX-a11y: includegraphics not implemented yet");
}
case "font":
{
// TODO: callout the start/end of specific fonts
// TODO: map \BBb{N} to "the naturals" or something like that
buildA11yStrings(tree.body, a11yStrings, atomType);
break;
}
case "href":
{
throw new Error("KaTeX-a11y: href not implemented yet");
}
case "cr":
{
// This is used by environments.
throw new Error("KaTeX-a11y: cr not implemented yet");
}
case "underline":
{
buildRegion(a11yStrings, function (a11yStrings) {
a11yStrings.push("start underline");
buildA11yStrings(tree.body, a11yStrings, atomType);
a11yStrings.push("end underline");
});
break;
}
case "xArrow":
{
throw new Error("KaTeX-a11y: xArrow not implemented yet");
}
case "cdlabel":
{
throw new Error("KaTeX-a11y: cdlabel not implemented yet");
}
case "cdlabelparent":
{
throw new Error("KaTeX-a11y: cdlabelparent not implemented yet");
}
case "mclass":
{
// \neq and \ne are macros so we let "htmlmathml" render the mathmal
// side of things and extract the text from that.
var _atomType = tree.mclass.slice(1); // $FlowFixMe: drop the leading "m" from the values in mclass
buildA11yStrings(tree.body, a11yStrings, _atomType);
break;
}
case "mathchoice":
{
// TODO: track which which style we're using, e.g. dispaly, text, etc.
// default to text style if even that may not be the correct style
buildA11yStrings(tree.text, a11yStrings, atomType);
break;
}
case "htmlmathml":
{
buildA11yStrings(tree.mathml, a11yStrings, atomType);
break;
}
case "middle":
{
buildString(tree.delim, atomType, a11yStrings);
break;
}
case "internal":
{
// internal nodes are never included in the parse tree
break;
}
case "html":
{
buildA11yStrings(tree.body, a11yStrings, atomType);
break;
}
default:
tree.type;
throw new Error("KaTeX a11y un-recognized type: " + tree.type);
}
};
var buildA11yStrings = function buildA11yStrings(tree, a11yStrings, atomType) {
if (a11yStrings === void 0) {
a11yStrings = [];
}
if (tree instanceof Array) {
for (var i = 0; i < tree.length; i++) {
buildA11yStrings(tree[i], a11yStrings, atomType);
}
} else {
handleObject(tree, a11yStrings, atomType);
}
return a11yStrings;
};
var flatten = function flatten(array) {
var result = [];
array.forEach(function (item) {
if (item instanceof Array) {
result = result.concat(flatten(item));
} else {
result.push(item);
}
});
return result;
};
var renderA11yString = function renderA11yString(text, settings) {
var tree = katex.__parse(text, settings);
var a11yStrings = buildA11yStrings(tree, [], "normal");
return flatten(a11yStrings).join(", ");
};
export { renderA11yString as default };

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more