Theme 'hugo-theme-flat' hinzugefuegt
parent
3415dde294
commit
8a2e9e1d15
66
config.toml
66
config.toml
|
@ -1,4 +1,62 @@
|
|||
baseURL = 'https://hugo-test.c3re.de/master/'
|
||||
languageCode = 'en-us'
|
||||
title = 'My New Hugo Site'
|
||||
theme = 'ananke'
|
||||
baseURL = "https://hugo-test.c3re.de/master/"
|
||||
languageCode = "en-us"
|
||||
title = "c3RE"
|
||||
theme = "hugo-theme-flat"
|
||||
# themeDir = '../..'
|
||||
defaultContentLanguage = "de"
|
||||
relativeURLs = true
|
||||
#style = "pink"
|
||||
|
||||
# Hauptmenue
|
||||
[[menus.main]]
|
||||
name = "Hallo beim c3RE"
|
||||
url = "/hallo"
|
||||
weight = 30
|
||||
[[menus.main]]
|
||||
parent = "Hallo beim c3RE"
|
||||
name = "Sommerfest"
|
||||
url = "#"
|
||||
[[menus.main]]
|
||||
parent = "Hallo beim c3RE"
|
||||
name = "Philosophie"
|
||||
url = "#"
|
||||
[[menus.main]]
|
||||
parent = "Hallo beim c3RE"
|
||||
name = "Codeweek"
|
||||
url = "#"
|
||||
|
||||
[[menus.main]]
|
||||
name = "Über uns"
|
||||
url = "/about/"
|
||||
weight = 50
|
||||
|
||||
[[menus.main]]
|
||||
name = "Gallery"
|
||||
url = "/gallery/"
|
||||
weight = 70
|
||||
|
||||
[[menus.main]]
|
||||
name = "Werkzeuge"
|
||||
url = "/tools/"
|
||||
weight = 90
|
||||
|
||||
[[menus.main]]
|
||||
name = "Downloads"
|
||||
url = "/about/"
|
||||
weight = 110
|
||||
|
||||
# Footer Menue
|
||||
[[params.footer_rows]]
|
||||
[[params.footer_rows.items]]
|
||||
name = "Kontakt"
|
||||
url = "/kontakt"
|
||||
|
||||
[[params.footer_rows]]
|
||||
[[params.footer_rows.items]]
|
||||
name = "Impressum"
|
||||
url = "/impressum"
|
||||
|
||||
[[params.footer_rows.items]]
|
||||
name = "Datenschutzerklärung"
|
||||
url = "/datenschutz"
|
||||
|
||||
|
|
|
@ -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.
|
|
@ -0,0 +1,39 @@
|
|||
# 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.
|
||||
|
||||
The hugo theme [jane](https://github.com/xianmin/hugo-theme-jane) and [mini](https://github.com/nodejh/hugo-theme-mini/), this is my first time to write a hugo theme, I referred this two themes' project structure and way of handling problems.
|
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
title: "{{ replace .Name "-" " " | title }}"
|
||||
date: {{ .Date }}
|
||||
tags: []
|
||||
categories: []
|
||||
weight: 50
|
||||
show_comments: true
|
||||
katex: false
|
||||
draft: true
|
||||
description: ""
|
||||
---
|
||||
|
||||
<!--more-->
|
|
@ -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 = "#"
|
|
@ -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).
|
||||
|
|
@ -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 world’s 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)
|
|
@ -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 |
|
@ -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 |
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
title: "Posts"
|
||||
date: 2022-05-18T11:22:44+08:00
|
||||
tags: []
|
||||
categories: []
|
||||
weight: 30
|
||||
draft: false
|
||||
---
|
||||
|
||||
<!--more-->
|
|
@ -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 >}}
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
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}
|
||||
$$
|
||||
```
|
|
@ -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.
|
|
@ -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} } }
|
||||
$$
|
|
@ -0,0 +1,91 @@
|
|||
---
|
||||
title: "My First Post"
|
||||
date: 2023-04-17T20:28:56+02:00
|
||||
draft: false
|
||||
---
|
||||
|
||||
# Maschinenraum - Hands-On Server
|
||||
|
||||
## backlog
|
||||
|
||||
- iCal Tool Dirk auf einen WAU portieren
|
||||
- SSL Certs in der lokalen Infrastruktur
|
||||
|
||||
## 08.05.2023
|
||||
|
||||
- GIT -> Was ist das und wie geht das?
|
||||
- Static Website ?! Hugo ?
|
||||
- ssh://git@git.c3re.de:2222/noc/test-website.git
|
||||
|
||||
## 17.04.2023
|
||||
|
||||
- GIT -> Was ist das und wie geht das?
|
||||
- Static Website ?! Hugo ?
|
||||
- ssh://git@git.c3re.de:2222/noc/test-website.git
|
||||
- Minetest Server
|
||||
|
||||
## 20.03.2023
|
||||
|
||||
- Kalender Plugin Wordpress -> selber gebaut
|
||||
- Traefik Basics
|
||||
|
||||
## 13.02.2023
|
||||
|
||||
- aktuell Probleme unserer Infrastruktur
|
||||
- Backup mit restic
|
||||
- was und wie funktioniert die storagebox
|
||||
- keys und wofür welche und warum
|
||||
- Themensammlung konkreter Kursthemen
|
||||
|
||||
## 09.01.2023
|
||||
|
||||
- Auftakt zur neuen Workshop Reihe
|
||||
- Sachstand eigene Infra
|
||||
- Bitwarden
|
||||
- Hüttenstatus auf Homepage -> Anpassung SpaceAPI
|
||||
- uvm
|
||||
|
||||
## Themensammlung
|
||||
|
||||
- GIT -> Was ist das und wie geht das?
|
||||
- statische Webseiten bauen über z.B. Hugo, Jekyll, etc.
|
||||
- unsere Docker-Compose Infra mit Git verwalten
|
||||
- Monitoring mit Grafana und Prometheus
|
||||
- Logfiles -> Sammeln, Auswerten und Bewerten
|
||||
- alternative Loginvarianten (alternative zum PW)
|
||||
- zentrale Benutzerverwaltung für alle Dienste z.B. Authentic
|
||||
- Kubernetes
|
||||
|
||||
- Mailman -> Zukunft, Upgrade was anderes oder Extern
|
||||
- eigener GPS gestützter öffentlicher Zeitserver -> Workshop? Hardware bauen, Software usw.
|
||||
|
||||
- Themenabende zum lernen wie z.B. Regex, Node-RD JS flows usw. aber eher Hands-on, einer erklärt die anderen machen mit
|
||||
|
||||
- Bitwarden/Vaultwarden -> Talk/Workshop?!
|
||||
|
||||
## pad
|
||||
<https://pads.c3re.de/c3redocker>
|
||||
|
||||
## man müsste Mal/Ideensammlung
|
||||
|
||||
www.keycloak.org <https://goauthentik.io/>
|
||||
nginxproxymanager.com
|
||||
www.cockpit-project.org
|
||||
snibox.github.io
|
||||
<https://github.com/philippe44/AirConnect>
|
||||
k3s
|
||||
photoprism
|
||||
<https://jellyfin.org/>
|
||||
link shortener
|
||||
syncthing
|
||||
logfiles
|
||||
Pterodactyl
|
||||
<https://openspeedtest.com/>
|
||||
<https://www.navidrome.org/>
|
||||
<https://jupyter.org/>
|
||||
chronyd ->
|
||||
<https://zoneminder.com/> -> vll was für die Zeche
|
||||
<https://vikunja.io/> - To-Do App
|
||||
mailjet
|
||||
|
||||
* Hugo
|
|
@ -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 >}}
|
|
@ -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 >}}
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: "Second Post"
|
||||
date: 2023-12-13T22:05:57+01:00
|
||||
draft: true
|
||||
---
|
||||
|
|
@ -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
|
||||
```
|
Binary file not shown.
After Width: | Height: | Size: 360 KiB |
Binary file not shown.
After Width: | Height: | Size: 90 KiB |
|
@ -0,0 +1,4 @@
|
|||
<div class="mermaid">
|
||||
{{- .Inner | safeHTML }}
|
||||
</div>
|
||||
{{ .Page.Store.Set "hasMermaid" true }}
|
|
@ -0,0 +1 @@
|
|||
<h{{ .Level }} id="{{ .Anchor | safeURL }}">{{ .Text | safeHTML }} <a href="#{{ .Anchor | safeURL }}" class="anchor">🔗</a></h{{ .Level }}>
|
|
@ -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>
|
|
@ -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 }}
|
|
@ -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>
|
|
@ -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 }}
|
|
@ -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 }}
|
|
@ -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 }}
|
|
@ -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 }}
|
|
@ -0,0 +1 @@
|
|||
<div class="commenting" id="remark42"></div>
|
|
@ -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>
|
|
@ -0,0 +1,79 @@
|
|||
<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.body);"></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 }}" />
|
||||
<link rel="shortcut icon" href="{{ "images/favicon.ico" | relURL }}" type="image/x-icon" />
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -0,0 +1,4 @@
|
|||
User-agent: *
|
||||
Allow: *
|
||||
|
||||
Sitemap: {{ .Site.BaseURL }}sitemap.xml
|
|
@ -0,0 +1,710 @@
|
|||
/* 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 { padding: 7px; }
|
||||
|
||||
.content pre code {
|
||||
display: block;
|
||||
|
||||
padding: var(--len-3);
|
||||
|
||||
border: none;
|
||||
background-color: var(--color-bg-block);
|
||||
border-radius: 3px;
|
||||
|
||||
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 {
|
||||
padding: 7px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
max-width: 100%;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
/**************************/
|
||||
/* 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%;
|
||||
}
|
||||
|
||||
/* keep content style from being affected by remark42 style */
|
||||
.content pre {
|
||||
background-color: transparent;
|
||||
color: var(--color-fg-font-normal)
|
||||
}
|
||||
|
||||
/**********/
|
||||
/** misc **/
|
||||
/**********/
|
||||
|
||||
.archive-hint {
|
||||
padding-left: var(--len-4);
|
||||
color: var(--color-fg-font-quote);
|
||||
}
|
||||
|
||||
.max-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
|
@ -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 { }
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -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.
|
@ -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="" 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.
|
@ -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;
|
||||
}
|
||||
|
|
@ -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}
|
|
@ -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).
|
|
@ -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__;
|
||||
/******/ })()
|
||||
;
|
||||
});
|
|
@ -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}()}));
|
|
@ -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 };
|
|
@ -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__;
|
||||
/******/ })()
|
||||
;
|
||||
});
|
|
@ -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}()}));
|
|
@ -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();
|
||||
});
|
|
@ -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__;
|
||||
/******/ })()
|
||||
;
|
||||
});
|
|
@ -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}()}));
|
|
@ -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
|
@ -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
|
@ -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
Loading…
Reference in New Issue