mirror of
https://github.com/cotes2020/jekyll-theme-chirpy.git
synced 2025-12-18 21:53:26 +00:00
Compare commits
191 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
388c1511d6 | ||
|
|
8849afe5cf | ||
|
|
89b962557a | ||
|
|
5de0153df4 | ||
|
|
ed4d304cd2 | ||
|
|
48564bda8d | ||
|
|
b9d053b3cd | ||
|
|
cd258c92c3 | ||
|
|
6230d1d750 | ||
|
|
365abc6b3b | ||
|
|
79c65b3e44 | ||
|
|
6b34901d94 | ||
|
|
90693ff95e | ||
|
|
1a01c35e52 | ||
|
|
c335bc6ce7 | ||
|
|
f3ea7e9887 | ||
|
|
c13ec31163 | ||
|
|
bbbb66b489 | ||
|
|
74f16623c9 | ||
|
|
1127c43823 | ||
|
|
ea3a22e13c | ||
|
|
c0018b66f3 | ||
|
|
02e296ed75 | ||
|
|
4facf5b390 | ||
|
|
c5d11441bc | ||
|
|
96bdd7c1dd | ||
|
|
ba764c1380 | ||
|
|
c7cfde0930 | ||
|
|
13177979bb | ||
|
|
6a17a7d46c | ||
|
|
8c30b41e20 | ||
|
|
b2d1cb68db | ||
|
|
3589a6ee53 | ||
|
|
7efbed6a24 | ||
|
|
21d74f1183 | ||
|
|
d6d0098379 | ||
|
|
241bb4df78 | ||
|
|
82d8f2db98 | ||
|
|
9882244bd9 | ||
|
|
f243cbd858 | ||
|
|
d420b38329 | ||
|
|
ea2d238bd8 | ||
|
|
5234511a2f | ||
|
|
746a31e125 | ||
|
|
c45e031155 | ||
|
|
4a2b89d0b6 | ||
|
|
2a4fbf6a79 | ||
|
|
84ea68cab0 | ||
|
|
3ed5eb1ee0 | ||
|
|
60836af606 | ||
|
|
739345ac24 | ||
|
|
1a977a87a0 | ||
|
|
d1a5b57e4d | ||
|
|
2b9d379d70 | ||
|
|
bdee5d6b6d | ||
|
|
348f6bff8b | ||
|
|
7a3d624364 | ||
|
|
06f1c6f256 | ||
|
|
4a7f33f7bb | ||
|
|
e077d2911d | ||
|
|
5f2edb0914 | ||
|
|
911206be80 | ||
|
|
18808851a9 | ||
|
|
2bf87e0de7 | ||
|
|
f6d96ab2b8 | ||
|
|
59c55121c7 | ||
|
|
9f174d9088 | ||
|
|
5810bcd1d7 | ||
|
|
897b57bfb4 | ||
|
|
fd83462ea4 | ||
|
|
fa8a2a0ada | ||
|
|
7b7e69a44d | ||
|
|
e6e2984e77 | ||
|
|
d71711d2d3 | ||
|
|
50835b4c71 | ||
|
|
575dc87d83 | ||
|
|
753cd0499d | ||
|
|
b7e9f3ec34 | ||
|
|
42bf39e21c | ||
|
|
45c2a18884 | ||
|
|
3fd3c571b5 | ||
|
|
2574118f40 | ||
|
|
0e2d593b00 | ||
|
|
2bc3172444 | ||
|
|
55659315c6 | ||
|
|
bbd92d11cc | ||
|
|
475d181aac | ||
|
|
f49155f034 | ||
|
|
109725d2dc | ||
|
|
e3b01636ac | ||
|
|
b489da89ca | ||
|
|
2d56597571 | ||
|
|
97004ddc44 | ||
|
|
75ea77d574 | ||
|
|
bf3a34d054 | ||
|
|
5015fdecf3 | ||
|
|
de2dff354a | ||
|
|
3a022bc816 | ||
|
|
9b74070d45 | ||
|
|
af4102476e | ||
|
|
9d9e3bbca3 | ||
|
|
6f2d3ea2bd | ||
|
|
8417927264 | ||
|
|
ca39e15a78 | ||
|
|
e9c920641b | ||
|
|
0a55e1297b | ||
|
|
0465a985dc | ||
|
|
73e171b0fb | ||
|
|
726085c647 | ||
|
|
b97fa93ffd | ||
|
|
13a3c3c906 | ||
|
|
e78f67d354 | ||
|
|
b34661efd7 | ||
|
|
bb589e8d31 | ||
|
|
f079bb7f5b | ||
|
|
ac4b402f97 | ||
|
|
87a12be897 | ||
|
|
0614473893 | ||
|
|
273b389c51 | ||
|
|
204cb44dc3 | ||
|
|
f949bda15b | ||
|
|
b3005f4e1a | ||
|
|
14d3960ca0 | ||
|
|
4da7406dfe | ||
|
|
1a041e0443 | ||
|
|
7ec8425e03 | ||
|
|
52084f85d4 | ||
|
|
5c6df66324 | ||
|
|
3f9f5c79e8 | ||
|
|
aff7566774 | ||
|
|
4237d078fa | ||
|
|
806fa3aa1a | ||
|
|
ec69bea841 | ||
|
|
75a2504fd9 | ||
|
|
8542b57e8b | ||
|
|
ed9bda022d | ||
|
|
25a27056e0 | ||
|
|
a069960439 | ||
|
|
c574166b51 | ||
|
|
ff87349fe7 | ||
|
|
505e314a31 | ||
|
|
41b8f9f519 | ||
|
|
62bcd601fc | ||
|
|
414b8f97ce | ||
|
|
229c2a2e2b | ||
|
|
c4af75389a | ||
|
|
4f86b04a84 | ||
|
|
2a5c184373 | ||
|
|
7b43a83c40 | ||
|
|
f659109de2 | ||
|
|
b39c6b526c | ||
|
|
7819fd0843 | ||
|
|
ba397a21aa | ||
|
|
0d4103d47b | ||
|
|
54e1dbe325 | ||
|
|
37c976499e | ||
|
|
0fd4c0bd0f | ||
|
|
0da2f80dd4 | ||
|
|
e8ef69ad17 | ||
|
|
2eb4267cdd | ||
|
|
e4e76f0a11 | ||
|
|
e07e6d46d7 | ||
|
|
2bbfda79ad | ||
|
|
b0f4ae5eec | ||
|
|
8b0fbf5a83 | ||
|
|
2639f8ed45 | ||
|
|
926d1ca068 | ||
|
|
df8ff546ec | ||
|
|
c075e11a4e | ||
|
|
b6d1992f85 | ||
|
|
74ab6f8adc | ||
|
|
4fe145e980 | ||
|
|
a60e90791d | ||
|
|
fa3257873e | ||
|
|
1682ce9d7c | ||
|
|
29a8bc26bc | ||
|
|
83625644ea | ||
|
|
728094d1ba | ||
|
|
ce2f6f5abe | ||
|
|
c4da99c7ea | ||
|
|
73af59194a | ||
|
|
f6bf6d0864 | ||
|
|
bef2ac085e | ||
|
|
7c9fa68331 | ||
|
|
066c1cd039 | ||
|
|
98850e1e5d | ||
|
|
83eecdabcb | ||
|
|
a51d31c55a | ||
|
|
eb40f51c84 | ||
|
|
3bd881da70 | ||
|
|
aba9468b53 |
@@ -1,5 +0,0 @@
|
||||
# https://github.com/browserslist/browserslist#browserslistrc
|
||||
|
||||
last 2 versions
|
||||
> 0.2%
|
||||
not dead
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"rules": {
|
||||
"body-max-line-length": [
|
||||
0,
|
||||
"always"
|
||||
]
|
||||
}
|
||||
}
|
||||
55
.github/CONTRIBUTING.md
vendored
55
.github/CONTRIBUTING.md
vendored
@@ -1,55 +0,0 @@
|
||||
# How to Contribute
|
||||
|
||||
:tada: We really appreciate you taking the time to improve this project! :tada:
|
||||
|
||||
To ensure that the blog design is not confusing, this project does not accept
|
||||
suggestions for design changes, such as color scheme, fonts, typography, etc.
|
||||
If your request is about an enhancement, it is recommended to first submit a
|
||||
[Feature Request][pr-issue] issue to discuss whether your idea fits the project.
|
||||
|
||||
Basically, you can follow these steps to complete the contribution.
|
||||
|
||||
1. Fork this project on GitHub and clone it locally.
|
||||
2. Create a new branch from the default branch and give it a descriptive name
|
||||
(format: `feature/<add-new-feat>` or `fix/<fix-a-bug>`).
|
||||
3. After completing development, create a [Conventional Commit][cc] with git.
|
||||
(See also: ["Verify the commits"](#verify-the-commits))
|
||||
4. Create a [Pull Request][gh-pr].
|
||||
|
||||
## Make sure you can pass the CI tests
|
||||
|
||||
This project has [CI][ci] turned on. In order for your [PR][gh-pr] to pass the test,
|
||||
please read the following.
|
||||
|
||||
### Check the core functionality
|
||||
|
||||
```console
|
||||
bash ./tools/test
|
||||
```
|
||||
|
||||
### Check the SASS syntax style
|
||||
|
||||
```console
|
||||
npm test
|
||||
```
|
||||
|
||||
### Verify the commits
|
||||
|
||||
Before you create a git commit, please complete the following setup.
|
||||
|
||||
Install `commitlint` & `husky`:
|
||||
|
||||
```console
|
||||
npm i -g @commitlint/{cli,config-conventional} husky
|
||||
```
|
||||
|
||||
And then enable `husky`:
|
||||
|
||||
```console
|
||||
husky install
|
||||
```
|
||||
|
||||
[pr-issue]: https://github.com/cotes2020/jekyll-theme-chirpy/issues/new?labels=enhancement&template=feature_request.md
|
||||
[gh-pr]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests
|
||||
[cc]: https://www.conventionalcommits.org/
|
||||
[ci]: https://en.wikipedia.org/wiki/Continuous_integration
|
||||
26
.github/DISCUSSION_TEMPLATE/general.yml
vendored
Normal file
26
.github/DISCUSSION_TEMPLATE/general.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Checklist
|
||||
description: Following the guidelines can make you more likely to get responses.
|
||||
options:
|
||||
- label: >-
|
||||
I have read and accepted the
|
||||
[contributing guidelines](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/docs/CONTRIBUTING.md).
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: What is the topic?
|
||||
options:
|
||||
- Sharing tips and tricks
|
||||
- Just chatting
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Description
|
||||
description: Please describe in detail what you want to share.
|
||||
validations:
|
||||
required: true
|
||||
40
.github/DISCUSSION_TEMPLATE/q-a.yml
vendored
Normal file
40
.github/DISCUSSION_TEMPLATE/q-a.yml
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Checklist
|
||||
description: Following the guidelines can make you more likely to get responses.
|
||||
options:
|
||||
- label: >-
|
||||
I have read and accepted the
|
||||
[contributing guidelines](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/docs/CONTRIBUTING.md).
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: download
|
||||
attributes:
|
||||
label: How did you create the site?
|
||||
options:
|
||||
- Generated from `chirpy-starter`
|
||||
- Built from `jekyll-theme-chirpy`
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Description
|
||||
description: Please describe your need in detail.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Operations you have already tried
|
||||
description: Describe the effort you went through.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Anything else?
|
||||
description: |
|
||||
Links? References? Or logs? Anything that will give us more context about the issue you are encountering!
|
||||
68
.github/ISSUE_TEMPLATE/bug_report.md
vendored
68
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,68 +0,0 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Create a report to help us improve
|
||||
---
|
||||
|
||||
**NOTE:** Before you start, the following should be completed.
|
||||
|
||||
- Read [Wiki][wiki] to understand the usage and the correct effect of functional design.
|
||||
- Make sure no [similar issue(including closed ones)][issues] exists.
|
||||
- Make sure the bug is found in the latest code of the `master` branch.
|
||||
|
||||
[wiki]: https://github.com/cotes2020/jekyll-theme-chirpy/wiki
|
||||
[issues]: https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue
|
||||
|
||||
## Describe the bug
|
||||
|
||||
<!-- A clear and concise description of what the bug is. -->
|
||||
|
||||
## To Reproduce
|
||||
|
||||
Steps to reproduce the behavior:
|
||||
<!--
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
-->
|
||||
|
||||
## Expected behavior
|
||||
|
||||
<!-- A clear and concise description of what you expected to happen. -->
|
||||
|
||||
## Logs/Screenshots
|
||||
|
||||
<!-- If applicable, add logs/screenshots to help explain your problem. -->
|
||||
|
||||
## Environment
|
||||
|
||||
| Command | Version |
|
||||
|-----------------------------------|---------|
|
||||
| `ruby -v` | |
|
||||
| `gem -v` | |
|
||||
| `bundle -v` | |
|
||||
| `bundle exec jekyll -v` | |
|
||||
| `bundle info jekyll-theme-chirpy` | |
|
||||
|
||||
<!-- If necessary, uncomment and fill in the following list:
|
||||
|
||||
### Desktop
|
||||
|
||||
- OS: [e.g. macOS 10.15.6]
|
||||
- Browser: [e.g. Chrome 85.0.4183.83 (64-bit)]
|
||||
|
||||
-->
|
||||
|
||||
<!-- If necessary, uncomment and fill in the following list:
|
||||
|
||||
### Smartphone
|
||||
|
||||
- Device: [e.g. iPhone 6]
|
||||
- OS: [e.g. iOS 13.6.1]
|
||||
- Browser: [e.g. Chrome 22]
|
||||
|
||||
-->
|
||||
|
||||
## Additional context
|
||||
|
||||
<!-- Add any other context about the problem here. -->
|
||||
64
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
64
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
name: Bug Report
|
||||
description: Create a report to help us improve
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Checklist
|
||||
description: Following the guidelines can make you more likely to get responses.
|
||||
options:
|
||||
- label: >-
|
||||
I have read and accepted the
|
||||
[contributing guidelines](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/docs/CONTRIBUTING.md).
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: download
|
||||
attributes:
|
||||
label: How did you create the site?
|
||||
options:
|
||||
- Generated from `chirpy-starter`
|
||||
- Built from `jekyll-theme-chirpy`
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: A clear and concise description of what the bug is.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps To Reproduce
|
||||
description: Steps to reproduce the behavior.
|
||||
placeholder: |
|
||||
1. In this environment...
|
||||
2. With this config...
|
||||
3. Run '...'
|
||||
4. See error...
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: A concise description of what you expected to happen.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Environment
|
||||
value: |
|
||||
- Ruby: <!-- run `ruby -v` -->
|
||||
- Jekyll: <!-- run `bundle exec jekyll -v` -->
|
||||
- Chirpy: <!-- run `bundle info jekyll-theme-chirpy` -->
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Anything else?
|
||||
description: |
|
||||
Links? References? Or logs? Anything that will give us more context about the issue you are encountering!
|
||||
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Ask the community for help
|
||||
url: https://github.com/cotes2020/jekyll-theme-chirpy/discussions
|
||||
about: Please ask and answer questions here.
|
||||
33
.github/ISSUE_TEMPLATE/feature_request.md
vendored
33
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,33 +0,0 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: Suggest an idea for this project
|
||||
labels: enhancement
|
||||
---
|
||||
|
||||
**NOTE:** Before you start, the following should be completed.
|
||||
|
||||
- Read [Wiki][wiki] to understand the usage and the correct effect of functional design.
|
||||
- Make sure no [similar issue(including closed ones)][issues] exists.
|
||||
- Make sure the request is based on the latest code in the `master` branch.
|
||||
|
||||
[wiki]: https://github.com/cotes2020/jekyll-theme-chirpy/wiki
|
||||
[issues]: https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue
|
||||
|
||||
## Is your feature request related to a problem? Please describe
|
||||
|
||||
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
|
||||
|
||||
|
||||
## Describe the solution you'd like
|
||||
|
||||
<!-- A clear and concise description of what you want to happen. -->
|
||||
|
||||
|
||||
## Describe alternatives you've considered
|
||||
|
||||
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
|
||||
|
||||
|
||||
## Additional context
|
||||
|
||||
<!-- Add any other context or screenshots about the feature request here. -->
|
||||
38
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
38
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
name: Feature Request
|
||||
description: Suggest an idea for this project
|
||||
labels:
|
||||
- enhancement
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Checklist
|
||||
description: Following the guidelines can make you more likely to get responses.
|
||||
options:
|
||||
- label: >-
|
||||
I have read and accepted the
|
||||
[contributing guidelines](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/docs/CONTRIBUTING.md).
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Is your feature request related to a problem? Please describe
|
||||
description: A clear and concise description of what the problem is.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the solution you'd like
|
||||
description: A clear and concise description of what you want to happen.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe alternatives you've considered
|
||||
description: A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context or screenshots about the feature request here.
|
||||
28
.github/ISSUE_TEMPLATE/help_wanted.md
vendored
28
.github/ISSUE_TEMPLATE/help_wanted.md
vendored
@@ -1,28 +0,0 @@
|
||||
---
|
||||
name: Help Wanted
|
||||
about: Need help that is not covered in the tutorial
|
||||
labels: 'help wanted'
|
||||
---
|
||||
|
||||
**NOTE:** Before you start, the following should be completed.
|
||||
|
||||
- Read [Wiki][wiki] to understand the usage and the correct effect of functional design.
|
||||
- Make sure no [similar issue(including closed ones)][issues] exists.
|
||||
- Try to find the answer on [Jekyll Forum][forum] and [StackOverflow][stack_overflow].
|
||||
|
||||
[wiki]: https://github.com/cotes2020/jekyll-theme-chirpy/wiki
|
||||
[issues]: https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue
|
||||
[forum]: https://talk.jekyllrb.com/
|
||||
[stack_overflow]: https://stackoverflow.com/questions/tagged/jekyll
|
||||
|
||||
## Description
|
||||
|
||||
<!-- Please describe your need in detail. -->
|
||||
|
||||
## Operations you have already tried
|
||||
|
||||
<!-- Describe the effort you went through. -->
|
||||
|
||||
## Logs/Screenshots
|
||||
|
||||
<!-- If applicable, add logs/screenshots to help explain your problem. -->
|
||||
20
.github/ISSUE_TEMPLATE/question.md
vendored
20
.github/ISSUE_TEMPLATE/question.md
vendored
@@ -1,20 +0,0 @@
|
||||
---
|
||||
name: Question
|
||||
about: Issues that differ from other templates
|
||||
labels: question
|
||||
---
|
||||
|
||||
**NOTE:** Before you start, the following should be completed.
|
||||
|
||||
- Read [Wiki][wiki] to understand the usage and the correct effect of functional design.
|
||||
- Make sure no [similar issue(including closed ones)][issues] exists.
|
||||
- Try to find the answer on [Jekyll Forum][forum] and [StackOverflow][stack_overflow].
|
||||
|
||||
[wiki]: https://github.com/cotes2020/jekyll-theme-chirpy/wiki
|
||||
[issues]: https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue
|
||||
[forum]: https://talk.jekyllrb.com/
|
||||
[stack_overflow]: https://stackoverflow.com/questions/tagged/jekyll
|
||||
|
||||
## Description
|
||||
|
||||
<!-- Please describe your question in detail. -->
|
||||
26
.github/PULL_REQUEST_TEMPLATE.md
vendored
26
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,29 +1,17 @@
|
||||
## Description
|
||||
|
||||
<!--
|
||||
Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
|
||||
-->
|
||||
|
||||
## Type of change
|
||||
|
||||
<!--
|
||||
Please select the desired item checkbox and change it to "[x]", then delete options that are not relevant.
|
||||
-->
|
||||
<!-- Please select the desired item checkbox and change it from `[ ]` to `[x]` and then delete the irrelevant options. -->
|
||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
- [ ] Improvement (refactoring and improving code)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||
- [ ] Documentation update
|
||||
|
||||
## Additional context
|
||||
|
||||
<!-- e.g. Fixes #(issue) -->
|
||||
|
||||
## How has this been tested
|
||||
|
||||
## Description
|
||||
<!--
|
||||
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
|
||||
Please include a summary of the change and which issue is fixed.
|
||||
Please also include relevant motivation and context.
|
||||
List any dependencies that are required for this change.
|
||||
-->
|
||||
|
||||
- [ ] I have run `bash ./tools/test` (at the root of the project) locally and passed
|
||||
- [ ] I have tested this feature in the browser
|
||||
## Additional context
|
||||
<!-- e.g. Fixes #(issue) -->
|
||||
|
||||
12
.github/SECURITY.md
vendored
12
.github/SECURITY.md
vendored
@@ -1,12 +0,0 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
| Version | Supported |
|
||||
|---------| ------------------ |
|
||||
| 5.x | :white_check_mark: |
|
||||
| < 5.0.0 | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you find a vulnerability, please report it to `cotes.chung@gmail.com`. We will try our best to respond within a week. Thank you for your time!
|
||||
2
.github/codeql/codeql-config.yml
vendored
Normal file
2
.github/codeql/codeql-config.yml
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
paths-ignore:
|
||||
- "assets/js"
|
||||
26
.github/dependabot.yml
vendored
Normal file
26
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "bundler"
|
||||
directory: "/"
|
||||
versioning-strategy: increase
|
||||
groups:
|
||||
bundler:
|
||||
dependency-type: "production"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/"
|
||||
versioning-strategy: increase
|
||||
groups:
|
||||
npm:
|
||||
dependency-type: "development"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
groups:
|
||||
gh-actions:
|
||||
update-types:
|
||||
- "major"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
17
.github/stale.yml
vendored
17
.github/stale.yml
vendored
@@ -1,17 +0,0 @@
|
||||
# Clean up the stale issues
|
||||
|
||||
daysUntilStale: 30
|
||||
daysUntilClose: 1
|
||||
|
||||
exemptLabels:
|
||||
- in progress
|
||||
- pending
|
||||
|
||||
staleLabel: stale
|
||||
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
|
||||
closeComment: false
|
||||
5
.github/workflows/cd.yml
vendored
5
.github/workflows/cd.yml
vendored
@@ -1,7 +1,10 @@
|
||||
name: CD
|
||||
on:
|
||||
push:
|
||||
branches: [production, docs]
|
||||
tags:
|
||||
- "v[0-9]+.[0-9]+.[0-9]+"
|
||||
branches:
|
||||
- docs
|
||||
|
||||
jobs:
|
||||
launch:
|
||||
|
||||
7
.github/workflows/ci.yml
vendored
7
.github/workflows/ci.yml
vendored
@@ -8,6 +8,7 @@ on:
|
||||
- ".github/**"
|
||||
- "!.github/workflows/ci.yml"
|
||||
- ".gitignore"
|
||||
- "docs/**"
|
||||
- "README.md"
|
||||
- "LICENSE"
|
||||
pull_request:
|
||||
@@ -20,11 +21,11 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
ruby: [2.7, 3]
|
||||
ruby: ["3.0", "3.1", "3.2"]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # for posts's lastmod
|
||||
|
||||
@@ -35,7 +36,7 @@ jobs:
|
||||
bundler-cache: true
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@v4
|
||||
|
||||
- name: Build Assets
|
||||
run: npm i && npm run build
|
||||
|
||||
15
.github/workflows/codeql.yml
vendored
15
.github/workflows/codeql.yml
vendored
@@ -2,11 +2,9 @@ name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
paths: ["**.js"]
|
||||
paths: ["_javascript/**/*.js"]
|
||||
pull_request:
|
||||
paths: ["**.js"]
|
||||
schedule:
|
||||
- cron: "0 0 * * 5"
|
||||
paths: ["_javascript/**/*.js"]
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
@@ -25,20 +23,21 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: "${{ matrix.language }}"
|
||||
config-file: .github/codeql/codeql-config.yml
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{ matrix.language }}"
|
||||
|
||||
2
.github/workflows/commitlint.yml
vendored
2
.github/workflows/commitlint.yml
vendored
@@ -5,7 +5,7 @@ jobs:
|
||||
commitlint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: wagoid/commitlint-github-action@v5
|
||||
|
||||
14
.github/workflows/pages-deploy.yml.hook
vendored
14
.github/workflows/pages-deploy.yml.hook
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
# submodules: true
|
||||
@@ -37,12 +37,12 @@ jobs:
|
||||
|
||||
- name: Setup Pages
|
||||
id: pages
|
||||
uses: actions/configure-pages@v3
|
||||
uses: actions/configure-pages@v4
|
||||
|
||||
- name: Setup Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 3 # reads from a '.ruby-version' or '.tools-version' file if 'ruby-version' is omitted
|
||||
ruby-version: 3.2
|
||||
bundler-cache: true
|
||||
|
||||
- name: Build site
|
||||
@@ -52,10 +52,12 @@ jobs:
|
||||
|
||||
- name: Test site
|
||||
run: |
|
||||
bundle exec htmlproofer _site --disable-external --check-html --allow_hash_href
|
||||
bundle exec htmlproofer _site \
|
||||
\-\-disable-external=true \
|
||||
\-\-ignore-urls "/^http:\/\/127.0.0.1/,/^http:\/\/0.0.0.0/,/^http:\/\/localhost/"
|
||||
|
||||
- name: Upload site artifact
|
||||
uses: actions/upload-pages-artifact@v1
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: "_site${{ steps.pages.outputs.base_path }}"
|
||||
|
||||
@@ -68,4 +70,4 @@ jobs:
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v1
|
||||
uses: actions/deploy-pages@v4
|
||||
|
||||
32
.github/workflows/stale.yml
vendored
Normal file
32
.github/workflows/stale.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
name: "Close stale issues and PRs"
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *" # every day at 00:00 UTC
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
env:
|
||||
STALE_LABEL: stale
|
||||
EXEMPT_LABELS: "pending,planning,in progress"
|
||||
MESSAGE: >
|
||||
This conversation has been automatically marked as stale because it has not had recent activity.
|
||||
It will be closed if no further activity occurs.
|
||||
Thank you for your contributions.
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
# 60 days before marking issues/PRs stale
|
||||
days-before-close: -1 # does not close automatically
|
||||
stale-issue-label: ${{ env.STALE_LABEL }}
|
||||
exempt-issue-labels: ${{ env.EXEMPT_LABELS }}
|
||||
stale-issue-message: ${{ env.MESSAGE }}
|
||||
stale-pr-label: ${{ env.STALE_LABEL }}
|
||||
exempt-pr-labels: ${{ env.EXEMPT_LABELS }}
|
||||
stale-pr-message: ${{ env.MESSAGE }}
|
||||
4
.github/workflows/style-lint.yml
vendored
4
.github/workflows/style-lint.yml
vendored
@@ -17,9 +17,9 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@v4
|
||||
- run: npm i
|
||||
- run: npm test
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -16,7 +16,6 @@ package-lock.json
|
||||
|
||||
# IDE configurations
|
||||
.idea
|
||||
.vscode
|
||||
|
||||
# Misc
|
||||
assets/js/dist
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx --no -- commitlint -x $(npm root -g)/@commitlint/config-conventional --edit
|
||||
npx --no -- commitlint --edit ${1}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"trailingComma": "none"
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"extends": "stylelint-config-standard-scss",
|
||||
"rules": {
|
||||
"no-descending-specificity": null,
|
||||
"shorthand-property-no-redundant-values": null,
|
||||
"at-rule-no-vendor-prefix": null,
|
||||
"property-no-vendor-prefix": null,
|
||||
"selector-no-vendor-prefix": null,
|
||||
"value-no-vendor-prefix": null,
|
||||
"color-function-notation": "legacy",
|
||||
"alpha-value-notation": "number",
|
||||
"selector-not-notation": "simple",
|
||||
"color-hex-length": "long",
|
||||
"declaration-block-single-line-max-declarations": 3,
|
||||
"scss/operator-no-newline-after": null,
|
||||
"rule-empty-line-before": [
|
||||
"always",
|
||||
{ "ignore": ["after-comment", "first-nested", "inside-block"] }
|
||||
],
|
||||
"value-keyword-case": ["lower", { "ignoreProperties": ["/^\\$/"] }]
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"skip": {
|
||||
"commit": true,
|
||||
"tag": true
|
||||
},
|
||||
"types": [
|
||||
{
|
||||
"type": "feat",
|
||||
"section": "Features"
|
||||
},
|
||||
{
|
||||
"type": "fix",
|
||||
"section": "Bug Fixes"
|
||||
},
|
||||
{
|
||||
"type": "perf",
|
||||
"section": "Improvements"
|
||||
}
|
||||
]
|
||||
}
|
||||
12
.vscode/extensions.json
vendored
Normal file
12
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"recommendations": [
|
||||
// Liquid tags auto-complete
|
||||
"killalau.vscode-liquid-snippets",
|
||||
// Liquid syntax highlighting and formatting
|
||||
"Shopify.theme-check-vscode",
|
||||
// Common formatter
|
||||
"esbenp.prettier-vscode",
|
||||
"foxundermoon.shell-format",
|
||||
"stylelint.vscode-stylelint"
|
||||
]
|
||||
}
|
||||
24
.vscode/settings.json
vendored
Normal file
24
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
// Prettier
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"prettier.trailingComma": "none",
|
||||
// Shopify Liquid
|
||||
"files.associations": {
|
||||
"*.html": "liquid"
|
||||
},
|
||||
// Formatter
|
||||
"[html][liquid]": {
|
||||
"editor.defaultFormatter": "Shopify.theme-check-vscode"
|
||||
},
|
||||
"[shellscript]": {
|
||||
"editor.defaultFormatter": "foxundermoon.shell-format"
|
||||
},
|
||||
// Disable vscode built-in stylelint
|
||||
"css.validate": false,
|
||||
"scss.validate": false,
|
||||
"less.validate": false,
|
||||
// Stylint extension settings
|
||||
"stylelint.snippet": ["css", "less", "postcss", "scss"],
|
||||
"stylelint.validate": ["css", "less", "postcss", "scss"]
|
||||
}
|
||||
7
Gemfile
7
Gemfile
@@ -5,7 +5,7 @@ source "https://rubygems.org"
|
||||
gemspec
|
||||
|
||||
group :test do
|
||||
gem "html-proofer", "~> 3.18"
|
||||
gem "html-proofer", "~> 4.4"
|
||||
end
|
||||
|
||||
# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
|
||||
@@ -21,8 +21,3 @@ gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin]
|
||||
# Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem
|
||||
# do not have a Java counterpart.
|
||||
gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby]
|
||||
|
||||
# Lock jekyll-sass-converter to 2.x on Linux-musl
|
||||
if RUBY_PLATFORM =~ /linux-musl/
|
||||
gem "jekyll-sass-converter", "~> 2.0"
|
||||
end
|
||||
|
||||
100
README.md
100
README.md
@@ -2,15 +2,15 @@
|
||||
|
||||
# Chirpy Jekyll Theme
|
||||
|
||||
A minimal, responsive and feature-rich Jekyll theme for technical writing.
|
||||
A minimal, responsive, and feature-rich Jekyll theme for technical writing.
|
||||
|
||||
[](https://rubygems.org/gems/jekyll-theme-chirpy)
|
||||
[](https://github.com/cotes2020/jekyll-theme-chirpy/actions/workflows/ci.yml)
|
||||
[](https://www.codacy.com/gh/cotes2020/jekyll-theme-chirpy/dashboard?utm_source=github.com&utm_medium=referral&utm_content=cotes2020/jekyll-theme-chirpy&utm_campaign=Badge_Grade)
|
||||
[](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE)
|
||||
[][gem]
|
||||
[][ci]
|
||||
[][codacy]
|
||||
[][license]
|
||||
[](https://996.icu)
|
||||
|
||||
[**Live Demo →**][demo]
|
||||
[**Live Demo** →][demo]
|
||||
|
||||
[][demo]
|
||||
|
||||
@@ -18,78 +18,64 @@
|
||||
|
||||
## Features
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
<i>Click to view features</i>
|
||||
</summary>
|
||||
<p>
|
||||
|
||||
- Dark / Light Theme Mode
|
||||
- Localized UI language
|
||||
- Pinned Posts
|
||||
- Hierarchical Categories
|
||||
- Trending Tags
|
||||
- Table of Contents
|
||||
- Last Modified Date of Posts
|
||||
- Syntax Highlighting
|
||||
- Mathematical Expressions
|
||||
- Mermaid Diagram & Flowchart
|
||||
- Dark / Light Mode Images
|
||||
- Embed Videos
|
||||
- Disqus / Utterances / Giscus Comments
|
||||
- Search
|
||||
- Atom Feeds
|
||||
- Google Analytics
|
||||
- Page Views Reporting
|
||||
- SEO & Performance Optimization
|
||||
|
||||
</p>
|
||||
</details>
|
||||
- Dark / Light Theme Mode
|
||||
- Localized UI language
|
||||
- Pinned Posts on Home Page
|
||||
- Hierarchical Categories
|
||||
- Trending Tags
|
||||
- Table of Contents
|
||||
- Last Modified Date
|
||||
- Syntax Highlighting
|
||||
- Mathematical Expressions
|
||||
- Mermaid Diagrams & Flowcharts
|
||||
- Dark / Light Mode Images
|
||||
- Embed Videos
|
||||
- Disqus / Giscus / Utterances Comments
|
||||
- Built-in Search
|
||||
- Atom Feeds
|
||||
- PWA
|
||||
- Google Analytics / GoatCounter
|
||||
- SEO & Performance Optimization
|
||||
|
||||
## Documentation
|
||||
|
||||
To explore usage, development, and upgrade guide of the project, please refer to
|
||||
the [Wiki][wiki].
|
||||
To learn how to use, develop, and upgrade the project, please refer to the [Wiki][wiki].
|
||||
|
||||
## Contributing
|
||||
|
||||
Welcome to report bugs, help improve the code or submit new features.
|
||||
For more information, please see the ["Contributing Guidelines"][contribute-guide].
|
||||
Contributions (_pull requests_, _issues_, and _discussions_) are what make the open-source community such an amazing place
|
||||
to learn, inspire, and create. Any contributions you make are greatly appreciated.
|
||||
For details, see the "[Contributing Guidelines][contribute-guide]".
|
||||
|
||||
## Credits
|
||||
|
||||
This theme is mainly built with [Jekyll][jekyllrb] ecosystem,
|
||||
[Bootstrap][bootstrap], [Font Awesome][icons] and some other [wonderful tools][lib].
|
||||
The avatar and favicon design come from [Clipart Max][image].
|
||||
### Contributors
|
||||
|
||||
Thanks to all the [contributors][contributors]. Also, folks who submitted issues
|
||||
or unmerged PRs should not be forgotten. Because they reported bugs, shared ideas,
|
||||
or inspired me to write more readable documentation.
|
||||
Thanks to [all the contributors][contributors] involved in the development of the project!
|
||||
|
||||
Last but not least, thanks to [JetBrains][jetbrains] for providing the
|
||||
_Open Source Development_ license.
|
||||
[][contributors]
|
||||
<sub> —— Made with [contrib.rocks](https://contrib.rocks)</sub>
|
||||
|
||||
## Sponsoring
|
||||
### Third-Party Assets
|
||||
|
||||
If you'd like to sponsor this project, the following options are available.
|
||||
This project is built on the [Jekyll][jekyllrb] ecosystem and some [great libraries][lib], and is developed using [VS Code][vscode] as well as tools provided by [JetBrains][jetbrains] under a non-commercial open-source software license.
|
||||
|
||||
[](https://ko-fi.com/coteschung)
|
||||
[][donation]
|
||||
[][donation]
|
||||
The avatar and favicon for the project's website are from [ClipartMAX][clipartmax].
|
||||
|
||||
## License
|
||||
|
||||
This work is published under [MIT][mit] License.
|
||||
This project is published under [MIT License][license].
|
||||
|
||||
[gem]: https://rubygems.org/gems/jekyll-theme-chirpy
|
||||
[ci]: https://github.com/cotes2020/jekyll-theme-chirpy/actions/workflows/ci.yml?query=event%3Apush+branch%3Amaster
|
||||
[codacy]: https://app.codacy.com/gh/cotes2020/jekyll-theme-chirpy/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade
|
||||
[license]: https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE
|
||||
[jekyllrb]: https://jekyllrb.com/
|
||||
[bootstrap]: https://getbootstrap.com/
|
||||
[icons]: https://fontawesome.com/
|
||||
[image]: https://www.clipartmax.com/middle/m2i8b1m2K9Z5m2K9_ant-clipart-childrens-ant-cute/
|
||||
[clipartmax]: https://www.clipartmax.com/middle/m2i8b1m2K9Z5m2K9_ant-clipart-childrens-ant-cute/
|
||||
[demo]: https://cotes2020.github.io/chirpy-demo/
|
||||
[wiki]: https://github.com/cotes2020/jekyll-theme-chirpy/wiki
|
||||
[contribute-guide]: https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/.github/CONTRIBUTING.md
|
||||
[contribute-guide]: https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/docs/CONTRIBUTING.md
|
||||
[contributors]: https://github.com/cotes2020/jekyll-theme-chirpy/graphs/contributors
|
||||
[lib]: https://github.com/cotes2020/chirpy-static-assets
|
||||
[vscode]: https://code.visualstudio.com/
|
||||
[jetbrains]: https://www.jetbrains.com/?from=jekyll-theme-chirpy
|
||||
[donation]: https://sponsor.cotes.page/
|
||||
[mit]: https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE
|
||||
|
||||
43
_config.yml
43
_config.yml
@@ -3,16 +3,12 @@
|
||||
# Import the theme
|
||||
theme: jekyll-theme-chirpy
|
||||
|
||||
# Change the following value to '/PROJECT_NAME' ONLY IF your site type is GitHub Pages Project sites
|
||||
# and doesn't have a custom domain.
|
||||
baseurl: ""
|
||||
|
||||
# The language of the webpage › http://www.lingoes.net/en/translator/langcode.htm
|
||||
# If it has the same name as one of the files in folder `_data/locales`, the layout language will also be changed,
|
||||
# otherwise, the layout language will use the default value of 'en'.
|
||||
lang: en
|
||||
|
||||
# Change to your timezone › http://www.timezoneconverter.com/cgi-bin/findzone/findzone
|
||||
# Change to your timezone › https://kevinnovak.github.io/Time-Zone-Picker
|
||||
timezone: Asia/Shanghai
|
||||
|
||||
# jekyll-seo-tag settings › https://github.com/jekyll/jekyll-seo-tag/blob/master/docs/usage.md
|
||||
@@ -25,7 +21,8 @@ tagline: A text-focused Jekyll theme # it will display as the sub-title
|
||||
description: >- # used by seo meta and the atom feed
|
||||
A minimal, responsive and feature-rich Jekyll theme for technical writing.
|
||||
|
||||
# fill in the protocol & hostname for your site, e.g., 'https://username.github.io'
|
||||
# Fill in the protocol & hostname for your site.
|
||||
# e.g. 'https://username.github.io', note that it does not end with a '/'.
|
||||
url: ""
|
||||
|
||||
github:
|
||||
@@ -54,10 +51,9 @@ google_site_verification: # fill in to your verification string
|
||||
|
||||
google_analytics:
|
||||
id: # fill in your Google Analytics ID
|
||||
# Google Analytics pageviews report settings
|
||||
pv:
|
||||
proxy_endpoint: # fill in the Google Analytics superProxy endpoint of Google App Engine
|
||||
cache_path: # the local PV cache data, friendly to visitors from GFW region
|
||||
|
||||
goatcounter:
|
||||
id: # fill in your Goatcounter ID
|
||||
|
||||
# Prefer color scheme setting.
|
||||
#
|
||||
@@ -70,7 +66,7 @@ google_analytics:
|
||||
# light - Use the light color scheme
|
||||
# dark - Use the dark color scheme
|
||||
#
|
||||
theme_mode: # [light|dark]
|
||||
theme_mode: # [light | dark]
|
||||
|
||||
# The CDN endpoint for images.
|
||||
# Notice that once it is assigned, the CDN url
|
||||
@@ -82,6 +78,10 @@ img_cdn: "https://chirpy-img.netlify.app"
|
||||
# the avatar on sidebar, support local or CORS resources
|
||||
avatar: "/commons/avatar.jpg"
|
||||
|
||||
# The URL of the site-wide social preview image used in SEO `og:image` meta tag.
|
||||
# It can be overridden by a customized `page.image` in front matter.
|
||||
social_preview_image: # string, local or CORS resources
|
||||
|
||||
# boolean type, the global switch for TOC in posts.
|
||||
toc: true
|
||||
|
||||
@@ -111,13 +111,23 @@ assets:
|
||||
enabled: # boolean, keep empty means false
|
||||
# specify the Jekyll environment, empty means both
|
||||
# only works if `assets.self_host.enabled` is 'true'
|
||||
env: # [development|production]
|
||||
env: # [development | production]
|
||||
|
||||
pwa:
|
||||
enabled: true # the option for PWA feature
|
||||
enabled: true # the option for PWA feature (installable)
|
||||
cache:
|
||||
enabled: true # the option for PWA offline cache
|
||||
# Paths defined here will be excluded from the PWA cache.
|
||||
# Usually its value is the `baseurl` of another website that
|
||||
# shares the same domain name as the current website.
|
||||
deny_paths:
|
||||
# - "/example" # URLs match `<SITE_URL>/example/*` will not be cached by the PWA
|
||||
|
||||
paginate: 10
|
||||
|
||||
# The base URL of your site
|
||||
baseurl: ""
|
||||
|
||||
# ------------ The following options are not recommended to be modified ------------------
|
||||
|
||||
kramdown:
|
||||
@@ -157,10 +167,6 @@ defaults:
|
||||
values:
|
||||
layout: page
|
||||
permalink: /:title/
|
||||
- scope:
|
||||
path: assets/img/favicons
|
||||
values:
|
||||
swcache: true
|
||||
- scope:
|
||||
path: assets/js/dist
|
||||
values:
|
||||
@@ -181,12 +187,11 @@ compress_html:
|
||||
exclude:
|
||||
- "*.gem"
|
||||
- "*.gemspec"
|
||||
- docs
|
||||
- tools
|
||||
- README.md
|
||||
- CHANGELOG.md
|
||||
- LICENSE
|
||||
- rollup.config.js
|
||||
- node_modules
|
||||
- package*.json
|
||||
|
||||
jekyll-archives:
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
icon: "fab fa-github"
|
||||
|
||||
- type: twitter
|
||||
icon: "fab fa-twitter"
|
||||
icon: "fa-brands fa-x-twitter"
|
||||
|
||||
- type: email
|
||||
icon: "fas fa-envelope"
|
||||
|
||||
@@ -58,7 +58,7 @@ post:
|
||||
pageview_measure: Aufrufe
|
||||
read_time:
|
||||
unit: Minuten
|
||||
prompt: lesen
|
||||
prompt: Lesezeit
|
||||
relate_posts: Weiterlesen
|
||||
share: Teilen
|
||||
button:
|
||||
@@ -70,6 +70,13 @@ post:
|
||||
title: Link kopieren
|
||||
succeed: Link erfolgreich kopiert!
|
||||
|
||||
# Date time format.
|
||||
# See: <http://strftime.net/>, <https://day.js.org/docs/en/display/format>
|
||||
df:
|
||||
post:
|
||||
strftime: "%d.%m.%Y"
|
||||
dayjs: "DD.MM.YYYY"
|
||||
|
||||
# categories page
|
||||
categories:
|
||||
category_measure:
|
||||
|
||||
@@ -40,7 +40,7 @@ copyright:
|
||||
Except where otherwise noted, the blog posts on this site are licensed
|
||||
under the Creative Commons Attribution 4.0 International (CC BY 4.0) License by the author.
|
||||
|
||||
meta: Using the :PLATFORM theme :THEME
|
||||
meta: Using the :THEME theme for :PLATFORM.
|
||||
|
||||
not_found:
|
||||
statment: Sorry, we've misplaced that URL or it's pointing to something that doesn't exist.
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
# ----- Commons label -----
|
||||
|
||||
layout:
|
||||
post: Публикация
|
||||
post: Пост
|
||||
category: Категория
|
||||
tag: Тег
|
||||
|
||||
# The tabs of sidebar
|
||||
tabs:
|
||||
# format: <filename_without_extension>: <value>
|
||||
home: Домашняя страница
|
||||
home: Главная
|
||||
categories: Категории
|
||||
tags: Теги
|
||||
archives: Архив
|
||||
@@ -19,8 +19,8 @@ tabs:
|
||||
# the text displayed in the search bar & search results
|
||||
search:
|
||||
hint: поиск
|
||||
cancel: Отменить
|
||||
no_results: Ох! Ничего не найдено.
|
||||
cancel: Отмена
|
||||
no_results: Упс! Ничего не найдено.
|
||||
|
||||
panel:
|
||||
lastmod: Недавно обновлено
|
||||
@@ -30,48 +30,58 @@ panel:
|
||||
copyright:
|
||||
# Shown at the bottom of the post
|
||||
license:
|
||||
template: Публикация защищена лицензией :LICENSE_NAME.
|
||||
template: Авторский пост защищен лицензией :LICENSE_NAME.
|
||||
name: CC BY 4.0
|
||||
link: https://creativecommons.org/licenses/by/4.0/
|
||||
|
||||
# Displayed in the footer
|
||||
brief: Некоторые права защищены.
|
||||
verbose: >-
|
||||
Публикации на сайте защищены лицензией Creative Commons Attribution 4.0 International (CC BY 4.0),
|
||||
если в тексте публикации не указано иное.
|
||||
Если не указано иное, авторские посты на этом сайте защищены лицензией Creative Commons Attribution 4.0 International (CC BY 4.0).
|
||||
|
||||
meta: Powered by :PLATFORM with :THEME theme
|
||||
meta: Использует тему :THEME для :PLATFORM
|
||||
|
||||
not_found:
|
||||
statment: Извините, эта ссылка указывает на ресурс который не существует.
|
||||
statment: Извините, мы перепутали URL-адрес или он указывает на что-то несуществующее.
|
||||
|
||||
notification:
|
||||
update_found: Доступна новая версия контента.
|
||||
update: Обновлять
|
||||
update: Обновить
|
||||
|
||||
# ----- Posts related labels -----
|
||||
|
||||
post:
|
||||
written_by: Автор
|
||||
posted: Время публикации
|
||||
posted: Опубликовано
|
||||
updated: Обновлено
|
||||
words: слов
|
||||
pageview_measure: просмотров
|
||||
read_time:
|
||||
unit: минут
|
||||
unit: мин.
|
||||
prompt: чтения
|
||||
relate_posts: Вам также может быть интересно
|
||||
relate_posts: Похожие посты
|
||||
share: Поделиться
|
||||
button:
|
||||
next: Предыдущая публикация
|
||||
previous: Следующая публикация
|
||||
next: Следующий пост
|
||||
previous: Предыдущий пост
|
||||
copy_code:
|
||||
succeed: Скопировано успешно!
|
||||
succeed: Скопировано!
|
||||
share_link:
|
||||
title: Скопировать ссылку
|
||||
succeed: Ссылка успешно скопирована!
|
||||
|
||||
# Date time format.
|
||||
# See: <http://strftime.net/>, <https://day.js.org/docs/en/display/format>
|
||||
df:
|
||||
post:
|
||||
strftime: "%d.%m.%Y"
|
||||
dayjs: "DD.MM.YYYY"
|
||||
|
||||
# categories page
|
||||
categories:
|
||||
category_measure: категории
|
||||
post_measure: публикации
|
||||
category_measure:
|
||||
singular: категория
|
||||
plural: категории
|
||||
post_measure:
|
||||
singular: пост
|
||||
plural: посты
|
||||
|
||||
91
_data/locales/th.yml
Normal file
91
_data/locales/th.yml
Normal file
@@ -0,0 +1,91 @@
|
||||
# The layout text of site
|
||||
|
||||
# ----- Commons label -----
|
||||
|
||||
layout:
|
||||
post: โพสต์
|
||||
category: หมวดหมู่
|
||||
tag: แท็ก
|
||||
|
||||
# The tabs of sidebar
|
||||
tabs:
|
||||
# format: <filename_without_extension>: <value>
|
||||
home: หน้าแรก
|
||||
categories: หมวดหมู่
|
||||
tags: แท็ก
|
||||
archives: คลังเก็บ
|
||||
about: เกี่ยวกับ
|
||||
|
||||
# the text displayed in the search bar & search results
|
||||
search:
|
||||
hint: ค้นหา
|
||||
cancel: ยกเลิก
|
||||
no_results: โอ๊ะ! ไม่พบผลลัพธ์
|
||||
|
||||
panel:
|
||||
lastmod: อัปเดตล่าสุด
|
||||
trending_tags: แท็กยอดนิยม
|
||||
toc: เนื้อหา
|
||||
|
||||
copyright:
|
||||
# Shown at the bottom of the post
|
||||
license:
|
||||
template: โพสต์นี้อยู่ภายใต้การอนุญาต :LICENSE_NAME โดยผู้เขียน
|
||||
name: CC BY 4.0
|
||||
link: https://creativecommons.org/licenses/by/4.0/
|
||||
|
||||
# Displayed in the footer
|
||||
brief: สงวนลิขสิทธิ์เป็นบางส่วน
|
||||
verbose: >-
|
||||
เว้นแต่ว่าจะระบุเป็นอย่างอื่น โพสต์บนเว็บไซต์นี้อยู่ภายใต้
|
||||
สัญญาอนุญาตครีเอทีฟคอมมอนส์แบบ 4.0 นานาชาติ (CC BY 4.0) โดยผู้เขียน
|
||||
|
||||
meta: กำลังใช้ธีมของ :PLATFORM ชื่อ :THEME
|
||||
|
||||
not_found:
|
||||
statment: ขออภัย เราวาง URL นั้นไว้ผิดที่ หรือมันชี้ไปยังสิ่งที่ไม่มีอยู่
|
||||
|
||||
notification:
|
||||
update_found: มีเวอร์ชันใหม่ของเนื้อหา
|
||||
update: อัปเดต
|
||||
|
||||
# ----- Posts related labels -----
|
||||
|
||||
post:
|
||||
written_by: โดย
|
||||
posted: โพสต์เมื่อ
|
||||
updated: อัปเดตเมื่อ
|
||||
words: คำ
|
||||
pageview_measure: ครั้ง
|
||||
read_time:
|
||||
unit: นาที
|
||||
prompt: อ่าน
|
||||
relate_posts: อ่านต่อ
|
||||
share: แชร์
|
||||
button:
|
||||
next: ใหม่กว่า
|
||||
previous: เก่ากว่า
|
||||
copy_code:
|
||||
succeed: คัดลอกแล้ว!
|
||||
share_link:
|
||||
title: คัดลอกลิงก์
|
||||
succeed: คัดลอกลิงก์เรียบร้อยแล้ว!
|
||||
|
||||
# Date time format.
|
||||
# See: <http://strftime.net/>, <https://day.js.org/docs/en/display/format>
|
||||
df:
|
||||
post:
|
||||
strftime: "%b %e, %Y"
|
||||
dayjs: "ll"
|
||||
archives:
|
||||
strftime: "%b"
|
||||
dayjs: "MMM"
|
||||
|
||||
# categories page
|
||||
categories:
|
||||
category_measure:
|
||||
singular: หมวดหมู่
|
||||
plural: หมวดหมู่
|
||||
post_measure:
|
||||
singular: โพสต์
|
||||
plural: โพสต์
|
||||
@@ -23,7 +23,7 @@ search:
|
||||
no_results: Hop! Öyle bir şey bulamadım.
|
||||
|
||||
panel:
|
||||
lastmod: Yeni Güncellendi
|
||||
lastmod: Son Güncellenenler
|
||||
trending_tags: Yükselen Etiketler
|
||||
toc: İçindekiler
|
||||
|
||||
@@ -38,7 +38,7 @@ copyright:
|
||||
brief: Bazı hakları saklıdır.
|
||||
verbose: >-
|
||||
Aksi belirtilmediği sürece, bu sitedeki gönderiler Creative Commons Atıf 4.0 Uluslararası (CC BY 4.0) Lisansı altındadır.
|
||||
Kısaca sayfa linkini de vererek paylaşabilir veya düzenleyip paylaşabilirsin.
|
||||
Kısaca sayfa linkini vererek değiştirebilir / paylaşabilirsiniz.
|
||||
|
||||
meta: :PLATFORM ve :THEME teması
|
||||
|
||||
@@ -53,8 +53,8 @@ notification:
|
||||
|
||||
post:
|
||||
written_by: Yazan
|
||||
posted: Gönderilme Tarihi
|
||||
updated: Güncellenme Tarihi
|
||||
posted: Gönderim
|
||||
updated: Güncelleme
|
||||
words: sözcük
|
||||
pageview_measure: görüntülenme
|
||||
read_time:
|
||||
|
||||
@@ -31,21 +31,16 @@ dayjs:
|
||||
relativeTime: /assets/lib/dayjs/plugin/relativeTime.min.js
|
||||
localizedFormat: /assets/lib/dayjs/plugin/localizedFormat.min.js
|
||||
|
||||
countup:
|
||||
js: /assets/lib/countup.js/countUp.min.js
|
||||
|
||||
magnific-popup:
|
||||
css: /assets/lib/magnific-popup/magnific-popup.css
|
||||
js: /assets/lib/magnific-popup/jquery.magnific-popup.min.js
|
||||
|
||||
lazysizes:
|
||||
js: /assets/lib/lazysizes/lazysizes.min.js
|
||||
lazy-polyfill:
|
||||
css: /assets/lib/loading-attribute-polyfill/loading-attribute-polyfill.min.css
|
||||
js: /assets/lib/loading-attribute-polyfill/loading-attribute-polyfill.umd.min.js
|
||||
|
||||
clipboard:
|
||||
js: /assets/lib/clipboard/clipboard.min.js
|
||||
|
||||
polyfill:
|
||||
js: /assets/lib/polyfill-v3-es6/polyfill.min.js
|
||||
|
||||
mathjax:
|
||||
js: /assets/lib/mathjax/tex-chtml.js
|
||||
|
||||
@@ -8,55 +8,52 @@ cdns:
|
||||
- url: https://fonts.googleapis.com
|
||||
# jsDelivr CDN
|
||||
- url: https://cdn.jsdelivr.net
|
||||
# polyfill.io for math
|
||||
- url: https://polyfill.io
|
||||
|
||||
# fonts
|
||||
|
||||
webfonts: https://fonts.googleapis.com/css2?family=Lato&family=Source+Sans+Pro:wght@400;600;900&display=swap
|
||||
webfonts: https://fonts.googleapis.com/css2?family=Lato&family=Source+Sans+Pro:wght@400;600;700;900&display=swap
|
||||
|
||||
# Libraries
|
||||
|
||||
jquery:
|
||||
js: https://cdn.jsdelivr.net/npm/jquery@3.7.0/dist/jquery.min.js
|
||||
js: https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js
|
||||
|
||||
bootstrap:
|
||||
css: https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css
|
||||
js: https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js
|
||||
css: https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css
|
||||
js: https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js
|
||||
|
||||
toc:
|
||||
css: https://cdn.jsdelivr.net/npm/tocbot@4.21.0/dist/tocbot.min.css
|
||||
js: https://cdn.jsdelivr.net/npm/tocbot@4.21.0/dist/tocbot.min.js
|
||||
css: https://cdn.jsdelivr.net/npm/tocbot@4.25.0/dist/tocbot.min.css
|
||||
js: https://cdn.jsdelivr.net/npm/tocbot@4.25.0/dist/tocbot.min.js
|
||||
|
||||
fontawesome:
|
||||
css: https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.4.0/css/all.min.css
|
||||
css: https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.5.1/css/all.min.css
|
||||
|
||||
search:
|
||||
js: https://cdn.jsdelivr.net/npm/simple-jekyll-search@1.10.0/dest/simple-jekyll-search.min.js
|
||||
|
||||
mermaid:
|
||||
js: https://cdn.jsdelivr.net/npm/mermaid@9.4.3/dist/mermaid.min.js
|
||||
js: https://cdn.jsdelivr.net/npm/mermaid@10.8.0/dist/mermaid.min.js
|
||||
|
||||
dayjs:
|
||||
js:
|
||||
common: https://cdn.jsdelivr.net/npm/dayjs@1.11.7/dayjs.min.js
|
||||
locale: https://cdn.jsdelivr.net/npm/dayjs@1.11.7/locale/:LOCALE.min.js
|
||||
relativeTime: https://cdn.jsdelivr.net/npm/dayjs@1.11.7/plugin/relativeTime.min.js
|
||||
localizedFormat: https://cdn.jsdelivr.net/npm/dayjs@1.11.7/plugin/localizedFormat.min.js
|
||||
|
||||
countup:
|
||||
js: https://cdn.jsdelivr.net/npm/countup.js@1.9.3/dist/countUp.min.js
|
||||
common: https://cdn.jsdelivr.net/npm/dayjs@1.11.10/dayjs.min.js
|
||||
locale: https://cdn.jsdelivr.net/npm/dayjs@1.11.10/locale/:LOCALE.min.js
|
||||
relativeTime: https://cdn.jsdelivr.net/npm/dayjs@1.11.10/plugin/relativeTime.min.js
|
||||
localizedFormat: https://cdn.jsdelivr.net/npm/dayjs@1.11.10/plugin/localizedFormat.min.js
|
||||
|
||||
magnific-popup:
|
||||
css: https://cdn.jsdelivr.net/npm/magnific-popup@1.1.0/dist/magnific-popup.min.css
|
||||
js: https://cdn.jsdelivr.net/npm/magnific-popup@1.1.0/dist/jquery.magnific-popup.min.js
|
||||
|
||||
lazysizes:
|
||||
js: https://cdn.jsdelivr.net/npm/lazysizes@5.3.2/lazysizes.min.js
|
||||
lazy-polyfill:
|
||||
css: https://cdn.jsdelivr.net/npm/loading-attribute-polyfill@2.1.1/dist/loading-attribute-polyfill.min.css
|
||||
js: https://cdn.jsdelivr.net/npm/loading-attribute-polyfill@2.1.1/dist/loading-attribute-polyfill.umd.min.js
|
||||
|
||||
clipboard:
|
||||
js: https://cdn.jsdelivr.net/npm/clipboard@2.0.11/dist/clipboard.min.js
|
||||
|
||||
polyfill:
|
||||
js: https://polyfill.io/v3/polyfill.min.js?features=es6
|
||||
|
||||
mathjax:
|
||||
js: https://cdn.jsdelivr.net/npm/mathjax@3.2.2/es5/tex-chtml.js
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
platforms:
|
||||
- type: Twitter
|
||||
icon: "fab fa-twitter"
|
||||
icon: "fa-brands fa-square-x-twitter"
|
||||
link: "https://twitter.com/intent/tweet?text=TITLE&url=URL"
|
||||
|
||||
- type: Facebook
|
||||
@@ -23,3 +23,16 @@ platforms:
|
||||
# - type: Weibo
|
||||
# icon: "fab fa-weibo"
|
||||
# link: "http://service.weibo.com/share/share.php?title=TITLE&url=URL"
|
||||
#
|
||||
# - type: Mastodon
|
||||
# icon: "fa-brands fa-mastodon"
|
||||
# # See: https://github.com/justinribeiro/share-to-mastodon#properties
|
||||
# instances:
|
||||
# - label: mastodon.social
|
||||
# link: "https://mastodon.social/"
|
||||
# - label: mastodon.online
|
||||
# link: "https://mastodon.online/"
|
||||
# - label: fosstodon.org
|
||||
# link: "https://fosstodon.org/"
|
||||
# - label: photog.social
|
||||
# link: "https://photog.social/"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<!-- The Disqus lazy loading. -->
|
||||
<div id="disqus_thread" class="pt-2 pb-2">
|
||||
|
||||
<div id="disqus_thread">
|
||||
<p class="text-center text-muted small">Comments powered by <a href="https://disqus.com/">Disqus</a>.</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
'data-theme': initTheme,
|
||||
'data-input-position': '{{ site.comments.giscus.input_position | default: 'bottom' }}',
|
||||
'data-lang': '{{ site.comments.giscus.lang | default: lang }}',
|
||||
'data-loading': 'lazy',
|
||||
crossorigin: 'anonymous',
|
||||
async: ''
|
||||
};
|
||||
|
||||
@@ -1,51 +1,50 @@
|
||||
<!-- https://utteranc.es/ -->
|
||||
<script src="https://utteranc.es/client.js"
|
||||
repo="{{ site.comments.utterances.repo }}"
|
||||
issue-term="{{ site.comments.utterances.issue_term }}"
|
||||
crossorigin="anonymous"
|
||||
async>
|
||||
</script>
|
||||
<script
|
||||
src="https://utteranc.es/client.js"
|
||||
repo="{{ site.comments.utterances.repo }}"
|
||||
issue-term="{{ site.comments.utterances.issue_term }}"
|
||||
crossorigin="anonymous"
|
||||
async
|
||||
></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
const origin = "https://utteranc.es";
|
||||
const iframe = "iframe.utterances-frame";
|
||||
const lightTheme = "github-light";
|
||||
const darkTheme = "github-dark";
|
||||
(function () {
|
||||
const origin = 'https://utteranc.es';
|
||||
const iframe = 'iframe.utterances-frame';
|
||||
const lightTheme = 'github-light';
|
||||
const darkTheme = 'github-dark';
|
||||
let initTheme = lightTheme;
|
||||
const html = document.documentElement;
|
||||
|
||||
if ($("html[data-mode=dark]").length > 0
|
||||
|| ($("html[data-mode]").length == 0
|
||||
&& window.matchMedia("(prefers-color-scheme: dark)").matches)) {
|
||||
if (
|
||||
(html.hasAttribute('data-mode') && html.getAttribute('data-mode') === 'dark') ||
|
||||
(!html.hasAttribute('data-mode') && window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||
) {
|
||||
initTheme = darkTheme;
|
||||
}
|
||||
|
||||
addEventListener("message", (event) => {
|
||||
addEventListener('message', (event) => {
|
||||
let theme;
|
||||
|
||||
/* credit to <https://github.com/utterance/utterances/issues/170#issuecomment-594036347> */
|
||||
if (event.origin === origin) {
|
||||
/* page initial */
|
||||
theme = initTheme;
|
||||
|
||||
} else if (event.source === window && event.data &&
|
||||
event.data.direction === ModeToggle.ID) {
|
||||
} else if (event.source === window && event.data && event.data.direction === ModeToggle.ID) {
|
||||
/* global theme mode changed */
|
||||
const mode = event.data.message;
|
||||
theme = (mode === ModeToggle.DARK_MODE ? darkTheme : lightTheme);
|
||||
|
||||
theme = mode === ModeToggle.DARK_MODE ? darkTheme : lightTheme;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
const message = {
|
||||
type: "set-theme",
|
||||
type: 'set-theme',
|
||||
theme: theme
|
||||
};
|
||||
|
||||
const utterances = document.querySelector(iframe).contentWindow;
|
||||
utterances.postMessage(message, origin);
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
See: ${JS_ROOT}/utils/locale-dateime.js
|
||||
-->
|
||||
|
||||
{% assign wrap_elem = include.wrap | default: 'em' %}
|
||||
{% assign df_strftime = site.data.locales[include.lang].df.post.strftime | default: '%d/%m/%Y' %}
|
||||
{% assign df_dayjs = site.data.locales[include.lang].df.post.dayjs | default: 'DD/MM/YYYY' %}
|
||||
|
||||
<{{ wrap_elem }}
|
||||
class="{% if include.class %}{{ include.class }}{% endif %}"
|
||||
<time
|
||||
{% if include.class %}
|
||||
class="{{ include.class }}"
|
||||
{% endif %}
|
||||
data-ts="{{ include.date | date: '%s' }}"
|
||||
data-df="{{ df_dayjs }}"
|
||||
{% if include.tooltip %}
|
||||
@@ -16,4 +17,4 @@
|
||||
{% endif %}
|
||||
>
|
||||
{{ include.date | date: df_strftime }}
|
||||
</{{ wrap_elem }}>
|
||||
</time>
|
||||
|
||||
10
_includes/embed/bilibili.html
Normal file
10
_includes/embed/bilibili.html
Normal file
@@ -0,0 +1,10 @@
|
||||
<iframe
|
||||
class="embed-video bilibili"
|
||||
loading="lazy"
|
||||
src="https://player.bilibili.com/player.html?bvid={{ include.id }}"
|
||||
scrolling="no"
|
||||
border="0"
|
||||
frameborder="no"
|
||||
framespacing="0"
|
||||
allowfullscreen="true"
|
||||
></iframe>
|
||||
@@ -1,4 +1,8 @@
|
||||
<iframe class="embed-video twitch lazyload"
|
||||
<iframe
|
||||
class="embed-video twitch"
|
||||
loading="lazy"
|
||||
src="https://player.twitch.tv/?video={{ include.id }}&parent={{ site.url | split: '://' | last | remove: '/' }}"
|
||||
frameborder="0" allowfullscreen="true"
|
||||
scrolling="no"></iframe>
|
||||
frameborder="0"
|
||||
allowfullscreen="true"
|
||||
scrolling="no"
|
||||
></iframe>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<iframe class="embed-video youtube lazyload"
|
||||
<iframe
|
||||
class="embed-video youtube"
|
||||
loading="lazy"
|
||||
src="https://www.youtube.com/embed/{{ include.id }}"
|
||||
title="YouTube video player"
|
||||
frameborder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen></iframe>
|
||||
allowfullscreen
|
||||
></iframe>
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{{ favicon_path }}/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="{{ favicon_path }}/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="{{ favicon_path }}/favicon-16x16.png">
|
||||
<link rel="manifest" href="{{ favicon_path }}/site.webmanifest">
|
||||
{% if site.pwa.enabled %}
|
||||
<link rel="manifest" href="{{ favicon_path }}/site.webmanifest">
|
||||
{% endif %}
|
||||
<link rel="shortcut icon" href="{{ favicon_path }}/favicon.ico">
|
||||
<meta name="apple-mobile-web-app-title" content="{{ site.title }}">
|
||||
<meta name="application-name" content="{{ site.title }}">
|
||||
|
||||
@@ -1,34 +1,42 @@
|
||||
<!-- The Footer -->
|
||||
|
||||
<footer>
|
||||
<div class="container px-lg-4">
|
||||
<div class="d-flex justify-content-center align-items-center text-muted mx-md-3">
|
||||
<p>
|
||||
{%- capture _platform -%}
|
||||
<a href="https://jekyllrb.com" target="_blank" rel="noopener">Jekyll</a>
|
||||
{%- endcapture -%}
|
||||
<footer
|
||||
aria-label="Site Info"
|
||||
class="
|
||||
d-flex flex-column justify-content-center text-muted
|
||||
flex-lg-row justify-content-lg-between align-items-lg-center pb-lg-3
|
||||
"
|
||||
>
|
||||
<p>
|
||||
{{- '©' }}
|
||||
<time>{{ 'now' | date: '%Y' }}</time>
|
||||
|
||||
{%- capture _theme -%}
|
||||
<a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank" rel="noopener">Chirpy</a>
|
||||
{%- endcapture -%}
|
||||
{% if site.social.links %}
|
||||
<a href="{{ site.social.links[0] }}">{{ site.social.name }}</a>.
|
||||
{% else %}
|
||||
<em class="fst-normal">{{ site.social.name }}</em>.
|
||||
{% endif %}
|
||||
|
||||
{{ site.data.locales[include.lang].meta | replace: ':PLATFORM', _platform | replace: ':THEME', _theme }}
|
||||
</p>
|
||||
{% if site.data.locales[include.lang].copyright.brief %}
|
||||
<span
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
title="{{ site.data.locales[include.lang].copyright.verbose }}"
|
||||
>
|
||||
{{- site.data.locales[include.lang].copyright.brief -}}
|
||||
</span>
|
||||
{% endif %}
|
||||
</p>
|
||||
|
||||
<p>
|
||||
{{- '©' }}
|
||||
{{ 'now' | date: '%Y' }}
|
||||
<a href="{{ site.social.links[0] }}">{{ site.social.name }}</a>.
|
||||
{% if site.data.locales[include.lang].copyright.brief %}
|
||||
<span
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
title="{{ site.data.locales[include.lang].copyright.verbose }}"
|
||||
>
|
||||
{{- site.data.locales[include.lang].copyright.brief -}}
|
||||
</span>
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
{%- capture _platform -%}
|
||||
<a href="https://jekyllrb.com" target="_blank" rel="noopener">Jekyll</a>
|
||||
{%- endcapture -%}
|
||||
|
||||
{%- capture _theme -%}
|
||||
<a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank" rel="noopener">Chirpy</a>
|
||||
{%- endcapture -%}
|
||||
|
||||
{{ site.data.locales[include.lang].meta | replace: ':PLATFORM', _platform | replace: ':THEME', _theme }}
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
8
_includes/goatcounter.html
Normal file
8
_includes/goatcounter.html
Normal file
@@ -0,0 +1,8 @@
|
||||
<!-- GoatCounter -->
|
||||
|
||||
<script
|
||||
data-goatcounter="https://{{ site.goatcounter.id }}.goatcounter.com/count"
|
||||
async
|
||||
src="https://gc.zgo.at/count.js"
|
||||
></script>
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
<!-- The Head -->
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="theme-color" media="(prefers-color-scheme: light)" content="#f7f7f7">
|
||||
@@ -11,39 +9,43 @@
|
||||
content="width=device-width, user-scalable=no initial-scale=1, shrink-to-fit=no, viewport-fit=cover"
|
||||
>
|
||||
|
||||
{% if page.layout == 'home' or page.layout == 'post' %}
|
||||
{% if site.google_analytics.pv.proxy_endpoint %}
|
||||
<meta name="pv-proxy-endpoint" content="{{ site.google_analytics.pv.proxy_endpoint }}">
|
||||
{% endif %}
|
||||
|
||||
{% if site.google_analytics.pv.cache_path %}
|
||||
<meta name="pv-cache-path" content="{{ site.google_analytics.pv.cache_path | relative_url }}">
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% capture seo_tags %}
|
||||
{%- capture seo_tags -%}
|
||||
{% seo title=false %}
|
||||
{% endcapture %}
|
||||
{%- endcapture -%}
|
||||
|
||||
<!-- Setup Open Graph image -->
|
||||
|
||||
{% if page.image %}
|
||||
{% assign img = page.image.path | default: page.image %}
|
||||
{% assign src = page.image.path | default: page.image %}
|
||||
|
||||
{% unless img contains '://' %}
|
||||
{% assign img_path = page.img_path | append: '/' | append: img | replace: '//', '/' %}
|
||||
{% capture target %}"{{ img | absolute_url }}"{% endcapture %}
|
||||
{% unless src contains '://' %}
|
||||
{%- capture img_url -%}
|
||||
{% include img-url.html src=src img_path=page.img_path absolute=true %}
|
||||
{%- endcapture -%}
|
||||
|
||||
{% if site.img_cdn contains '//' %}
|
||||
<!-- it's a cross-origin URL -->
|
||||
{% capture replacement %}"{{ site.img_cdn }}{{ img_path }}"{% endcapture %}
|
||||
{% else %}
|
||||
<!-- it's a local file path -->
|
||||
{%- capture replacement -%}
|
||||
"{{ site.img_cdn | append: '/' | append: img_path | replace: '//', '/' | absolute_url }}"
|
||||
{%- endcapture -%}
|
||||
{% endif %}
|
||||
{%- capture old_url -%}{{ src | absolute_url }}{%- endcapture -%}
|
||||
{%- capture new_url -%}{{ img_url }}{%- endcapture -%}
|
||||
|
||||
{% assign seo_tags = seo_tags | replace: target, replacement %}
|
||||
{% assign seo_tags = seo_tags | replace: old_url, new_url %}
|
||||
{% endunless %}
|
||||
|
||||
{% elsif site.social_preview_image %}
|
||||
{%- capture img_url -%}
|
||||
{% include img-url.html src=site.social_preview_image absolute=true %}
|
||||
{%- endcapture -%}
|
||||
|
||||
{%- capture og_image -%}
|
||||
<meta property="og:image" content="{{ img_url }}" />
|
||||
{%- endcapture -%}
|
||||
|
||||
{%- capture twitter_image -%}
|
||||
<meta property="twitter:card" content="summary_large_image" />
|
||||
<meta property="twitter:image" content="{{ img_url }}" />
|
||||
{%- endcapture -%}
|
||||
|
||||
{% assign old_meta_clip = '<meta name="twitter:card" content="summary" />' %}
|
||||
{% assign new_meta_clip = og_image | append: twitter_image %}
|
||||
{% assign seo_tags = seo_tags | replace: old_meta_clip, new_meta_clip %}
|
||||
{% endif %}
|
||||
|
||||
{{ seo_tags }}
|
||||
@@ -55,7 +57,7 @@
|
||||
{{ site.title }}
|
||||
</title>
|
||||
|
||||
{% include favicons.html %}
|
||||
{% include_cached favicons.html %}
|
||||
|
||||
{% if site.resources.ignore_env != jekyll.environment and site.resources.self_hosted %}
|
||||
<link href="{{ site.data.origin[type].webfonts | relative_url }}" rel="stylesheet">
|
||||
@@ -76,31 +78,24 @@
|
||||
|
||||
<link rel="preconnect" href="https://www.googletagmanager.com" crossorigin="anonymous">
|
||||
<link rel="dns-prefetch" href="https://www.googletagmanager.com">
|
||||
|
||||
{% if site.google_analytics.pv.proxy_endpoint %}
|
||||
{% assign proxy_url = site.google_analytics.pv.proxy_endpoint
|
||||
| replace: 'https://', ''
|
||||
| split: '/'
|
||||
| first
|
||||
| prepend: 'https://'
|
||||
%}
|
||||
<link rel="preconnect" href="{{ proxy_url }}" crossorigin="use-credentials">
|
||||
<link rel="dns-prefetch" href="{{ proxy_url }}">
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<!-- Bootstrap -->
|
||||
<link rel="stylesheet" href="{{ site.data.origin[type].bootstrap.css | relative_url}}">
|
||||
<link rel="stylesheet" href="{{ site.data.origin[type].bootstrap.css | relative_url }}">
|
||||
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="{{ site.data.origin[type].fontawesome.css | relative_url }}">
|
||||
|
||||
<link rel="stylesheet" href="{{ '/assets/css/style.css' | relative_url }}">
|
||||
<link rel="stylesheet" href="{{ '/assets/css/:THEME.css' | replace: ':THEME', site.theme | relative_url }}">
|
||||
|
||||
{% if site.toc and page.toc %}
|
||||
<link rel="stylesheet" href="{{ site.data.origin[type].toc.css | relative_url }}">
|
||||
{% endif %}
|
||||
|
||||
{% if page.layout == 'post' or page.layout == 'page' or page.layout == 'home' %}
|
||||
<link rel="stylesheet" href="{{ site.data.origin[type]['lazy-polyfill'].css | relative_url }}">
|
||||
{% endif %}
|
||||
|
||||
{% if page.layout == 'page' or page.layout == 'post' %}
|
||||
<!-- Manific Popup -->
|
||||
<link rel="stylesheet" href="{{ site.data.origin[type].magnific-popup.css | relative_url }}">
|
||||
|
||||
39
_includes/img-url.html
Normal file
39
_includes/img-url.html
Normal file
@@ -0,0 +1,39 @@
|
||||
{%- comment -%}
|
||||
Generate image final URL based on `site.img_cdn`, `page.img_path`
|
||||
|
||||
Arguments:
|
||||
src - required, basic image path
|
||||
img_path - optional, relative path of image
|
||||
absolute - optional, boolean, if true, generate absolute URL
|
||||
|
||||
Return:
|
||||
image URL
|
||||
{%- endcomment -%}
|
||||
|
||||
{% assign url = include.src %}
|
||||
|
||||
{%- if url -%}
|
||||
{% unless url contains ':' %}
|
||||
{%- comment -%} CND URL {%- endcomment -%}
|
||||
{% assign prefix = site.img_cdn | default: '' %}
|
||||
|
||||
{%- comment -%} Add page image path prefix {%- endcomment -%}
|
||||
{% assign url = include.img_path | default: '' | append: '/' | append: url %}
|
||||
|
||||
{% assign url = prefix
|
||||
| append: '/'
|
||||
| append: url
|
||||
| replace: '///', '/'
|
||||
| replace: '//', '/'
|
||||
| replace: ':', ':/'
|
||||
%}
|
||||
|
||||
{% if include.absolute %}
|
||||
{% assign url = site.url | append: site.base_url | append: url %}
|
||||
{% else %}
|
||||
{% assign url = site.base_url | append: url %}
|
||||
{% endif %}
|
||||
{% endunless %}
|
||||
{%- endif -%}
|
||||
|
||||
{{- url -}}
|
||||
@@ -11,15 +11,10 @@
|
||||
|
||||
<!-- layout specified -->
|
||||
|
||||
{% if page.layout == 'post' %}
|
||||
{% if site.google_analytics.pv.proxy_endpoint or site.google_analytics.pv.cache_path %}
|
||||
<!-- pv-report needs countup.js -->
|
||||
{% assign urls = urls | append: ',' | append: site.data.origin[type].countup.js %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% assign js_dist = '/assets/js/dist/' %}
|
||||
|
||||
{% if page.layout == 'post' or page.layout == 'page' or page.layout == 'home' %}
|
||||
{% assign urls = urls | append: ',' | append: site.data.origin[type].lazysizes.js %}
|
||||
{% assign urls = urls | append: ',' | append: site.data.origin[type]['lazy-polyfill'].js %}
|
||||
|
||||
{% unless page.layout == 'home' %}
|
||||
<!-- image lazy-loading & popup & clipboard -->
|
||||
@@ -72,7 +67,7 @@
|
||||
{% assign js = 'commons' %}
|
||||
{% endcase %}
|
||||
|
||||
{% capture script %}/assets/js/dist/{{ js }}.min.js{% endcapture %}
|
||||
{% capture script %}{{ js_dist }}{{ js }}.min.js{% endcapture %}
|
||||
<script defer src="{{ script | relative_url }}"></script>
|
||||
|
||||
{% if page.math %}
|
||||
@@ -90,24 +85,29 @@
|
||||
displayMath: [
|
||||
['$$', '$$'],
|
||||
['\\[', '\\]']
|
||||
]
|
||||
],
|
||||
/* equation numbering */
|
||||
tags: 'ams'
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<script src="{{ site.data.origin[type].polyfill.js | relative_url }}"></script>
|
||||
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
|
||||
<script id="MathJax-script" async src="{{ site.data.origin[type].mathjax.js | relative_url }}"></script>
|
||||
{% endif %}
|
||||
|
||||
{% if jekyll.environment == 'production' %}
|
||||
<!-- PWA -->
|
||||
{% if site.pwa.enabled %}
|
||||
<script defer src="{{ '/app.js' | relative_url }}"></script>
|
||||
{% else %}
|
||||
<script defer src="{{ '/unregister.js' | relative_url }}"></script>
|
||||
<script defer src="{{ 'app.min.js' | prepend: js_dist | relative_url }}"></script>
|
||||
{% endif %}
|
||||
|
||||
<!-- GA -->
|
||||
{% if site.google_analytics.id != empty and site.google_analytics.id %}
|
||||
{% include google-analytics.html %}
|
||||
{% endif %}
|
||||
|
||||
<!-- GoatCounter -->
|
||||
{% if site.goatcounter.id != empty and site.goatcounter.id %}
|
||||
{% include goatcounter.html %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
24
_includes/notification.html
Normal file
24
_includes/notification.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<aside
|
||||
id="notification"
|
||||
class="toast"
|
||||
role="alert"
|
||||
aria-live="assertive"
|
||||
aria-atomic="true"
|
||||
data-bs-animation="true"
|
||||
data-bs-autohide="false"
|
||||
>
|
||||
<div class="toast-header">
|
||||
<button
|
||||
type="button"
|
||||
class="btn-close ms-auto"
|
||||
data-bs-dismiss="toast"
|
||||
aria-label="Close"
|
||||
></button>
|
||||
</div>
|
||||
<div class="toast-body text-center pt-0">
|
||||
<p class="px-2 mb-3">{{ site.data.locales[include.lang].notification.update_found }}</p>
|
||||
<button type="button" class="btn btn-primary" aria-label="Update">
|
||||
{{ site.data.locales[include.lang].notification.update }}
|
||||
</button>
|
||||
</div>
|
||||
</aside>
|
||||
@@ -1,19 +1,19 @@
|
||||
<!-- Navigation buttons at the bottom of the post. -->
|
||||
|
||||
<div class="post-navigation d-flex justify-content-between">
|
||||
<nav class="post-navigation d-flex justify-content-between" aria-label="Post Navigation">
|
||||
{% assign previous = site.data.locales[include.lang].post.button.previous %}
|
||||
{% assign next = site.data.locales[include.lang].post.button.next %}
|
||||
|
||||
{% if page.previous.url %}
|
||||
<a
|
||||
href="{{ site.baseurl }}{{ page.previous.url }}"
|
||||
class="btn btn-outline-primary"
|
||||
prompt="{{ site.data.locales[include.lang].post.button.previous }}"
|
||||
aria-label="{{ previous }}"
|
||||
>
|
||||
<p>{{ page.previous.title }}</p>
|
||||
</a>
|
||||
{% else %}
|
||||
<div
|
||||
class="btn btn-outline-primary disabled"
|
||||
prompt="{{ site.data.locales[include.lang].post.button.previous }}"
|
||||
>
|
||||
<div class="btn btn-outline-primary disabled" aria-label="{{ previous }}">
|
||||
<p>-</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -22,16 +22,13 @@
|
||||
<a
|
||||
href="{{ site.baseurl }}{{page.next.url}}"
|
||||
class="btn btn-outline-primary"
|
||||
prompt="{{ site.data.locales[include.lang].post.button.next }}"
|
||||
aria-label="{{ next }}"
|
||||
>
|
||||
<p>{{ page.next.title }}</p>
|
||||
</a>
|
||||
{% else %}
|
||||
<div
|
||||
class="btn btn-outline-primary disabled"
|
||||
prompt="{{ site.data.locales[include.lang].post.button.next }}"
|
||||
>
|
||||
<div class="btn btn-outline-primary disabled" aria-label="{{ next }}">
|
||||
<p>-</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
@@ -1,89 +1,91 @@
|
||||
<!-- The paginator for post list on HomgPage. -->
|
||||
|
||||
<ul class="pagination align-items-center my-4 ps-lg-2">
|
||||
<!-- left arrow -->
|
||||
{% if paginator.previous_page %}
|
||||
{% assign prev_url = paginator.previous_page_path | relative_url %}
|
||||
{% else %}
|
||||
{% assign prev_url = '#' %}
|
||||
{% endif %}
|
||||
|
||||
<li class="page-item {% unless paginator.previous_page %}disabled{% endunless %}">
|
||||
<a class="page-link btn-box-shadow" href="{{ prev_url }}" aria-label="previous-page">
|
||||
<i class="fas fa-angle-left"></i>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<!-- page numbers -->
|
||||
{% assign left_ellipsis = false %}
|
||||
{% assign right_ellipsis = false %}
|
||||
|
||||
{% for i in (1..paginator.total_pages) %}
|
||||
{% assign pre = paginator.page | minus: 1 %}
|
||||
{% assign next = paginator.page | plus: 1 %}
|
||||
{% assign pre_less = pre | minus: 1 %}
|
||||
{% assign next_more = next | plus: 1 %}
|
||||
{% assign show = false %}
|
||||
|
||||
{% if paginator.page == 1 %}
|
||||
{% if i <= 3 or i == paginator.total_pages %}
|
||||
{% assign show = true %}
|
||||
{% endif %}
|
||||
{% elsif paginator.page == paginator.total_pages %}
|
||||
{% if i == 1 or i >= pre_less %}
|
||||
{% assign show = true %}
|
||||
{% endif %}
|
||||
<nav aria-label="Page Navigation">
|
||||
<ul class="pagination align-items-center mt-4 mb-0">
|
||||
<!-- left arrow -->
|
||||
{% if paginator.previous_page %}
|
||||
{% assign prev_url = paginator.previous_page_path | relative_url %}
|
||||
{% else %}
|
||||
{% if i == 1 or i == paginator.total_pages %}
|
||||
{% assign show = true %}
|
||||
{% elsif i >= pre and i <= next %}
|
||||
{% assign show = true %}
|
||||
{% endif %}
|
||||
{% assign prev_url = '#' %}
|
||||
{% endif %}
|
||||
|
||||
{% if show %}
|
||||
<!-- show number -->
|
||||
<li class="page-item {% if i == paginator.page %} active{% endif %}">
|
||||
<a
|
||||
class="page-link btn-box-shadow"
|
||||
href="{% if i > 1 %}{{ site.paginate_path | replace: ':num', i | relative_url }}{% else %}{{ '/' | relative_url }}{% endif %}"
|
||||
>
|
||||
{{- i -}}
|
||||
</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<!-- hide number -->
|
||||
{% if i < pre and left_ellipsis == false %}
|
||||
<li class="page-item disabled">
|
||||
<span class="page-link btn-box-shadow">...</span>
|
||||
</li>
|
||||
{% assign left_ellipsis = true %}
|
||||
{% elsif i > next and right_ellipsis == false %}
|
||||
<li class="page-item disabled">
|
||||
<span class="page-link btn-box-shadow">...</span>
|
||||
</li>
|
||||
{% assign right_ellipsis = true %}
|
||||
<li class="page-item {% unless paginator.previous_page %}disabled{% endunless %}">
|
||||
<a class="page-link" href="{{ prev_url }}" aria-label="previous-page">
|
||||
<i class="fas fa-angle-left"></i>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<!-- page numbers -->
|
||||
{% assign left_ellipsis = false %}
|
||||
{% assign right_ellipsis = false %}
|
||||
|
||||
{% for i in (1..paginator.total_pages) %}
|
||||
{% assign pre = paginator.page | minus: 1 %}
|
||||
{% assign next = paginator.page | plus: 1 %}
|
||||
{% assign pre_less = pre | minus: 1 %}
|
||||
{% assign next_more = next | plus: 1 %}
|
||||
{% assign show = false %}
|
||||
|
||||
{% if paginator.page == 1 %}
|
||||
{% if i <= 3 or i == paginator.total_pages %}
|
||||
{% assign show = true %}
|
||||
{% endif %}
|
||||
{% elsif paginator.page == paginator.total_pages %}
|
||||
{% if i == 1 or i >= pre_less %}
|
||||
{% assign show = true %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if i == 1 or i == paginator.total_pages %}
|
||||
{% assign show = true %}
|
||||
{% elsif i >= pre and i <= next %}
|
||||
{% assign show = true %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if show %}
|
||||
<!-- show number -->
|
||||
<li class="page-item {% if i == paginator.page %} active{% endif %}">
|
||||
<a
|
||||
class="page-link"
|
||||
href="{% if i > 1 %}{{ site.paginate_path | replace: ':num', i | relative_url }}{% else %}{{ '/' | relative_url }}{% endif %}"
|
||||
>
|
||||
{{- i -}}
|
||||
</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<!-- hide number -->
|
||||
{% if i < pre and left_ellipsis == false %}
|
||||
<li class="page-item disabled">
|
||||
<span class="page-link">...</span>
|
||||
</li>
|
||||
{% assign left_ellipsis = true %}
|
||||
{% elsif i > next and right_ellipsis == false %}
|
||||
<li class="page-item disabled">
|
||||
<span class="page-link">...</span>
|
||||
</li>
|
||||
{% assign right_ellipsis = true %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
<!-- mobile pagination -->
|
||||
<li class="page-index align-middle">
|
||||
<span>{{ paginator.page }}</span>
|
||||
<span class="text-muted">/ {{ paginator.total_pages }}</span>
|
||||
</li>
|
||||
|
||||
<!-- right arrow -->
|
||||
{% if paginator.next_page_path %}
|
||||
{% assign next_url = paginator.next_page_path | relative_url %}
|
||||
{% else %}
|
||||
{% assign next_url = '#' %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
<!-- mobile pagination -->
|
||||
<li class="page-index align-middle">
|
||||
<span>{{ paginator.page }}</span>
|
||||
<span class="text-muted">/ {{ paginator.total_pages }}</span>
|
||||
</li>
|
||||
|
||||
<!-- right arrow -->
|
||||
{% if paginator.next_page_path %}
|
||||
{% assign next_url = paginator.next_page_path | relative_url %}
|
||||
{% else %}
|
||||
{% assign next_url = '#' %}
|
||||
{% endif %}
|
||||
|
||||
<li class="page-item {% unless paginator.next_page_path %}disabled{% endunless %}">
|
||||
<a class="page-link btn-box-shadow" href="{{ next_url }}" aria-label="next-page">
|
||||
<i class="fas fa-angle-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<li class="page-item {% unless paginator.next_page_path %}disabled{% endunless %}">
|
||||
<a class="page-link" href="{{ next_url }}" aria-label="next-page">
|
||||
<i class="fas fa-angle-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<!-- .pagination -->
|
||||
|
||||
@@ -1,35 +1,52 @@
|
||||
<!-- Post sharing snippet -->
|
||||
|
||||
<div class="share-wrapper">
|
||||
<span class="share-label text-muted me-1">{{ site.data.locales[include.lang].post.share }}</span>
|
||||
<div class="share-wrapper d-flex align-items-center">
|
||||
<span class="share-label text-muted">{{ site.data.locales[include.lang].post.share }}</span>
|
||||
<span class="share-icons">
|
||||
{% capture title %}{{ page.title }} - {{ site.title }}{% endcapture %}
|
||||
{% assign title = title | uri_escape %}
|
||||
{% assign url = page.url | absolute_url | url_encode %}
|
||||
|
||||
{% for share in site.data.share.platforms %}
|
||||
{% for share in site.data.share.platforms -%}
|
||||
{%- capture tooltip -%}
|
||||
data-bs-toggle="tooltip" data-bs-placement="top" title="{{ share.type }}" aria-label="{{ share.type }}"
|
||||
{%- endcapture -%}
|
||||
|
||||
{% if share.type == 'Mastodon' %}
|
||||
<script defer type="module" src="https://cdn.jsdelivr.net/npm/@justinribeiro/share-to-mastodon/+esm"></script>
|
||||
<button class="btn text-start" {{ tooltip }}>
|
||||
<share-to-mastodon
|
||||
class="share-mastodon"
|
||||
message="{{ title }}"
|
||||
url="{{ url }}"
|
||||
{%- if share.instances -%}
|
||||
customInstanceList="{{ share.instances | jsonify | xml_escape }}"
|
||||
{%- endif %}
|
||||
>
|
||||
<i class="fa-fw {{ share.icon }}"></i>
|
||||
</share-to-mastodon>
|
||||
</button>
|
||||
|
||||
{% continue %}
|
||||
{% endif %}
|
||||
|
||||
{% assign link = share.link | replace: 'TITLE', title | replace: 'URL', url %}
|
||||
<a
|
||||
href="{{ link }}"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
title="{{ share.type }}"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
aria-label="{{ share.type }}"
|
||||
>
|
||||
|
||||
<a href="{{ link }}" target="_blank" rel="noopener" {{ tooltip }}>
|
||||
<i class="fa-fw {{ share.icon }}"></i>
|
||||
</a>
|
||||
{% endfor %}
|
||||
|
||||
<i
|
||||
<button
|
||||
id="copy-link"
|
||||
class="fa-fw fas fa-link small"
|
||||
aria-label="Copy link"
|
||||
class="btn small"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
title="{{ site.data.locales[include.lang].post.button.share_link.title }}"
|
||||
data-title-succeed="{{ site.data.locales[include.lang].post.button.share_link.succeed }}"
|
||||
>
|
||||
</i>
|
||||
<i class="fa-fw fas fa-link pe-none fs-6"></i>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
<!--
|
||||
Refactor the HTML structure.
|
||||
-->
|
||||
<!-- Refactor the HTML structure -->
|
||||
|
||||
{% assign _content = include.content %}
|
||||
|
||||
@@ -32,41 +30,24 @@
|
||||
{% endif %}
|
||||
|
||||
<!-- Change the icon of checkbox -->
|
||||
|
||||
{% if _content contains '<input type="checkbox"' %}
|
||||
{% assign _content = _content
|
||||
| replace:
|
||||
'<input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />',
|
||||
'<i class="fas fa-check-circle fa-fw checked"></i>'
|
||||
| replace:
|
||||
'<input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />',
|
||||
'<i class="far fa-circle fa-fw"></i>'
|
||||
| replace: '<input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />',
|
||||
'<i class="fas fa-check-circle fa-fw checked"></i>'
|
||||
| replace: '<input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />',
|
||||
'<i class="far fa-circle fa-fw"></i>'
|
||||
%}
|
||||
{% endif %}
|
||||
|
||||
<!-- images -->
|
||||
<!-- Handle images -->
|
||||
|
||||
{% if _content contains '<img' %}
|
||||
{% assign IMG_TAG = '<img ' %}
|
||||
{% assign _img_content = nil %}
|
||||
{% assign IMG_TAG = '<img ' %}
|
||||
|
||||
{% if _content contains IMG_TAG %}
|
||||
{% assign _img_content = null %}
|
||||
{% assign _img_snippets = _content | split: IMG_TAG %}
|
||||
|
||||
<!-- CDN URL -->
|
||||
{% if site.img_cdn %}
|
||||
{% if site.img_cdn contains '//' %}
|
||||
{% assign _path_prefix = site.img_cdn %}
|
||||
{% else %}
|
||||
{% assign _path_prefix = site.img_cdn | relative_url %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% assign _path_prefix = site.baseurl %}
|
||||
{% endif %}
|
||||
|
||||
<!-- Add image path -->
|
||||
{% if page.img_path %}
|
||||
{% assign _path = page.img_path | append: '/' | replace: '//', '/' %}
|
||||
{% assign _path_prefix = _path_prefix | append: _path %}
|
||||
{% endif %}
|
||||
|
||||
{% for _img_snippet in _img_snippets %}
|
||||
{% if forloop.first %}
|
||||
{% assign _img_content = _img_snippet %}
|
||||
@@ -83,10 +64,9 @@
|
||||
{% assign _left = _left | remove: ' /' | replace: ' w=', ' width=' | replace: ' h=', ' height=' %}
|
||||
{% assign _attrs = _left | split: '" ' %}
|
||||
|
||||
{% assign _width = nil %}
|
||||
{% assign _height = nil %}
|
||||
{% assign _lqip = nil %}
|
||||
{% assign _class = nil %}
|
||||
{% assign _src = null %}
|
||||
{% assign _lqip = null %}
|
||||
{% assign _class = null %}
|
||||
|
||||
{% for _attr in _attrs %}
|
||||
{% unless _attr contains '=' %}
|
||||
@@ -98,10 +78,6 @@
|
||||
{% capture _value %}{{ _pair | last | remove: '"' }}{% endcapture %}
|
||||
|
||||
{% case _key %}
|
||||
{% when 'width' %}
|
||||
{% assign _width = _value %}
|
||||
{% when 'height' %}
|
||||
{% assign _height = _value %}
|
||||
{% when 'src' %}
|
||||
{% assign _src = _value %}
|
||||
{% when 'lqip' %}
|
||||
@@ -117,50 +93,50 @@
|
||||
{% assign _left = _left | remove: _old_class %}
|
||||
{% endif %}
|
||||
|
||||
{% assign _final_src = nil %}
|
||||
{% assign _final_src = null %}
|
||||
{% assign _lazyload = true %}
|
||||
|
||||
{%- capture _img_url -%}
|
||||
{% include img-url.html src=_src img_path=page.img_path %}
|
||||
{%- endcapture -%}
|
||||
|
||||
{% assign _path_prefix = _img_url | remove: _src %}
|
||||
|
||||
{% unless _src contains '//' %}
|
||||
{% assign _final_src = _path_prefix | append: _src %}
|
||||
{% capture _src_from %}"{{ _src }}"{% endcapture %}
|
||||
{% capture _src_to %}"{{ _final_src }}"{% endcapture %}
|
||||
{% assign _left = _left | replace: _src_from, _src_to %}
|
||||
{% assign _src_alt = 'src="' | append: _path_prefix %}
|
||||
{% assign _left = _left | replace: 'src="', _src_alt %}
|
||||
{% endunless %}
|
||||
|
||||
{% if _lqip %}
|
||||
{% unless _lqip contains ':' %}
|
||||
{% assign _final_lqip = _path_prefix | append: _lqip %}
|
||||
{% capture _lqip_from %}"{{ _lqip }}"{% endcapture %}
|
||||
{% capture _lqip_to %}"{{ _final_lqip }}"{% endcapture %}
|
||||
{% assign _left = _left | replace: _lqip_from, _lqip_to %}
|
||||
{% assign _lazyload = false %}
|
||||
{% assign _class = _class | append: ' blur' %}
|
||||
|
||||
{% unless _lqip contains 'data:' %}
|
||||
{% assign _lqip_alt = 'lqip="' | append: _path_prefix %}
|
||||
{% assign _left = _left | replace: 'lqip="', _lqip_alt %}
|
||||
{% endunless %}
|
||||
{% endif %}
|
||||
|
||||
<!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
|
||||
{% assign _left = _left | replace: 'src=', 'data-src=' %}
|
||||
{% if _left contains 'class=' %}
|
||||
{% assign _left = _left | replace: 'class="', 'class="lazyload '%}
|
||||
<!-- add image placeholder -->
|
||||
{% assign _left = _left | replace: 'src=', 'data-src=' | replace: ' lqip=', ' data-lqip="true" src=' %}
|
||||
|
||||
{% else %}
|
||||
{% assign _left = _left | append: ' class="lazyload"' %}
|
||||
{% assign _class = _class | append: ' shimmer' %}
|
||||
{% endif %}
|
||||
|
||||
<!-- add image placeholder -->
|
||||
{% if _lqip %}
|
||||
{% assign _left = _left | replace: ' lqip=', ' data-lqip="true" src=' %}
|
||||
<!-- lazy-load images -->
|
||||
{% if _lazyload %}
|
||||
{% assign _left = _left | append: ' loading="lazy"' %}
|
||||
{% endif %}
|
||||
|
||||
{% if page.layout == 'home' %}
|
||||
<!-- create the image wrapper -->
|
||||
{% assign _wrapper_start = '<div class="preview-img ' | append: _class | append: '">' %}
|
||||
|
||||
{% assign _img_content = _img_content | append: _wrapper_start %}
|
||||
{% assign _right = _right | prepend: '></div' %}
|
||||
|
||||
{% else %}
|
||||
{% if _width and _height %}
|
||||
<!-- add SVG placehoder -->
|
||||
{%- capture _svg -%}
|
||||
src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 {{ _width }} {{ _height }}'%3E%3C/svg%3E"
|
||||
{%- endcapture -%}
|
||||
{% assign _left = _svg | append: ' ' | append: _left %}
|
||||
{% assign _class = _class | append: ' shimmer' %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<!-- Bypass the HTML-proofer test -->
|
||||
{% assign _left = _left | append: ' data-proofer-ignore' %}
|
||||
|
||||
{% if page.layout == 'post' %}
|
||||
<!-- make sure the `<img>` is wrapped by `<a>` -->
|
||||
{% assign _parent = _right | slice: 1, 4 %}
|
||||
|
||||
@@ -170,36 +146,30 @@
|
||||
{% capture _class %}
|
||||
class="img-link{% unless _lqip %} shimmer{% endunless %}"
|
||||
{% endcapture %}
|
||||
{% assign _img_content = _img_content | slice: 0, _size | append: _class | append: '>' %}
|
||||
{% assign _img_content = _img_content | slice: 0, _size | append: _class | append: '>' %}
|
||||
|
||||
{% else %}
|
||||
<!-- create the image wrapper -->
|
||||
{%- capture _wrapper_start -%}
|
||||
<a href="{{ _final_src | default: _src }}" class="popup img-link {{ _class }}">
|
||||
{%- endcapture -%}
|
||||
{% assign _wrapper_start = _final_src
|
||||
| default: _src
|
||||
| prepend: '<a href="'
|
||||
| append: '" class="popup img-link '
|
||||
| append: _class
|
||||
| append: '">'
|
||||
%}
|
||||
|
||||
{% assign _img_content = _img_content | append: _wrapper_start %}
|
||||
{% assign _right = _right | prepend: '></a' %}
|
||||
{% assign _right = '></a' | append: _right %}
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if page.layout == 'home' %}
|
||||
<!-- create the image wrapper -->
|
||||
{%- capture _wrapper_start -%}
|
||||
<div class="preview-img {{ _class | strip }}">
|
||||
{%- endcapture -%}
|
||||
{% assign _img_content = _img_content | append: _wrapper_start %}
|
||||
{% assign _right = _right | prepend: '></div' %}
|
||||
{% endif %}
|
||||
|
||||
<!-- combine -->
|
||||
{% assign _img_content = _img_content | append: debug | append: IMG_TAG | append: _left | append: _right %}
|
||||
|
||||
{% assign _img_content = _img_content | append: IMG_TAG | append: _left | append: _right %}
|
||||
{% endfor %}
|
||||
|
||||
{% if _img_content %}
|
||||
{% assign _content = _img_content %}
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
<!-- Add header for code snippets -->
|
||||
@@ -209,13 +179,11 @@
|
||||
{% assign _new_content = '' %}
|
||||
|
||||
{% for _snippet in _code_spippets %}
|
||||
|
||||
{% if forloop.last %}
|
||||
{% assign _new_content = _new_content | append: _snippet %}
|
||||
|
||||
{% else %}
|
||||
|
||||
{% assign _left = _snippet | split: '><' | last%}
|
||||
{% assign _left = _snippet | split: '><' | last %}
|
||||
|
||||
{% if _left contains 'file="' %}
|
||||
{% assign _label_text = _left | split: 'file="' | last | split: '"' | first %}
|
||||
@@ -230,21 +198,19 @@
|
||||
<span data-label-text="{{ _label_text | strip }}"><i class="{{ _label_icon }}"></i></span>
|
||||
{% endcapture %}
|
||||
|
||||
{% assign _new_content = _new_content | append: _snippet
|
||||
| append: '<div class="code-header">'
|
||||
| append: _label
|
||||
| append: '<button aria-label="copy" data-title-succeed="'
|
||||
| append: site.data.locales[include.lang].post.button.copy_code.succeed
|
||||
| append: '"><i class="far fa-clipboard"></i></button></div>'
|
||||
| append: '<div class="highlight"><code>'
|
||||
{% assign _new_content = _new_content
|
||||
| append: _snippet
|
||||
| append: '<div class="code-header">'
|
||||
| append: _label
|
||||
| append: '<button aria-label="copy" data-title-succeed="'
|
||||
| append: site.data.locales[include.lang].post.button.copy_code.succeed
|
||||
| append: '"><i class="far fa-clipboard"></i></button></div>'
|
||||
| append: '<div class="highlight"><code>'
|
||||
%}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{% assign _content = _new_content %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
<!-- Create heading anchors -->
|
||||
@@ -253,11 +219,11 @@
|
||||
{% assign _heading_content = _content %}
|
||||
|
||||
{% for level in heading_levels %}
|
||||
{% capture mark_start %}<h{{ level }} id="{% endcapture %}
|
||||
{% capture mark_end %}</h{{ level }}>{% endcapture %}
|
||||
{% assign mark_start = '<h' | append: level | append: ' id="' %}
|
||||
{% assign mark_end = '</h' | append: level | append: '>' %}
|
||||
|
||||
{% if _heading_content contains mark_start %}
|
||||
{% assign _new_content = nil %}
|
||||
{% assign _new_content = null %}
|
||||
{% assign heading_snippets = _heading_content | split: mark_start %}
|
||||
|
||||
{% for snippet in heading_snippets %}
|
||||
@@ -267,20 +233,19 @@
|
||||
{% endif %}
|
||||
|
||||
{% assign id = snippet | split: '"' | first %}
|
||||
{% capture anchor %}<a href="#{{ id }}" class="anchor text-muted"><i class="fas fa-hashtag"></i></a>{% endcapture %}
|
||||
{% assign anchor = '<a href="#'
|
||||
| append: id
|
||||
| append: '" class="anchor text-muted"><i class="fas fa-hashtag"></i></a>'
|
||||
%}
|
||||
|
||||
{% assign left = snippet | split: mark_end | first %}
|
||||
{% assign right = snippet | slice: left.size, snippet.size %}
|
||||
{% assign left = left | replace_first: '">', '"><span class="me-2">' | append: '</span>' %}
|
||||
|
||||
{% assign _new_content = _new_content | append: mark_start
|
||||
| append: left | append: anchor | append: right
|
||||
%}
|
||||
|
||||
{% assign _new_content = _new_content | append: mark_start | append: left | append: anchor | append: right %}
|
||||
{% endfor %}
|
||||
|
||||
{% assign _heading_content = _new_content %}
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
<!--
|
||||
Recommend the other 3 posts according to the tags and categories of the current post,
|
||||
if the number is not enough, use the other latest posts to supplement.
|
||||
-->
|
||||
<!-- Recommend the other 3 posts according to the tags and categories of the current post. -->
|
||||
|
||||
<!-- The total size of related posts -->
|
||||
{% assign TOTAL_SIZE = 3 %}
|
||||
@@ -14,11 +11,21 @@
|
||||
|
||||
{% assign SEPARATOR = ':' %}
|
||||
|
||||
{% assign match_posts = '' | split: '' %}
|
||||
|
||||
{% for category in page.categories %}
|
||||
{% assign match_posts = match_posts | push: site.categories[category] | uniq %}
|
||||
{% endfor %}
|
||||
|
||||
{% for tag in page.tags %}
|
||||
{% assign match_posts = match_posts | push: site.tags[tag] | uniq %}
|
||||
{% endfor %}
|
||||
|
||||
{% assign last_index = match_posts.size | minus: 1 %}
|
||||
{% assign score_list = '' | split: '' %}
|
||||
{% assign last_index = site.posts.size | minus: 1 %}
|
||||
|
||||
{% for i in (0..last_index) %}
|
||||
{% assign post = site.posts[i] %}
|
||||
{% assign post = match_posts[i] %}
|
||||
|
||||
{% if post.url == page.url %}
|
||||
{% continue %}
|
||||
@@ -54,40 +61,26 @@
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
<!-- Fill with the other newlest posts -->
|
||||
{% assign less = TOTAL_SIZE | minus: index_list.size %}
|
||||
{% assign relate_posts = '' | split: '' %}
|
||||
|
||||
{% if less > 0 %}
|
||||
{% for i in (0..last_index) %}
|
||||
{% assign post = site.posts[i] %}
|
||||
{% if post.url != page.url %}
|
||||
{% capture cur_index %}{{ i }}{% endcapture %}
|
||||
{% unless index_list contains cur_index %}
|
||||
{% assign index_list = index_list | push: cur_index %}
|
||||
{% assign less = less | minus: 1 %}
|
||||
{% if less <= 0 %}
|
||||
{% break %}
|
||||
{% endif %}
|
||||
{% endunless %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% for index in index_list %}
|
||||
{% assign i = index | to_integer %}
|
||||
{% assign relate_posts = relate_posts | push: match_posts[i] %}
|
||||
{% endfor %}
|
||||
|
||||
{% if index_list.size > 0 %}
|
||||
<div id="related-posts" class="mb-2 mb-sm-4">
|
||||
<h3 class="pt-2 mb-4 ms-1" data-toc-skip>
|
||||
{{ site.data.locales[include.lang].post.relate_posts }}
|
||||
{% if relate_posts.size > 0 %}
|
||||
<aside id="related-posts" aria-labelledby="related-label">
|
||||
<h3 class="mb-4" id="related-label">
|
||||
{{- site.data.locales[include.lang].post.relate_posts -}}
|
||||
</h3>
|
||||
<div class="row row-cols-1 row-cols-md-2 row-cols-xl-3 g-4 mb-4">
|
||||
{% for entry in index_list %}
|
||||
{% assign index = entry | plus: 0 %}
|
||||
{% assign post = site.posts[index] %}
|
||||
<div class="col">
|
||||
<a href="{{ post.url | relative_url }}" class="card post-preview h-100">
|
||||
<nav class="row row-cols-1 row-cols-md-2 row-cols-xl-3 g-4 mb-4">
|
||||
{% for post in relate_posts %}
|
||||
<article class="col">
|
||||
<a href="{{ post.url | relative_url }}" class="post-preview card h-100">
|
||||
<div class="card-body">
|
||||
{% include datetime.html date=post.date class="small" lang=include.lang %}
|
||||
<h4 class="pt-0 my-2" data-toc-skip>{{ post.title }}</h4>
|
||||
<div class="text-muted small">
|
||||
{% include datetime.html date=post.date lang=include.lang %}
|
||||
<h4 class="pt-0 my-2">{{ post.title }}</h4>
|
||||
<div class="text-muted">
|
||||
<p>
|
||||
{% include no-linenos.html content=post.content %}
|
||||
{{ content | markdownify | strip_html | truncate: 200 | escape }}
|
||||
@@ -95,10 +88,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</article>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- .card-deck -->
|
||||
</div>
|
||||
</nav>
|
||||
</aside>
|
||||
<!-- #related-posts -->
|
||||
{% endif %}
|
||||
|
||||
@@ -4,14 +4,16 @@
|
||||
-->
|
||||
|
||||
{% capture result_elem %}
|
||||
<div class="px-1 px-sm-2 px-lg-4 px-xl-0">
|
||||
<a href="{url}">{title}</a>
|
||||
<div class="post-meta d-flex flex-column flex-sm-row text-muted mt-1 mb-1">
|
||||
{categories}
|
||||
{tags}
|
||||
</div>
|
||||
<p>{snippet}</p>
|
||||
</div>
|
||||
<article class="px-1 px-sm-2 px-lg-4 px-xl-0">
|
||||
<header>
|
||||
<h2><a href="{url}">{title}</a></h2>
|
||||
<div class="post-meta d-flex flex-column flex-sm-row text-muted mt-1 mb-1">
|
||||
{categories}
|
||||
{tags}
|
||||
</div>
|
||||
</header>
|
||||
<p>{snippet}</p>
|
||||
</article>
|
||||
{% endcapture %}
|
||||
|
||||
{% capture not_found %}<p class="mt-5">{{ site.data.locales[include.lang].search.no_results }}</p>{% endcapture %}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<!-- The Search results -->
|
||||
|
||||
<div id="search-result-wrapper" class="d-flex justify-content-center unloaded">
|
||||
<div class="col-11 post-content">
|
||||
<div class="col-11 content">
|
||||
<div id="search-hints">
|
||||
{% include trending-tags.html %}
|
||||
{% include_cached trending-tags.html %}
|
||||
</div>
|
||||
<div id="search-results" class="d-flex flex-wrap justify-content-center text-muted mt-3"></div>
|
||||
</div>
|
||||
|
||||
@@ -1,55 +1,50 @@
|
||||
<!-- The Side Bar -->
|
||||
|
||||
<div id="sidebar" class="d-flex flex-column align-items-end">
|
||||
<div class="profile-wrapper">
|
||||
<aside aria-label="Sidebar" id="sidebar" class="d-flex flex-column align-items-end">
|
||||
<header class="profile-wrapper">
|
||||
<a href="{{ '/' | relative_url }}" id="avatar" class="rounded-circle">
|
||||
{% if site.avatar != empty and site.avatar %}
|
||||
{% capture avatar_url %}
|
||||
{% if site.avatar contains '://' %}
|
||||
{{ site.avatar }}
|
||||
{% elsif site.img_cdn != empty and site.img_cdn %}
|
||||
{{ site.avatar | prepend: site.img_cdn }}
|
||||
{% else %}
|
||||
{{ site.avatar | relative_url }}
|
||||
{% endif %}
|
||||
{% endcapture %}
|
||||
<img src="{{ avatar_url | strip }}" width="112" height="112" alt="avatar" onerror="this.style.display='none'">
|
||||
{% endif %}
|
||||
{%- if site.avatar != empty and site.avatar -%}
|
||||
{%- capture avatar_url -%}
|
||||
{% include img-url.html src=site.avatar %}
|
||||
{%- endcapture -%}
|
||||
<img src="{{- avatar_url -}}" width="112" height="112" alt="avatar" onerror="this.style.display='none'">
|
||||
{%- endif -%}
|
||||
</a>
|
||||
|
||||
<div class="site-title">
|
||||
<h1 class="site-title">
|
||||
<a href="{{ '/' | relative_url }}">{{ site.title }}</a>
|
||||
</div>
|
||||
<div class="site-subtitle fst-italic">{{ site.tagline }}</div>
|
||||
</div>
|
||||
</h1>
|
||||
<p class="site-subtitle fst-italic mb-0">{{ site.tagline }}</p>
|
||||
</header>
|
||||
<!-- .profile-wrapper -->
|
||||
|
||||
<ul class="nav flex-column flex-grow-1 w-100 ps-0">
|
||||
<!-- home -->
|
||||
<li class="nav-item{% if page.layout == 'home' %}{{ " active" }}{% endif %}">
|
||||
<a href="{{ '/' | relative_url }}" class="nav-link">
|
||||
<i class="fa-fw fas fa-home"></i>
|
||||
<span>{{ site.data.locales[include.lang].tabs.home | upcase }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<!-- the real tabs -->
|
||||
{% for tab in site.tabs %}
|
||||
<li class="nav-item{% if tab.url == page.url %}{{ " active" }}{% endif %}">
|
||||
<a href="{{ tab.url | relative_url }}" class="nav-link">
|
||||
<i class="fa-fw {{ tab.icon }}"></i>
|
||||
{% capture tab_name %}{{ tab.url | split: '/' }}{% endcapture %}
|
||||
|
||||
<span>{{ site.data.locales[include.lang].tabs.[tab_name] | default: tab.title | upcase }}</span>
|
||||
<nav class="flex-column flex-grow-1 w-100 ps-0">
|
||||
<ul class="nav">
|
||||
<!-- home -->
|
||||
<li class="nav-item{% if page.layout == 'home' %}{{ " active" }}{% endif %}">
|
||||
<a href="{{ '/' | relative_url }}" class="nav-link">
|
||||
<i class="fa-fw fas fa-home"></i>
|
||||
<span>{{ site.data.locales[include.lang].tabs.home | upcase }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<!-- .nav-item -->
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<!-- ul.nav.flex-column -->
|
||||
<!-- the real tabs -->
|
||||
{% for tab in site.tabs %}
|
||||
<li class="nav-item{% if tab.url == page.url %}{{ " active" }}{% endif %}">
|
||||
<a href="{{ tab.url | relative_url }}" class="nav-link">
|
||||
<i class="fa-fw {{ tab.icon }}"></i>
|
||||
{% capture tab_name %}{{ tab.url | split: '/' }}{% endcapture %}
|
||||
|
||||
<span>{{ site.data.locales[include.lang].tabs.[tab_name] | default: tab.title | upcase }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<!-- .nav-item -->
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<div class="sidebar-bottom d-flex flex-wrap align-items-center w-100">
|
||||
{% unless site.theme_mode %}
|
||||
<button class="mode-toggle btn" aria-label="Switch Mode">
|
||||
<button type="button" class="mode-toggle btn" aria-label="Switch Mode">
|
||||
<i class="fas fa-adjust"></i>
|
||||
</button>
|
||||
|
||||
@@ -100,5 +95,5 @@
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- .sidebar-bottom -->
|
||||
</div>
|
||||
</aside>
|
||||
<!-- #sidebar -->
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
{% endif %}
|
||||
|
||||
{% if enable_toc %}
|
||||
<div id="toc-wrapper" class="ps-0 pe-4 mb-5">
|
||||
<div class="panel-heading ps-3 pt-2 mb-2">{{- site.data.locales[include.lang].panel.toc -}}</div>
|
||||
<section id="toc-wrapper" class="ps-0 pe-4">
|
||||
<h2 class="panel-heading ps-3 pt-2 mb-2">{{- site.data.locales[include.lang].panel.toc -}}</h2>
|
||||
<nav id="toc"></nav>
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<!-- The Top Bar -->
|
||||
|
||||
<div id="topbar-wrapper">
|
||||
<header id="topbar-wrapper" aria-label="Top Bar">
|
||||
<div
|
||||
id="topbar"
|
||||
class="container d-flex align-items-center justify-content-between h-100"
|
||||
class="d-flex align-items-center justify-content-between px-lg-3 h-100"
|
||||
>
|
||||
<span id="breadcrumb">
|
||||
<nav id="breadcrumb" aria-label="Breadcrumb">
|
||||
{% assign paths = page.url | split: '/' %}
|
||||
|
||||
{% if paths.size == 0 or page.layout == 'home' %}
|
||||
@@ -17,7 +17,7 @@
|
||||
{% if forloop.first %}
|
||||
<span>
|
||||
<a href="{{ '/' | relative_url }}">
|
||||
{{ site.data.locales[include.lang].tabs.home | capitalize }}
|
||||
{{- site.data.locales[include.lang].tabs.home | capitalize -}}
|
||||
</a>
|
||||
</span>
|
||||
|
||||
@@ -30,17 +30,19 @@
|
||||
|
||||
{% elsif page.layout == 'category' or page.layout == 'tag' %}
|
||||
<span>
|
||||
<a href="{{ item | relative_url }}">
|
||||
{{ site.data.locales[include.lang].tabs[item] | default: page.title }}
|
||||
<a href="{{ item | append: '/' | relative_url }}">
|
||||
{{- site.data.locales[include.lang].tabs[item] | default: page.title -}}
|
||||
</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</span>
|
||||
</nav>
|
||||
<!-- endof #breadcrumb -->
|
||||
|
||||
<i id="sidebar-trigger" class="fas fa-bars fa-fw"></i>
|
||||
<button type="button" id="sidebar-trigger" class="btn btn-link">
|
||||
<i class="fas fa-bars fa-fw"></i>
|
||||
</button>
|
||||
|
||||
<div id="topbar-title">
|
||||
{% if page.layout == 'home' %}
|
||||
@@ -53,8 +55,11 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<i id="search-trigger" class="fas fa-search fa-fw"></i>
|
||||
<span id="search-wrapper" class="align-items-center">
|
||||
<button type="button" id="search-trigger" class="btn btn-link">
|
||||
<i class="fas fa-search fa-fw"></i>
|
||||
</button>
|
||||
|
||||
<search class="align-items-center ms-3 ms-lg-0">
|
||||
<i class="fas fa-search fa-fw"></i>
|
||||
<input
|
||||
class="form-control"
|
||||
@@ -64,7 +69,9 @@
|
||||
autocomplete="off"
|
||||
placeholder="{{ site.data.locales[include.lang].search.hint | capitalize }}..."
|
||||
>
|
||||
</span>
|
||||
<span id="search-cancel">{{ site.data.locales[include.lang].search.cancel }}</span>
|
||||
</search>
|
||||
<button type="button" class="btn btn-link text-decoration-none" id="search-cancel">
|
||||
{{- site.data.locales[include.lang].search.cancel -}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -34,13 +34,13 @@
|
||||
{% endfor %}
|
||||
|
||||
{% if trending_tags.size > 0 %}
|
||||
<div id="access-tags">
|
||||
<div class="panel-heading">{{- site.data.locales[include.lang].panel.trending_tags -}}</div>
|
||||
<section>
|
||||
<h2 class="panel-heading">{{- site.data.locales[include.lang].panel.trending_tags -}}</h2>
|
||||
<div class="d-flex flex-wrap mt-3 mb-1 me-3">
|
||||
{% for tag_name in trending_tags %}
|
||||
{% assign url = tag_name | slugify | url_encode | prepend: '/tags/' | append: '/' %}
|
||||
<a class="post-tag btn btn-outline-primary" href="{{ url | relative_url }}">{{ tag_name }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
{% comment %}
|
||||
Get the last 5 posts from lastmod list.
|
||||
{% endcomment %}
|
||||
<!-- Get 5 last posted/updated posts -->
|
||||
|
||||
{% assign MAX_SIZE = 5 %}
|
||||
|
||||
{% assign all_list = '' | split: '' %}
|
||||
|
||||
{% for post in site.posts %}
|
||||
{% if post.last_modified_at and post.last_modified_at != post.date %}
|
||||
{% capture elem %}
|
||||
{{- post.last_modified_at | date: "%Y%m%d%H%M%S" -}}::{{- forloop.index0 -}}
|
||||
{% endcapture %}
|
||||
{% assign all_list = all_list | push: elem %}
|
||||
{% endif %}
|
||||
{% assign datetime = post.last_modified_at | default: post.date %}
|
||||
|
||||
{% capture elem %}
|
||||
{{- datetime | date: "%Y%m%d%H%M%S" -}}::{{- forloop.index0 -}}
|
||||
{% endcapture %}
|
||||
|
||||
{% assign all_list = all_list | push: elem %}
|
||||
{% endfor %}
|
||||
|
||||
{% assign all_list = all_list | sort | reverse %}
|
||||
@@ -24,18 +23,18 @@
|
||||
{% endfor %}
|
||||
|
||||
{% if update_list.size > 0 %}
|
||||
<div id="access-lastmod" class="post">
|
||||
<div class="panel-heading">{{- site.data.locales[include.lang].panel.lastmod -}}</div>
|
||||
<ul class="post-content ps-0 pb-1 ms-1 mt-2">
|
||||
<section id="access-lastmod">
|
||||
<h2 class="panel-heading">{{- site.data.locales[include.lang].panel.lastmod -}}</h2>
|
||||
<ul class="content list-unstyled ps-0 pb-1 ms-1 mt-2">
|
||||
{% for item in update_list %}
|
||||
{% assign index = item | split: '::' | last | plus: 0 %}
|
||||
{% assign post = site.posts[index] %}
|
||||
{% assign url = post.url | relative_url %}
|
||||
<li>
|
||||
<li class="text-truncate lh-lg">
|
||||
<a href="{{ url }}">{{ post.title }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
<!-- #access-lastmod -->
|
||||
{% endif %}
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
Chirpy v<%= pkg.version %> (<%= pkg.homepage %>)
|
||||
© 2019 <%= pkg.author %>
|
||||
<%= pkg.license %> Licensed
|
||||
Chirpy v<%= pkg.version %> | © 2019 <%= pkg.author %> | <%= pkg.license %> Licensed | <%= pkg.homepage %>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { basic, initSidebar, initTopbar } from './modules/layouts';
|
||||
import { initLocaleDatetime, imgLazy } from './modules/plugins';
|
||||
import { initLocaleDatetime, loadImg } from './modules/plugins';
|
||||
|
||||
basic();
|
||||
initSidebar();
|
||||
initTopbar();
|
||||
initLocaleDatetime();
|
||||
imgLazy();
|
||||
loadImg();
|
||||
|
||||
@@ -3,15 +3,18 @@
|
||||
*/
|
||||
|
||||
export function back2top() {
|
||||
$(window).on('scroll', () => {
|
||||
if ($(window).scrollTop() > 50) {
|
||||
$('#back-to-top').fadeIn();
|
||||
const $window = $(window);
|
||||
const $btn = $('#back-to-top');
|
||||
|
||||
$window.on('scroll', () => {
|
||||
if ($window.scrollTop() > 50) {
|
||||
$btn.fadeIn();
|
||||
} else {
|
||||
$('#back-to-top').fadeOut();
|
||||
$btn.fadeOut();
|
||||
}
|
||||
});
|
||||
|
||||
$('#back-to-top').on('click', () => {
|
||||
window.scrollTo(0, 0);
|
||||
$btn.on('click', () => {
|
||||
$window.scrollTop(0);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -99,7 +99,9 @@ export function initClipboard() {
|
||||
|
||||
/* --- Post link sharing --- */
|
||||
|
||||
$('#copy-link').on('click', (e) => {
|
||||
const btnCopyLink = $('#copy-link');
|
||||
|
||||
btnCopyLink.on('click', (e) => {
|
||||
let target = $(e.target);
|
||||
|
||||
if (isLocked(target)) {
|
||||
@@ -120,4 +122,9 @@ export function initClipboard() {
|
||||
}, TIMEOUT);
|
||||
});
|
||||
});
|
||||
|
||||
btnCopyLink.on('mouseleave', function (e) {
|
||||
const target = $(e.target);
|
||||
target.tooltip('hide');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
/**
|
||||
* Set up image lazy-load
|
||||
*/
|
||||
|
||||
export function imgLazy() {
|
||||
if ($('#core-wrapper img[data-src]') <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Stop shimmer when image loaded */
|
||||
document.addEventListener('lazyloaded', function (e) {
|
||||
const $img = $(e.target);
|
||||
$img.parent().removeClass('shimmer');
|
||||
});
|
||||
}
|
||||
61
_javascript/modules/components/img-loading.js
Normal file
61
_javascript/modules/components/img-loading.js
Normal file
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Setting up image lazy loading and LQIP switching
|
||||
*/
|
||||
|
||||
const ATTR_DATA_SRC = 'data-src';
|
||||
const ATTR_DATA_LQIP = 'data-lqip';
|
||||
|
||||
const cover = {
|
||||
SHIMMER: 'shimmer',
|
||||
BLUR: 'blur'
|
||||
};
|
||||
|
||||
function removeCover(clzss) {
|
||||
$(this).parent().removeClass(clzss);
|
||||
}
|
||||
|
||||
function handleImage() {
|
||||
if (!this.complete) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.hasAttribute(ATTR_DATA_LQIP)) {
|
||||
removeCover.call(this, cover.BLUR);
|
||||
} else {
|
||||
removeCover.call(this, cover.SHIMMER);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches the LQIP with the real image URL.
|
||||
*/
|
||||
function switchLQIP() {
|
||||
const $img = $(this);
|
||||
const src = $img.attr(ATTR_DATA_SRC);
|
||||
|
||||
$img.attr('src', encodeURI(src));
|
||||
$img.removeAttr(ATTR_DATA_SRC);
|
||||
}
|
||||
|
||||
export function loadImg() {
|
||||
const $images = $('article img');
|
||||
|
||||
if ($images.length) {
|
||||
$images.on('load', handleImage);
|
||||
}
|
||||
|
||||
// Images loaded from the browser cache do not trigger the 'load' event
|
||||
$('article img[loading="lazy"]').each(function () {
|
||||
if (this.complete) {
|
||||
removeCover.call(this, cover.SHIMMER);
|
||||
}
|
||||
});
|
||||
|
||||
// LQIPs set by the data URI or WebP will not trigger the 'load' event,
|
||||
// so manually convert the URI to the URL of a high-resolution image.
|
||||
const $lqips = $(`article img[${ATTR_DATA_LQIP}="true"]`);
|
||||
|
||||
if ($lqips.length) {
|
||||
$lqips.each(switchLQIP);
|
||||
}
|
||||
}
|
||||
@@ -1,248 +0,0 @@
|
||||
/**
|
||||
* Count page views form GA or local cache file.
|
||||
*
|
||||
* Dependencies:
|
||||
* - jQuery
|
||||
* - countUp.js <https://github.com/inorganik/countUp.js>
|
||||
*/
|
||||
|
||||
const getInitStatus = (function () {
|
||||
let hasInit = false;
|
||||
return () => {
|
||||
let ret = hasInit;
|
||||
if (!hasInit) {
|
||||
hasInit = true;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
})();
|
||||
|
||||
const PvOpts = (function () {
|
||||
function getContent(selector) {
|
||||
return $(selector).attr('content');
|
||||
}
|
||||
|
||||
function hasContent(selector) {
|
||||
let content = getContent(selector);
|
||||
return typeof content !== 'undefined' && content !== false;
|
||||
}
|
||||
|
||||
return {
|
||||
getProxyMeta() {
|
||||
return getContent('meta[name=pv-proxy-endpoint]');
|
||||
},
|
||||
getLocalMeta() {
|
||||
return getContent('meta[name=pv-cache-path]');
|
||||
},
|
||||
hasProxyMeta() {
|
||||
return hasContent('meta[name=pv-proxy-endpoint]');
|
||||
},
|
||||
hasLocalMeta() {
|
||||
return hasContent('meta[name=pv-cache-path]');
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
const PvStorage = (function () {
|
||||
const Keys = {
|
||||
KEY_PV: 'pv',
|
||||
KEY_PV_SRC: 'pv_src',
|
||||
KEY_CREATION: 'pv_created_date'
|
||||
};
|
||||
|
||||
const Source = {
|
||||
LOCAL: 'same-origin',
|
||||
PROXY: 'cors'
|
||||
};
|
||||
|
||||
function get(key) {
|
||||
return localStorage.getItem(key);
|
||||
}
|
||||
|
||||
function set(key, val) {
|
||||
localStorage.setItem(key, val);
|
||||
}
|
||||
|
||||
function saveCache(pv, src) {
|
||||
set(Keys.KEY_PV, pv);
|
||||
set(Keys.KEY_PV_SRC, src);
|
||||
set(Keys.KEY_CREATION, new Date().toJSON());
|
||||
}
|
||||
|
||||
return {
|
||||
keysCount() {
|
||||
return Object.keys(Keys).length;
|
||||
},
|
||||
hasCache() {
|
||||
return localStorage.getItem(Keys.KEY_PV) !== null;
|
||||
},
|
||||
getCache() {
|
||||
return JSON.parse(localStorage.getItem(Keys.KEY_PV));
|
||||
},
|
||||
saveLocalCache(pv) {
|
||||
saveCache(pv, Source.LOCAL);
|
||||
},
|
||||
saveProxyCache(pv) {
|
||||
saveCache(pv, Source.PROXY);
|
||||
},
|
||||
isExpired() {
|
||||
let date = new Date(get(Keys.KEY_CREATION));
|
||||
date.setHours(date.getHours() + 1); // per hour
|
||||
return Date.now() >= date.getTime();
|
||||
},
|
||||
isFromLocal() {
|
||||
return get(Keys.KEY_PV_SRC) === Source.LOCAL;
|
||||
},
|
||||
isFromProxy() {
|
||||
return get(Keys.KEY_PV_SRC) === Source.PROXY;
|
||||
},
|
||||
newerThan(pv) {
|
||||
return (
|
||||
PvStorage.getCache().totalsForAllResults['ga:pageviews'] >
|
||||
pv.totalsForAllResults['ga:pageviews']
|
||||
);
|
||||
},
|
||||
inspectKeys() {
|
||||
if (localStorage.length !== PvStorage.keysCount()) {
|
||||
localStorage.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
const key = localStorage.key(i);
|
||||
switch (key) {
|
||||
case Keys.KEY_PV:
|
||||
case Keys.KEY_PV_SRC:
|
||||
case Keys.KEY_CREATION:
|
||||
break;
|
||||
default:
|
||||
localStorage.clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
})(); /* PvStorage */
|
||||
|
||||
function countUp(min, max, destId) {
|
||||
if (min < max) {
|
||||
let numAnim = new CountUp(destId, min, max);
|
||||
if (!numAnim.error) {
|
||||
numAnim.start();
|
||||
} else {
|
||||
console.error(numAnim.error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function countPV(path, rows) {
|
||||
let count = 0;
|
||||
|
||||
if (typeof rows !== 'undefined') {
|
||||
for (let i = 0; i < rows.length; ++i) {
|
||||
const gaPath = rows[parseInt(i, 10)][0];
|
||||
if (gaPath === path) {
|
||||
/* path format see: site.permalink */
|
||||
count += parseInt(rows[parseInt(i, 10)][1], 10);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
function tacklePV(rows, path, elem, hasInit) {
|
||||
let count = countPV(path, rows);
|
||||
count = count === 0 ? 1 : count;
|
||||
|
||||
if (!hasInit) {
|
||||
elem.text(new Intl.NumberFormat().format(count));
|
||||
} else {
|
||||
const initCount = parseInt(elem.text().replace(/,/g, ''), 10);
|
||||
if (count > initCount) {
|
||||
countUp(initCount, count, elem.attr('id'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function displayPageviews(data) {
|
||||
if (typeof data === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
let hasInit = getInitStatus();
|
||||
const rows = data.rows; /* could be undefined */
|
||||
|
||||
if ($('.post').length > 0) {
|
||||
/* the post */
|
||||
const path = window.location.pathname;
|
||||
tacklePV(rows, path, $('#pv'), hasInit);
|
||||
}
|
||||
}
|
||||
|
||||
function fetchProxyPageviews() {
|
||||
if (PvOpts.hasProxyMeta()) {
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: PvOpts.getProxyMeta(),
|
||||
dataType: 'jsonp',
|
||||
success: (data) => {
|
||||
displayPageviews(data);
|
||||
PvStorage.saveProxyCache(JSON.stringify(data));
|
||||
},
|
||||
error: (jqXHR, textStatus, errorThrown) => {
|
||||
console.log(
|
||||
'Failed to load pageviews from proxy server: ' + errorThrown
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function fetchLocalPageviews(hasCache = false) {
|
||||
return fetch(PvOpts.getLocalMeta())
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
if (hasCache) {
|
||||
// The cache from the proxy will sometimes be more recent than the local one
|
||||
if (PvStorage.isFromProxy() && PvStorage.newerThan(data)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
displayPageviews(data);
|
||||
PvStorage.saveLocalCache(JSON.stringify(data));
|
||||
});
|
||||
}
|
||||
|
||||
export function initPageviews() {
|
||||
if ($('.pageviews').length <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
PvStorage.inspectKeys();
|
||||
|
||||
if (PvStorage.hasCache()) {
|
||||
displayPageviews(PvStorage.getCache());
|
||||
|
||||
if (PvStorage.isExpired()) {
|
||||
if (PvOpts.hasLocalMeta()) {
|
||||
fetchLocalPageviews(true).then(fetchProxyPageviews);
|
||||
} else {
|
||||
fetchProxyPageviews();
|
||||
}
|
||||
} else {
|
||||
if (PvStorage.isFromLocal()) {
|
||||
fetchProxyPageviews();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// no cached
|
||||
|
||||
if (PvOpts.hasLocalMeta()) {
|
||||
fetchLocalPageviews().then(fetchProxyPageviews);
|
||||
} else {
|
||||
fetchProxyPageviews();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,9 @@
|
||||
const $btnSbTrigger = $('#sidebar-trigger');
|
||||
const $btnSearchTrigger = $('#search-trigger');
|
||||
const $btnCancel = $('#search-cancel');
|
||||
const $content = $('#main>.row');
|
||||
const $content = $('#main-wrapper>.container>.row');
|
||||
const $topbarTitle = $('#topbar-title');
|
||||
const $searchWrapper = $('#search-wrapper');
|
||||
const $search = $('search');
|
||||
const $resultWrapper = $('#search-result-wrapper');
|
||||
const $results = $('#search-results');
|
||||
const $input = $('#search-input');
|
||||
@@ -39,13 +39,13 @@ class MobileSearchBar {
|
||||
$btnSbTrigger.addClass(C_UNLOADED);
|
||||
$topbarTitle.addClass(C_UNLOADED);
|
||||
$btnSearchTrigger.addClass(C_UNLOADED);
|
||||
$searchWrapper.addClass(C_FLEX);
|
||||
$search.addClass(C_FLEX);
|
||||
$btnCancel.addClass(C_LOADED);
|
||||
}
|
||||
|
||||
static off() {
|
||||
$btnCancel.removeClass(C_LOADED);
|
||||
$searchWrapper.removeClass(C_FLEX);
|
||||
$search.removeClass(C_FLEX);
|
||||
$btnSbTrigger.removeClass(C_UNLOADED);
|
||||
$topbarTitle.removeClass(C_UNLOADED);
|
||||
$btnSearchTrigger.removeClass(C_UNLOADED);
|
||||
@@ -55,7 +55,7 @@ class MobileSearchBar {
|
||||
class ResultSwitch {
|
||||
static on() {
|
||||
if (!ScrollBlocker.resultVisible) {
|
||||
// the block method must be called before $(#main) unloaded.
|
||||
// the block method must be called before $(#main-wrapper>.container) unloaded.
|
||||
ScrollBlocker.on();
|
||||
$resultWrapper.removeClass(C_UNLOADED);
|
||||
$content.addClass(C_UNLOADED);
|
||||
@@ -72,7 +72,7 @@ class ResultSwitch {
|
||||
$resultWrapper.addClass(C_UNLOADED);
|
||||
$content.removeClass(C_UNLOADED);
|
||||
|
||||
// now the release method must be called after $(#main) display
|
||||
// now the release method must be called after $(#main-wrapper>.container) display
|
||||
ScrollBlocker.off();
|
||||
|
||||
$input.val('');
|
||||
@@ -98,11 +98,11 @@ export function displaySearch() {
|
||||
});
|
||||
|
||||
$input.on('focus', function () {
|
||||
$searchWrapper.addClass(C_FOCUS);
|
||||
$search.addClass(C_FOCUS);
|
||||
});
|
||||
|
||||
$input.on('focusout', function () {
|
||||
$searchWrapper.removeClass(C_FOCUS);
|
||||
$search.removeClass(C_FOCUS);
|
||||
});
|
||||
|
||||
$input.on('input', () => {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
export function toc() {
|
||||
if (document.querySelector('#core-wrapper h2,#core-wrapper h3')) {
|
||||
if (document.querySelector('main h2, main h3')) {
|
||||
// see: https://github.com/tscanlin/tocbot#usage
|
||||
tocbot.init({
|
||||
tocSelector: '#toc',
|
||||
contentSelector: '.post-content',
|
||||
contentSelector: '.content',
|
||||
ignoreSelector: '[data-toc-skip]',
|
||||
headingSelector: 'h2, h3',
|
||||
headingSelector: 'h2, h3, h4',
|
||||
orderedList: false,
|
||||
scrollSmooth: false
|
||||
});
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
export { categoryCollapse } from './components/category-collapse';
|
||||
export { initClipboard } from './components/clipboard';
|
||||
export { imgLazy } from './components/img-lazyload';
|
||||
export { loadImg } from './components/img-loading';
|
||||
export { imgPopup } from './components/img-popup';
|
||||
export { initLocaleDatetime } from './components/locale-datetime';
|
||||
export { initPageviews } from './components/pageviews';
|
||||
export { toc } from './components/toc';
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { basic, initSidebar, initTopbar } from './modules/layouts';
|
||||
import { imgLazy, imgPopup, initClipboard } from './modules/plugins';
|
||||
import { loadImg, imgPopup, initClipboard } from './modules/plugins';
|
||||
|
||||
basic();
|
||||
initSidebar();
|
||||
initTopbar();
|
||||
imgLazy();
|
||||
loadImg();
|
||||
imgPopup();
|
||||
initClipboard();
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
import { basic, initSidebar, initTopbar } from './modules/layouts';
|
||||
import {
|
||||
imgLazy,
|
||||
loadImg,
|
||||
imgPopup,
|
||||
initLocaleDatetime,
|
||||
initClipboard,
|
||||
initPageviews,
|
||||
toc
|
||||
} from './modules/plugins';
|
||||
|
||||
basic();
|
||||
initSidebar();
|
||||
initTopbar();
|
||||
imgLazy();
|
||||
loadImg();
|
||||
imgPopup();
|
||||
initLocaleDatetime();
|
||||
initClipboard();
|
||||
toc();
|
||||
initPageviews();
|
||||
basic();
|
||||
|
||||
@@ -9,28 +9,27 @@ layout: page
|
||||
{% assign df_dayjs_m = site.data.locales[lang].df.archives.dayjs | default: '/ MM' %}
|
||||
|
||||
<div id="archives" class="pl-xl-3">
|
||||
{% for post in site.posts %}
|
||||
{% assign cur_year = post.date | date: '%Y' %}
|
||||
|
||||
{% for post in site.posts %}
|
||||
{% capture cur_year %}{{ post.date | date: "%Y" }}{% endcapture %}
|
||||
{% if cur_year != last_year %}
|
||||
{% unless forloop.first %}</ul>{% endunless %}
|
||||
|
||||
{% if cur_year != last_year %}
|
||||
{% unless forloop.first %}</ul>{% endunless %}
|
||||
<div class="year lead">{{ cur_year }}</div>
|
||||
<ul class="list-unstyled">
|
||||
{% assign last_year = cur_year %}
|
||||
{% endif %}
|
||||
<time class="year lead d-block">{{ cur_year }}</time>
|
||||
{{ '<ul class="list-unstyled">' }}
|
||||
|
||||
<li>
|
||||
{% assign ts = post.date | date: '%s' %}
|
||||
<span class="date day" data-ts="{{ ts }}" data-df="DD">{{ post.date | date: "%d" }}</span>
|
||||
<span class="date month small text-muted ms-1" data-ts="{{ ts }}" data-df="{{ df_dayjs_m }}">
|
||||
{{ post.date | date: df_strftime_m }}
|
||||
</span>
|
||||
<a href="{{ post.url | relative_url }}">{{ post.title }}</a>
|
||||
</li>
|
||||
{% assign last_year = cur_year %}
|
||||
{% endif %}
|
||||
|
||||
{% if forloop.last %}</ul>{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
<li>
|
||||
{% assign ts = post.date | date: '%s' %}
|
||||
<span class="date day" data-ts="{{ ts }}" data-df="DD">{{ post.date | date: '%d' }}</span>
|
||||
<span class="date month small text-muted ms-1" data-ts="{{ ts }}" data-df="{{ df_dayjs_m }}">
|
||||
{{ post.date | date: df_strftime_m }}
|
||||
</span>
|
||||
<a href="{{ post.url | relative_url }}">{{ post.title }}</a>
|
||||
</li>
|
||||
|
||||
{% if forloop.last %}</ul>{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
@@ -12,12 +12,12 @@ layout: page
|
||||
<span class="lead text-muted ps-2">{{ page.posts | size }}</span>
|
||||
</h1>
|
||||
|
||||
<ul class="post-content ps-0">
|
||||
<ul class="content ps-0">
|
||||
{% for post in page.posts %}
|
||||
<li class="d-flex justify-content-between px-md-3">
|
||||
<a href="{{ post.url | relative_url }}">{{ post.title }}</a>
|
||||
<span class="dash flex-grow-1"></span>
|
||||
{% include datetime.html date=post.date wrap='span' class='text-muted small' lang=lang %}
|
||||
{% include datetime.html date=post.date class='text-muted small text-nowrap' lang=lang %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
layout: compress
|
||||
# Default layout
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
@@ -9,11 +8,9 @@ layout: compress
|
||||
|
||||
{% include lang.html %}
|
||||
|
||||
{% capture prefer_mode %}
|
||||
{% if site.theme_mode %}
|
||||
data-mode="{{ site.theme_mode }}"
|
||||
{% endif %}
|
||||
{% endcapture %}
|
||||
{% if site.theme_mode %}
|
||||
{% capture prefer_mode %}data-mode="{{ site.theme_mode }}"{% endcapture %}
|
||||
{% endif %}
|
||||
|
||||
<!-- `site.alt_lang` can specify a language different from the UI -->
|
||||
<html lang="{{ site.alt_lang | default: site.lang }}" {{ prefer_mode }}>
|
||||
@@ -23,54 +20,68 @@ layout: compress
|
||||
{% include sidebar.html lang=lang %}
|
||||
|
||||
<div id="main-wrapper" class="d-flex justify-content-center">
|
||||
<div id="main" class="container px-xxl-5">
|
||||
<div class="container d-flex flex-column px-xxl-5">
|
||||
{% include topbar.html lang=lang %}
|
||||
{{ content }}
|
||||
{% include search-results.html lang=lang %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include footer.html lang=lang %}
|
||||
<div class="row flex-grow-1">
|
||||
<main aria-label="Main Content" class="col-12 col-lg-11 col-xl-9 px-md-4">
|
||||
{% if layout.refactor or layout.layout == 'default' %}
|
||||
{% include refactor-content.html content=content lang=lang %}
|
||||
{% else %}
|
||||
{{ content }}
|
||||
{% endif %}
|
||||
</main>
|
||||
|
||||
<!-- panel -->
|
||||
<aside aria-label="Panel" id="panel-wrapper" class="col-xl-3 ps-2 mb-5 text-muted">
|
||||
<div class="access">
|
||||
{% include_cached update-list.html lang=lang %}
|
||||
{% include_cached trending-tags.html lang=lang %}
|
||||
</div>
|
||||
|
||||
{% for _include in layout.panel_includes %}
|
||||
{% assign _include_path = _include | append: '.html' %}
|
||||
{% include {{ _include_path }} lang=lang %}
|
||||
{% endfor %}
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<!-- tail -->
|
||||
<div id="tail-wrapper" class="col-12 col-lg-11 col-xl-9 px-md-4">
|
||||
{% for _include in layout.tail_includes %}
|
||||
{% assign _include_path = _include | append: '.html' %}
|
||||
{% include {{ _include_path }} lang=lang %}
|
||||
{% endfor %}
|
||||
|
||||
{% include_cached footer.html lang=lang %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include_cached search-results.html lang=lang %}
|
||||
</div>
|
||||
|
||||
<aside aria-label="Scroll to Top">
|
||||
<button id="back-to-top" type="button" class="btn btn-lg btn-box-shadow">
|
||||
<i class="fas fa-angle-up"></i>
|
||||
</button>
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
<div id="mask"></div>
|
||||
|
||||
<a id="back-to-top" href="#" aria-label="back-to-top" class="btn btn-lg btn-box-shadow" role="button">
|
||||
<i class="fas fa-angle-up"></i>
|
||||
</a>
|
||||
|
||||
{% if site.pwa.enabled %}
|
||||
<div
|
||||
id="notification"
|
||||
class="toast"
|
||||
role="alert"
|
||||
aria-live="assertive"
|
||||
aria-atomic="true"
|
||||
data-bs-animation="true"
|
||||
data-bs-autohide="false"
|
||||
>
|
||||
<div class="toast-header">
|
||||
<button
|
||||
type="button"
|
||||
class="btn-close ms-auto"
|
||||
data-bs-dismiss="toast"
|
||||
aria-label="Close"
|
||||
></button>
|
||||
</div>
|
||||
<div class="toast-body text-center pt-0">
|
||||
<p class="px-2 mb-3">{{ site.data.locales[lang].notification.update_found }}</p>
|
||||
<button type="button" class="btn btn-primary" aria-label="Update">
|
||||
{{ site.data.locales[lang].notification.update }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{% include_cached notification.html lang=lang %}
|
||||
{% endif %}
|
||||
|
||||
<!-- JavaScripts -->
|
||||
|
||||
{% include js-selector.html %}
|
||||
|
||||
{% if page.mermaid %}
|
||||
{% include mermaid.html %}
|
||||
{% endif %}
|
||||
|
||||
{% include search-loader.html %}
|
||||
{% include_cached search-loader.html %}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
layout: page
|
||||
layout: default
|
||||
refactor: true
|
||||
---
|
||||
|
||||
@@ -40,59 +40,75 @@ refactor: true
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
<div id="post-list">
|
||||
<div id="post-list" class="flex-grow-1 px-xl-1">
|
||||
{% for post in posts %}
|
||||
<a href="{{ post.url | relative_url }}" class="card-wrapper">
|
||||
<div class="card post-preview flex-md-row-reverse">
|
||||
<article class="card-wrapper card">
|
||||
<a href="{{ post.url | relative_url }}" class="post-preview row g-0 flex-md-row-reverse">
|
||||
{% assign card_body_col = '12' %}
|
||||
|
||||
{% if post.image %}
|
||||
{% assign src = post.image.path | default: post.image %}
|
||||
{% unless src contains '//' %}
|
||||
{% assign src = post.img_path | append: '/' | append: src | replace: '//', '/' %}
|
||||
{% endunless %}
|
||||
|
||||
{% assign alt = post.image.alt | xml_escape | default: 'Preview Image' %}
|
||||
|
||||
{% assign lqip = null %}
|
||||
|
||||
{% if post.image.lqip %}
|
||||
{% capture lqip %}lqip="{{ post.image.lqip }}"{% endcapture %}
|
||||
{% endif %}
|
||||
<img src="{{ post.image.path | default: post.image }}" w="15" h="8" {{ lqip }}>
|
||||
|
||||
<div class="col-md-5">
|
||||
<img src="{{ src }}" alt="{{ alt }}" {{ lqip }}>
|
||||
</div>
|
||||
|
||||
{% assign card_body_col = '7' %}
|
||||
{% endif %}
|
||||
|
||||
<div class="card-body d-flex flex-column">
|
||||
<h1 class="card-title my-2 mt-md-0">
|
||||
{{ post.title }}
|
||||
</h1>
|
||||
<div class="col-md-{{ card_body_col }}">
|
||||
<div class="card-body d-flex flex-column">
|
||||
<h1 class="card-title my-2 mt-md-0">{{ post.title }}</h1>
|
||||
|
||||
<div class="card-text post-content mt-0 mb-2">
|
||||
<p>
|
||||
{% include no-linenos.html content=post.content %}
|
||||
{{ content | markdownify | strip_html | truncate: 200 | escape }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="post-meta flex-grow-1 d-flex align-items-end">
|
||||
<div class="me-auto">
|
||||
<!-- posted date -->
|
||||
<i class="far fa-calendar fa-fw me-1"></i>
|
||||
{% include datetime.html date=post.date lang=lang %}
|
||||
|
||||
<!-- categories -->
|
||||
{% if post.categories.size > 0 %}
|
||||
<i class="far fa-folder-open fa-fw me-1"></i>
|
||||
<span class="categories">
|
||||
{% for category in post.categories %}
|
||||
{{ category }}
|
||||
{%- unless forloop.last -%},{%- endunless -%}
|
||||
{% endfor %}
|
||||
</span>
|
||||
{% endif %}
|
||||
<div class="card-text content mt-0 mb-3">
|
||||
<p>
|
||||
{% include no-linenos.html content=post.content %}
|
||||
{{ content | markdownify | strip_html | truncate: 200 | escape }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{% if post.pin %}
|
||||
<div class="pin ms-1">
|
||||
<i class="fas fa-thumbtack fa-fw"></i>
|
||||
<span>{{ site.data.locales[lang].post.pin_prompt }}</span>
|
||||
<div class="post-meta flex-grow-1 d-flex align-items-end">
|
||||
<div class="me-auto">
|
||||
<!-- posted date -->
|
||||
<i class="far fa-calendar fa-fw me-1"></i>
|
||||
{% include datetime.html date=post.date lang=lang %}
|
||||
|
||||
<!-- categories -->
|
||||
{% if post.categories.size > 0 %}
|
||||
<i class="far fa-folder-open fa-fw me-1"></i>
|
||||
<span class="categories">
|
||||
{% for category in post.categories %}
|
||||
{{ category }}
|
||||
{%- unless forloop.last -%},{%- endunless -%}
|
||||
{% endfor %}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if post.pin %}
|
||||
<div class="pin ms-1">
|
||||
<i class="fas fa-thumbtack fa-fw"></i>
|
||||
<span>{{ site.data.locales[lang].post.pin_prompt }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<!-- .post-meta -->
|
||||
</div>
|
||||
<!-- .post-meta -->
|
||||
<!-- .card-body -->
|
||||
</div>
|
||||
<!-- .card-body -->
|
||||
</div>
|
||||
</a>
|
||||
</a>
|
||||
</article>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- #post-list -->
|
||||
|
||||
@@ -3,62 +3,18 @@ layout: default
|
||||
---
|
||||
|
||||
{% include lang.html %}
|
||||
{% include origin-type.html %}
|
||||
|
||||
<div class="row">
|
||||
<!-- core -->
|
||||
<div id="core-wrapper" class="col-12 col-lg-11 col-xl-9 pe-xl-4">
|
||||
{% capture padding %}
|
||||
{% unless page.layout == 'home' %}px-1{% endunless %}
|
||||
{% endcapture %}
|
||||
|
||||
<div class="post {{ padding | strip }} px-md-2">
|
||||
{% capture _content %}
|
||||
{% if layout.refactor or page.layout == 'page' %}
|
||||
{% include refactor-content.html content=content lang=lang %}
|
||||
{% else %}
|
||||
{{ content }}
|
||||
{% endif %}
|
||||
{% endcapture %}
|
||||
|
||||
{% if page.layout == 'page' or page.collection == 'tabs' %}
|
||||
{% assign tab_key = page.title | downcase %}
|
||||
{% assign title = site.data.locales[lang].tabs[tab_key] | default: page.title %}
|
||||
<h1 class="dynamic-title">
|
||||
{{ title }}
|
||||
</h1>
|
||||
<div class="post-content">
|
||||
{{ _content }}
|
||||
</div>
|
||||
{% else %}
|
||||
{{ _content }}
|
||||
{% endif %}
|
||||
<article class="px-1">
|
||||
{% if page.layout == 'page' or page.collection == 'tabs' %}
|
||||
{% assign tab_key = page.title | downcase %}
|
||||
{% assign title = site.data.locales[lang].tabs[tab_key] | default: page.title %}
|
||||
<h1 class="dynamic-title">
|
||||
{{ title }}
|
||||
</h1>
|
||||
<div class="content">
|
||||
{{ content }}
|
||||
</div>
|
||||
</div>
|
||||
<!-- #core-wrapper -->
|
||||
|
||||
<!-- panel -->
|
||||
<div id="panel-wrapper" class="col-xl-3 ps-2 text-muted">
|
||||
<div class="access">
|
||||
{% include update-list.html lang=lang %}
|
||||
{% include trending-tags.html lang=lang %}
|
||||
</div>
|
||||
|
||||
{% for _include in layout.panel_includes %}
|
||||
{% assign _include_path = _include | append: '.html' %}
|
||||
{% include {{ _include_path }} lang=lang %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- tail -->
|
||||
{% if layout.tail_includes %}
|
||||
<div class="row">
|
||||
<div id="tail-wrapper" class="col-12 col-lg-11 col-xl-9 px-3 pe-xl-4 mt-5">
|
||||
{% for _include in layout.tail_includes %}
|
||||
{% assign _include_path = _include | append: '.html' %}
|
||||
{% include {{ _include_path }} lang=lang %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{{ content }}
|
||||
{% endif %}
|
||||
</article>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
layout: page
|
||||
layout: default
|
||||
refactor: true
|
||||
panel_includes:
|
||||
- toc
|
||||
@@ -11,133 +11,129 @@ tail_includes:
|
||||
|
||||
{% include lang.html %}
|
||||
|
||||
<h1 data-toc-skip>{{ page.title }}</h1>
|
||||
<article class="px-1">
|
||||
<header>
|
||||
<h1 data-toc-skip>{{ page.title }}</h1>
|
||||
|
||||
<div class="post-meta text-muted">
|
||||
<!-- published date -->
|
||||
<span>
|
||||
{{ site.data.locales[lang].post.posted }}
|
||||
{% include datetime.html date=page.date tooltip=true lang=lang %}
|
||||
</span>
|
||||
<div class="post-meta text-muted">
|
||||
<!-- published date -->
|
||||
<span>
|
||||
{{ site.data.locales[lang].post.posted }}
|
||||
{% include datetime.html date=page.date tooltip=true lang=lang %}
|
||||
</span>
|
||||
|
||||
<!-- lastmod date -->
|
||||
{% if page.last_modified_at and page.last_modified_at != page.date %}
|
||||
<span>
|
||||
{{ site.data.locales[lang].post.updated }}
|
||||
{% include datetime.html date=page.last_modified_at tooltip=true lang=lang %}
|
||||
</span>
|
||||
<!-- lastmod date -->
|
||||
{% if page.last_modified_at and page.last_modified_at != page.date %}
|
||||
<span>
|
||||
{{ site.data.locales[lang].post.updated }}
|
||||
{% include datetime.html date=page.last_modified_at tooltip=true lang=lang %}
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
{% if page.image %}
|
||||
{% capture src %}src="{{ page.image.path | default: page.image }}"{% endcapture %}
|
||||
{% capture class %}class="preview-img{% if page.image.no_bg %}{{ ' no-bg' }}{% endif %}"{% endcapture %}
|
||||
{% capture alt %}alt="{{ page.image.alt | xml_escape | default: "Preview Image" }}"{% endcapture %}
|
||||
|
||||
{% if page.image.lqip %}
|
||||
{%- capture lqip -%}lqip="{{ page.image.lqip }}"{%- endcapture -%}
|
||||
{% endif %}
|
||||
|
||||
<div class="mt-3 mb-3">
|
||||
<img {{ src }} {{ class }} {{ alt }} w="1200" h="630" {{ lqip }}>
|
||||
{%- if page.image.alt -%}
|
||||
<figcaption class="text-center pt-2 pb-2">{{ page.image.alt }}</figcaption>
|
||||
{%- endif -%}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="d-flex justify-content-between">
|
||||
<!-- author(s) -->
|
||||
<span>
|
||||
{% if page.author %}
|
||||
{% assign authors = page.author %}
|
||||
{% elsif page.authors %}
|
||||
{% assign authors = page.authors %}
|
||||
{% endif %}
|
||||
|
||||
{{ site.data.locales[lang].post.written_by }}
|
||||
|
||||
<em>
|
||||
{% if authors %}
|
||||
{% for author in authors %}
|
||||
{% if site.data.authors[author].url -%}
|
||||
<a href="{{ site.data.authors[author].url }}">{{ site.data.authors[author].name }}</a>
|
||||
{%- else -%}
|
||||
{{ site.data.authors[author].name }}
|
||||
{%- endif %}
|
||||
{% unless forloop.last %}{{ '</em>, <em>' }}{% endunless %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<a href="{{ site.social.links[0] }}">{{ site.social.name }}</a>
|
||||
{% endif %}
|
||||
</em>
|
||||
</span>
|
||||
|
||||
<!-- read time -->
|
||||
{% include read-time.html content=content prompt=true lang=lang %}
|
||||
</div>
|
||||
<!-- .d-flex -->
|
||||
</div>
|
||||
<!-- .post-meta -->
|
||||
</header>
|
||||
|
||||
<div class="content">
|
||||
{{ content }}
|
||||
</div>
|
||||
|
||||
<div class="post-tail-wrapper text-muted">
|
||||
<!-- categories -->
|
||||
{% if page.categories.size > 0 %}
|
||||
<div class="post-meta mb-3">
|
||||
<i class="far fa-folder-open fa-fw me-1"></i>
|
||||
{% for category in page.categories %}
|
||||
<a href="{{ site.baseurl }}/categories/{{ category | slugify | url_encode }}/">{{ category }}</a>
|
||||
{%- unless forloop.last -%},{%- endunless -%}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if page.image %}
|
||||
{% capture src %}src="{{ page.image.path | default: page.image }}"{% endcapture %}
|
||||
{% capture class %}class="preview-img{% if page.image.no_bg %}{{ ' no-bg' }}{% endif %}"{% endcapture %}
|
||||
{% capture alt %}alt="{{ page.image.alt | default: "Preview Image" }}"{% endcapture %}
|
||||
|
||||
{% capture lqip %}
|
||||
{% if page.image.lqip %}
|
||||
lqip="{{ page.image.lqip }}"
|
||||
{% endif %}
|
||||
{% endcapture %}
|
||||
|
||||
<div class="mt-3 mb-3">
|
||||
<img {{ src }} {{ class }} {{ alt }} w="1200" h="630" {{ lqip | strip }}>
|
||||
{%- if page.image.alt -%}
|
||||
<figcaption class="text-center pt-2 pb-2">{{ page.image.alt }}</figcaption>
|
||||
{%- endif -%}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="d-flex justify-content-between">
|
||||
<!-- author(s) -->
|
||||
<span>
|
||||
{% if page.author %}
|
||||
{% assign authors = page.author %}
|
||||
{% elsif page.authors %}
|
||||
{% assign authors = page.authors %}
|
||||
{% endif %}
|
||||
|
||||
{{ site.data.locales[lang].post.written_by }}
|
||||
|
||||
<em>
|
||||
{% if authors %}
|
||||
{% for author in authors %}
|
||||
<a href="{{ site.data.authors[author].url }}">{{ site.data.authors[author].name }}</a>
|
||||
{% unless forloop.last %}</em>, <em>{% endunless %}
|
||||
<!-- tags -->
|
||||
{% if page.tags.size > 0 %}
|
||||
<div class="post-tags">
|
||||
<i class="fa fa-tags fa-fw me-1"></i>
|
||||
{% for tag in page.tags %}
|
||||
<a
|
||||
href="{{ site.baseurl }}/tags/{{ tag | slugify | url_encode }}/"
|
||||
class="post-tag no-text-decoration"
|
||||
>
|
||||
{{- tag -}}
|
||||
</a>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<a href="{{ site.social.links[0] }}">{{ site.social.name }}</a>
|
||||
{% endif %}
|
||||
</em>
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div>
|
||||
<!-- page views -->
|
||||
{% if site.google_analytics.pv.proxy_endpoint or site.google_analytics.pv.cache_path %}
|
||||
<span>
|
||||
<em id="pv" class="pageviews">
|
||||
<i class="fas fa-spinner fa-spin fa-fw"></i>
|
||||
</em>
|
||||
{{ site.data.locales[lang].post.pageview_measure }}
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
<!-- read time -->
|
||||
{% include read-time.html content=content prompt=true lang=lang %}
|
||||
</div>
|
||||
|
||||
</div> <!-- .d-flex -->
|
||||
|
||||
</div> <!-- .post-meta -->
|
||||
|
||||
<div class="post-content">
|
||||
{{ content }}
|
||||
</div>
|
||||
|
||||
<div class="post-tail-wrapper text-muted">
|
||||
|
||||
<!-- categories -->
|
||||
{% if page.categories.size > 0 %}
|
||||
<div class="post-meta mb-3">
|
||||
<i class="far fa-folder-open fa-fw me-1"></i>
|
||||
{% for category in page.categories %}
|
||||
<a href='{{ site.baseurl }}/categories/{{ category | slugify | url_encode }}/'>{{ category }}</a>
|
||||
{%- unless forloop.last -%}, {%- endunless -%}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- tags -->
|
||||
{% if page.tags.size > 0 %}
|
||||
<div class="post-tags">
|
||||
<i class="fa fa-tags fa-fw me-1"></i>
|
||||
{% for tag in page.tags %}
|
||||
<a href="{{ site.baseurl }}/tags/{{ tag | slugify | url_encode }}/"
|
||||
class="post-tag no-text-decoration" >
|
||||
{{- tag -}}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="post-tail-bottom
|
||||
d-flex justify-content-between align-items-center mt-3 pt-5 pb-2">
|
||||
<div class="license-wrapper">
|
||||
|
||||
{% if site.data.locales[lang].copyright.license.template %}
|
||||
|
||||
{% capture _replacement %}
|
||||
<div
|
||||
class="
|
||||
post-tail-bottom
|
||||
d-flex justify-content-between align-items-center mt-5 pb-2
|
||||
"
|
||||
>
|
||||
<div class="license-wrapper">
|
||||
{% if site.data.locales[lang].copyright.license.template %}
|
||||
{% capture _replacement %}
|
||||
<a href="{{ site.data.locales[lang].copyright.license.link }}">
|
||||
{{ site.data.locales[lang].copyright.license.name }}
|
||||
</a>
|
||||
{% endcapture %}
|
||||
|
||||
{{ site.data.locales[lang].copyright.license.template | replace: ':LICENSE_NAME', _replacement }}
|
||||
{{ site.data.locales[lang].copyright.license.template | replace: ':LICENSE_NAME', _replacement }}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
{% include post-sharing.html lang=lang %}
|
||||
</div>
|
||||
|
||||
{% include post-sharing.html lang=lang %}
|
||||
|
||||
</div><!-- .post-tail-bottom -->
|
||||
|
||||
</div><!-- div.post-tail-wrapper -->
|
||||
<!-- .post-tail-bottom -->
|
||||
</div>
|
||||
<!-- div.post-tail-wrapper -->
|
||||
</article>
|
||||
|
||||
@@ -11,12 +11,12 @@ layout: page
|
||||
{{ page.title }}
|
||||
<span class="lead text-muted ps-2">{{ page.posts | size }}</span>
|
||||
</h1>
|
||||
<ul class="post-content ps-0">
|
||||
<ul class="content ps-0">
|
||||
{% for post in page.posts %}
|
||||
<li class="d-flex justify-content-between px-md-3">
|
||||
<a href="{{ post.url | relative_url }}">{{ post.title }}</a>
|
||||
<span class="dash flex-grow-1"></span>
|
||||
{% include datetime.html date=post.date wrap='span' class='text-muted small' lang=lang %}
|
||||
{% include datetime.html date=post.date class='text-muted small text-nowrap' lang=lang %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
@@ -17,13 +17,17 @@ This post is to show Markdown syntax rendering on [**Chirpy**](https://github.co
|
||||
|
||||
## Headings
|
||||
|
||||
<h1 class="mt-5">H1 - heading</h1>
|
||||
# H1 - heading
|
||||
{: .mt-4 .mb-0 }
|
||||
|
||||
<h2 data-toc-skip>H2 - heading</h2>
|
||||
## H2 - heading
|
||||
{: data-toc-skip='' .mt-4 .mb-0 }
|
||||
|
||||
<h3 data-toc-skip>H3 - heading</h3>
|
||||
### H3 - heading
|
||||
{: data-toc-skip='' .mt-4 .mb-0 }
|
||||
|
||||
<h4>H4 - heading</h4>
|
||||
#### H4 - heading
|
||||
{: data-toc-skip='' .mt-4 }
|
||||
|
||||
## Paragraph
|
||||
|
||||
@@ -130,7 +134,14 @@ fi;
|
||||
|
||||
The mathematics powered by [**MathJax**](https://www.mathjax.org/):
|
||||
|
||||
$$ \sum_{n=1}^\infty 1/n^2 = \frac{\pi^2}{6} $$
|
||||
$$
|
||||
\begin{equation}
|
||||
\sum_{n=1}^\infty 1/n^2 = \frac{\pi^2}{6}
|
||||
\label{eq:series}
|
||||
\end{equation}
|
||||
$$
|
||||
|
||||
We can reference the equation as \eqref{eq:series}.
|
||||
|
||||
When $a \ne 0$, there are two solutions to $ax^2 + bx + c = 0$ and they are
|
||||
|
||||
|
||||
@@ -69,7 +69,6 @@ authors: [<author1_id>, <author2_id>] # for multiple entries
|
||||
---
|
||||
```
|
||||
|
||||
|
||||
Having said that, the key `author` can also identify multiple entries.
|
||||
|
||||
> The benefit of reading the author information from the file `_data/authors.yml`{: .filepath } is that the page will have the meta tag `twitter:creator`, which enriches the [Twitter Cards](https://developer.twitter.com/en/docs/twitter-for-websites/cards/guides/getting-started#card-and-content-attribution) and is good for SEO.
|
||||
@@ -107,9 +106,46 @@ math: true
|
||||
---
|
||||
```
|
||||
|
||||
After enabling the mathematical feature, you can add math equations with the following syntax:
|
||||
|
||||
- **Block math** should be added with `$$ math $$` with **mandatory** blank lines before and after `$$`
|
||||
- **Inserting equation numbering** should be added with `$$\begin{equation} math \end{equation}$$`
|
||||
- **Referencing equation numbering** should be done with `\label{eq:label_name}` in the equation block and `\eqref{eq:label_name}` inline with text (see example below)
|
||||
- **Inline math** (in lines) should be added with `$$ math $$` without any blank line before or after `$$`
|
||||
- **Inline math** (in lists) should be added with `\$$ math $$`
|
||||
|
||||
```markdown
|
||||
<!-- Block math, keep all blank lines -->
|
||||
|
||||
$$
|
||||
LaTeX_math_expression
|
||||
$$
|
||||
|
||||
<!-- Equation numbering, keep all blank lines -->
|
||||
|
||||
$$
|
||||
\begin{equation}
|
||||
LaTeX_math_expression
|
||||
\label{eq:label_name}
|
||||
\end{equation}
|
||||
$$
|
||||
|
||||
Can be referenced as \eqref{eq:label_name}.
|
||||
|
||||
<!-- Inline math in lines, NO blank lines -->
|
||||
|
||||
"Lorem ipsum dolor sit amet, $$ LaTeX_math_expression $$ consectetur adipiscing elit."
|
||||
|
||||
<!-- Inline math in lists, escape the first `$` -->
|
||||
|
||||
1. \$$ LaTeX_math_expression $$
|
||||
2. \$$ LaTeX_math_expression $$
|
||||
3. \$$ LaTeX_math_expression $$
|
||||
```
|
||||
|
||||
## Mermaid
|
||||
|
||||
[**Mermaid**](https://github.com/mermaid-js/mermaid) is a great diagrams generation tool. To enable it on your post, add the following to the YAML block:
|
||||
[**Mermaid**](https://github.com/mermaid-js/mermaid) is a great diagram generation tool. To enable it on your post, add the following to the YAML block:
|
||||
|
||||
```yaml
|
||||
---
|
||||
@@ -123,7 +159,7 @@ Then you can use it like other markdown languages: surround the graph code with
|
||||
|
||||
### Caption
|
||||
|
||||
Add italics to the next line of an image,then it will become the caption and appear at the bottom of the image:
|
||||
Add italics to the next line of an image, then it will become the caption and appear at the bottom of the image:
|
||||
|
||||
```markdown
|
||||

|
||||
@@ -219,7 +255,7 @@ For instance, when using images:
|
||||
The parsing result will automatically add the CDN prefix `https://cdn.com` before the image path:
|
||||
|
||||
```html
|
||||
<img src="https://cdn.com/path/to/flower.png" alt="The flower">
|
||||
<img src="https://cdn.com/path/to/flower.png" alt="The flower" />
|
||||
```
|
||||
{: .nolineno }
|
||||
|
||||
@@ -243,7 +279,7 @@ And then, the image source of Markdown can write the file name directly:
|
||||
The output will be:
|
||||
|
||||
```html
|
||||
<img src="/img/path/flower.png" alt="The flower">
|
||||
<img src="/img/path/flower.png" alt="The flower" />
|
||||
```
|
||||
{: .nolineno }
|
||||
|
||||
@@ -261,7 +297,7 @@ image:
|
||||
---
|
||||
```
|
||||
|
||||
Note that the [`img_path`](#image-path) can also be passed to the preview image, that is, when it has been set, the attribute `path` only needs the image file name.
|
||||
Note that the [`img_path`](#image-path) can also be passed to the preview image, that is, when it has been set, the attribute `path` only needs the image file name.
|
||||
|
||||
For simple use, you can also just use `image` to define the path.
|
||||
|
||||
@@ -396,16 +432,16 @@ You can embed a video with the following syntax:
|
||||
```liquid
|
||||
{% include embed/{Platform}.html id='{ID}' %}
|
||||
```
|
||||
|
||||
Where `Platform` is the lowercase of the platform name, and `ID` is the video ID.
|
||||
|
||||
The following table shows how to get the two parameters we need in a given video URL, and you can also know the currently supported video platforms.
|
||||
|
||||
| Video URL | Platform | ID |
|
||||
|----------------------------------------------------------------------------------------------------|-----------|:--------------|
|
||||
| [https://www.**youtube**.com/watch?v=**H-B46URT4mg**](https://www.youtube.com/watch?v=H-B46URT4mg) | `youtube` | `H-B46URT4mg` |
|
||||
| [https://www.**twitch**.tv/videos/**1634779211**](https://www.twitch.tv/videos/1634779211) | `twitch` | `1634779211` |
|
||||
|
||||
|
||||
| Video URL | Platform | ID |
|
||||
| -------------------------------------------------------------------------------------------------- | ---------- | :------------- |
|
||||
| [https://www.**youtube**.com/watch?v=**H-B46URT4mg**](https://www.youtube.com/watch?v=H-B46URT4mg) | `youtube` | `H-B46URT4mg` |
|
||||
| [https://www.**twitch**.tv/videos/**1634779211**](https://www.twitch.tv/videos/1634779211) | `twitch` | `1634779211` |
|
||||
| [https://www.**bilibili**.com/video/**BV1Q44y1B7Wf**](https://www.bilibili.com/video/BV1Q44y1B7Wf) | `bilibili` | `BV1Q44y1B7Wf` |
|
||||
|
||||
## Learn More
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ date: 2019-08-09 20:55:00 +0800
|
||||
categories: [Blogging, Tutorial]
|
||||
tags: [getting started]
|
||||
pin: true
|
||||
img_path: '/posts/20180809'
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
@@ -63,11 +64,15 @@ Update the variables of `_config.yml`{: .filepath} as needed. Some of them are t
|
||||
- `timezone`
|
||||
- `lang`
|
||||
|
||||
### Social Contact Options
|
||||
|
||||
Social contact options are displayed at the bottom of the sidebar. You can turn on/off the specified contacts in file `_data/contact.yml`{: .filepath }.
|
||||
|
||||
### Customizing Stylesheet
|
||||
|
||||
If you need to customize the stylesheet, copy the theme's `assets/css/style.scss`{: .filepath} to the same path on your Jekyll site, and then add the custom style at the end of it.
|
||||
If you need to customize the stylesheet, copy the theme's `assets/css/jekyll-theme-chirpy.scss`{: .filepath} to the same path on your Jekyll site, and then add the custom style at the end of it.
|
||||
|
||||
Starting with version `4.1.0`, if you want to overwrite the SASS variables defined in `_sass/addon/variables.scss`{: .filepath}, copy the main sass file `_sass/jekyll-theme-chirpy.scss`{: .filepath} into the `_sass`{: .filepath} directory in your site's source, then create a new file `_sass/variables-hook.scss`{: .filepath} and assign new value.
|
||||
Starting with version `6.2.0`, if you want to overwrite the SASS variables defined in `_sass/addon/variables.scss`{: .filepath}, copy the main sass file `_sass/main.scss`{: .filepath} into the `_sass`{: .filepath} directory in your site's source, then create a new file `_sass/variables-hook.scss`{: .filepath} and assign new value.
|
||||
|
||||
### Customing Static Assets
|
||||
|
||||
@@ -83,15 +88,6 @@ You may want to preview the site contents before publishing, so just run it by:
|
||||
$ bundle exec jekyll s
|
||||
```
|
||||
|
||||
Or run the site on Docker with the following command:
|
||||
|
||||
```console
|
||||
$ docker run -it --rm \
|
||||
--volume="$PWD:/srv/jekyll" \
|
||||
-p 4000:4000 jekyll/jekyll \
|
||||
jekyll serve
|
||||
```
|
||||
|
||||
After a few seconds, the local service will be published at _<http://127.0.0.1:4000>_.
|
||||
|
||||
## Deployment
|
||||
@@ -105,7 +101,7 @@ Now you can choose _ONE_ of the following methods to deploy your Jekyll site.
|
||||
There are a few things to get ready for.
|
||||
|
||||
- If you're on the GitHub Free plan, keep your site repository public.
|
||||
- If you have committed `Gemfile.lock`{: .filepath} to the repository, and your local machine is not running Linux, go the the root of your site and update the platform list of the lock-file:
|
||||
- If you have committed `Gemfile.lock`{: .filepath} to the repository, and your local machine is not running Linux, go to the root of your site and update the platform list of the lock-file:
|
||||
|
||||
```console
|
||||
$ bundle lock --add-platform x86_64-linux
|
||||
@@ -113,7 +109,9 @@ There are a few things to get ready for.
|
||||
|
||||
Next, configure the _Pages_ service.
|
||||
|
||||
1. Browse to your repository on GitHub. Select the tab _Settings_, then click _Pages_ in the left navigation bar. Then, in the **Source** section (under _Build and deployment_), select [**GitHub Actions**][pages-workflow-src] from the dropdown menu.
|
||||
1. Browse to your repository on GitHub. Select the tab _Settings_, then click _Pages_ in the left navigation bar. Then, in the **Source** section (under _Build and deployment_), select [**GitHub Actions**][pages-workflow-src] from the dropdown menu.
|
||||
{: .light .border .normal w='375' h='140' }
|
||||
{: .dark .normal w='375' h='140' }
|
||||
|
||||
2. Push any commits to GitHub to trigger the _Actions_ workflow. In the _Actions_ tab of your repository, you should see the workflow _Build and Deploy_ running. Once the build is complete and successful, the site will be deployed automatically.
|
||||
|
||||
@@ -129,16 +127,6 @@ Go to the root of the source project, and build your site as follows:
|
||||
$ JEKYLL_ENV=production bundle exec jekyll b
|
||||
```
|
||||
|
||||
Or build the site on Docker:
|
||||
|
||||
```console
|
||||
$ docker run -it --rm \
|
||||
--env JEKYLL_ENV=production \
|
||||
--volume="$PWD:/srv/jekyll" \
|
||||
jekyll/jekyll \
|
||||
jekyll build
|
||||
```
|
||||
|
||||
Unless you specified the output path, the generated site files will be placed in folder `_site`{: .filepath} of the project's root directory. Now you should upload those files to the target server.
|
||||
|
||||
[nodejs]: https://nodejs.org/
|
||||
|
||||
@@ -1,243 +0,0 @@
|
||||
---
|
||||
title: Enable Google Page Views
|
||||
author: sille_bille
|
||||
date: 2021-01-03 18:32:00 -0500
|
||||
categories: [Blogging, Tutorial]
|
||||
tags: [google analytics, pageviews]
|
||||
---
|
||||
|
||||
> The content of this post applies only to [_Universal Analytics property_](https://support.google.com/analytics/answer/10220206) (UA), not [_Google Analytics 4_](https://support.google.com/analytics/answer/10089681) (GA 4). In addition, since [UA is about to be deprecated on Jul 1, 2023](https://support.google.com/analytics/answer/11583528), the Page Views feature of [_Chirpy_][chirpy-homepage] will also be deprecated at that time.
|
||||
{: .prompt-danger }
|
||||
|
||||
This post is to enable Page Views on the [**Chirpy**][chirpy-homepage] theme based blog that you just built. This requires technical knowledge and it's recommended to keep the `google_analytics.pv.*` empty unless you have a good reason. If your website has low traffic, the page views count would discourage you to write more blogs. With that said, let's start with the setup.
|
||||
|
||||
## Set up Google Analytics
|
||||
|
||||
### Create GA account and property
|
||||
|
||||
First, you need to set up your account on Google analytics. While you create your account, you must create your first **Property** as well.
|
||||
|
||||
1. Head to <https://analytics.google.com/> and click on **Start Measuring**
|
||||
2. Enter your desired _Account Name_ and choose the desired checkboxes
|
||||
3. Enter your desired _Property Name_. This is the name of the tracker project that appears on your Google Analytics dashboard
|
||||
4. Enter the required information _About your business_
|
||||
5. Hit _Create_ and accept any license popup to set up your Google Analytics account and create your property
|
||||
|
||||
### Create Data Stream
|
||||
|
||||
With your property created, you now need to set up Data Stream to track your blog traffic. After you signup, the prompt should automatically take you to create your first **Data Stream**. If not, follow these steps:
|
||||
|
||||
1. Go to **Admin** on the left column
|
||||
2. Select the desired property from the drop-down on the second column
|
||||
3. Click on **Data Streams**
|
||||
4. Add a stream and click on **Web**
|
||||
5. Enter your blog's URL
|
||||
|
||||
It should look like this:
|
||||
|
||||
{: width="1086" height="542"}
|
||||
|
||||
Now, click on the new data stream and grab the **Measurement ID**. It should look something like `G-V6XXXXXXXX`. Copy this to your `_config.yml`{: .filepath} file:
|
||||
|
||||
```yaml
|
||||
google_analytics:
|
||||
id: 'G-V6XXXXXXX' # fill in your Google Analytics ID
|
||||
# Google Analytics pageviews report settings
|
||||
pv:
|
||||
proxy_endpoint: # fill in the Google Analytics superProxy endpoint of Google App Engine
|
||||
cache_path: # the local PV cache data, friendly to visitors from GFW region
|
||||
```
|
||||
{: file="_config.yml"}
|
||||
|
||||
When you push these changes to your blog, you should start seeing the traffic on your Google Analytics. Play around with the Google Analytics dashboard to get familiar with the options available as it takes like 5 mins to pick up your changes. You should now be able to monitor your traffic in real time.
|
||||
|
||||
{: width="616" height="557"}
|
||||
|
||||
## Setup Page Views
|
||||
|
||||
There is a detailed [tutorial](https://developers.google.com/analytics/solutions/google-analytics-super-proxy) available to set up Google Analytics superProxy. But, if you are interested to just quickly get your Chirpy-based blog display page views, follow along. These steps were tested on a Linux machine. If you are running Windows, you can use the Git bash terminal to run Unix-like commands.
|
||||
|
||||
### Setup Google App Engine
|
||||
|
||||
1. Visit <https://console.cloud.google.com/appengine>
|
||||
|
||||
2. Click on **Create Application**
|
||||
|
||||
3. Click on **Create Project**
|
||||
|
||||
4. Enter the name and choose the data center close to you
|
||||
|
||||
5. Select **Python** language and **Standard** environment
|
||||
|
||||
6. Enable billing account. Yeah, you have to link your credit card. But, you won't be billed unless you exceed your free quota. For a simple blog, the free quota is more than sufficient.
|
||||
|
||||
7. Go to your App Engine dashboard on your browser and select **API & Services** from the left navigation menu
|
||||
|
||||
8. Click on **Enable APIs and Services** button on the top
|
||||
|
||||
9. Enable the following APIs: _Google Analytics API_
|
||||
|
||||
10. On the left, Click on _OAuth Consent Screen_ and accept **Configure Consent Screen**. Select **External** since your blog is probably hosted for the public. Click on **Publish** under _Publishing Status_
|
||||
|
||||
11. Click on **Credentials** on the left and create a new **OAuth Client IDs** credential. Make sure to add an entry under `Authorized redirect URIs` that matches: `https://<project-id>.<region>.r.appspot.com/admin/auth`
|
||||
|
||||
12. Note down the **Your Client ID** and **Your Client Secret**. You'll need this in the next section.
|
||||
|
||||
13. Download and install the cloud SDK for your platform: <https://cloud.google.com/sdk/docs/quickstart>
|
||||
|
||||
14. Run the following commands:
|
||||
|
||||
```console
|
||||
[root@bc96abf71ef8 /]# gcloud init
|
||||
|
||||
~snip~
|
||||
|
||||
Go to the following link in your browser:
|
||||
|
||||
https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=XYZ.apps.googleusercontent.com&redirect_uri=ABCDEFG
|
||||
|
||||
Enter verification code: <VERIFICATION CODE THAT YOU GET AFTER YOU VISIT AND AUTHENTICATE FROM THE ABOVE LINK>
|
||||
|
||||
You are logged in as: [blah_blah@gmail.com].
|
||||
|
||||
Pick cloud project to use:
|
||||
[1] chirpy-test-300716
|
||||
[2] Create a new project
|
||||
Please enter numeric choice or text value (must exactly match list
|
||||
item): 1
|
||||
|
||||
|
||||
[root@bc96abf71ef8 /]# gcloud info
|
||||
# Your selected project info should be displayed here
|
||||
```
|
||||
|
||||
### Setup Google Analytics superProxy
|
||||
|
||||
1. Clone the **Google Analytics superProxy** project on Github: <https://github.com/googleanalytics/google-analytics-super-proxy> to your local.
|
||||
|
||||
2. Remove the first 2 lines in the [`src/app.yaml`{: .filepath}](https://github.com/googleanalytics/google-analytics-super-proxy/blob/master/src/app.yaml#L1-L2) file:
|
||||
|
||||
```diff
|
||||
- application: your-project-id
|
||||
- version: 1
|
||||
```
|
||||
|
||||
3. In `src/config.py`{: .filepath}, add the `OAUTH_CLIENT_ID` and `OAUTH_CLIENT_SECRET` that you gathered from your App Engine Dashboard.
|
||||
|
||||
4. Enter any random key for `XSRF_KEY`, your `config.py`{: .filepath} should look similar to this
|
||||
|
||||
```python
|
||||
#!/usr/bin/python2.7
|
||||
|
||||
__author__ = 'pete.frisella@gmail.com (Pete Frisella)'
|
||||
|
||||
# OAuth 2.0 Client Settings
|
||||
AUTH_CONFIG = {
|
||||
'OAUTH_CLIENT_ID': 'YOUR_CLIENT_ID',
|
||||
'OAUTH_CLIENT_SECRET': 'YOUR_CLIENT_SECRET',
|
||||
'OAUTH_REDIRECT_URI': '%s%s' % (
|
||||
'https://chirpy-test-XXXXXX.ue.r.appspot.com',
|
||||
'/admin/auth'
|
||||
)
|
||||
}
|
||||
|
||||
# XSRF Settings
|
||||
XSRF_KEY = 'OnceUponATimeThereLivedALegend'
|
||||
```
|
||||
{: file="src/config.py"}
|
||||
|
||||
> You can configure a custom domain instead of `https://PROJECT_ID.REGION_ID.r.appspot.com`.
|
||||
> But, for the sake of keeping it simple, we will be using the Google provided default URL.
|
||||
{: .prompt-info }
|
||||
|
||||
5. From inside the `src/`{: .filepath} directory, deploy the app
|
||||
|
||||
```console
|
||||
[root@bc96abf71ef8 src]# gcloud app deploy
|
||||
Services to deploy:
|
||||
|
||||
descriptor: [/tmp/google-analytics-super-proxy/src/app.yaml]
|
||||
source: [/tmp/google-analytics-super-proxy/src]
|
||||
target project: [chirpy-test-XXXX]
|
||||
target service: [default]
|
||||
target version: [VESRION_NUM]
|
||||
target url: [https://chirpy-test-XXXX.ue.r.appspot.com]
|
||||
|
||||
|
||||
Do you want to continue (Y/n)? Y
|
||||
|
||||
Beginning deployment of service [default]...
|
||||
╔════════════════════════════════════════════════════════════╗
|
||||
╠═ Uploading 1 file to Google Cloud Storage ═╣
|
||||
╚════════════════════════════════════════════════════════════╝
|
||||
File upload done.
|
||||
Updating service [default]...done.
|
||||
Setting traffic split for service [default]...done.
|
||||
Deployed service [default] to [https://chirpy-test-XXXX.ue.r.appspot.com]
|
||||
|
||||
You can stream logs from the command line by running:
|
||||
$ gcloud app logs tail -s default
|
||||
|
||||
To view your application in the web browser run:
|
||||
$ gcloud app browse
|
||||
```
|
||||
|
||||
6. Visit the deployed service. Add a `/admin` to the end of the URL.
|
||||
|
||||
7. Click on **Authorize Users** and make sure to add yourself as a managed user.
|
||||
|
||||
8. If you get any errors, please Google it. The errors are self-explanatory and should be easy to fix.
|
||||
|
||||
If everything went good, you'll get this screen:
|
||||
|
||||
{: width="1366" height="354"}
|
||||
|
||||
### Create Google Analytics Query
|
||||
|
||||
Head to `https://PROJECT_ID.REGION_ID.r.appspot.com/admin` and create a query after verifying the account. **GA Core Reporting API** query request can be created in [Query Explorer](https://ga-dev-tools.appspot.com/query-explorer/).
|
||||
|
||||
The query parameters are as follows:
|
||||
|
||||
- **start-date**: fill in the first day of blog posting
|
||||
- **end-date**: fill in `today` (this is a parameter supported by GA Report, which means that it will always end according to the current query date)
|
||||
- **metrics**: select `ga:pageviews`
|
||||
- **dimensions**: select `ga:pagePath`
|
||||
|
||||
In order to reduce the returned results and reduce the network bandwidth, we add custom filtering rules [^ga-filters]:
|
||||
|
||||
- **filters**: fill in `ga:pagePath=~^/posts/.*/$;ga:pagePath!@=`.
|
||||
|
||||
Among them, `;` means using _logical AND_ to concatenate two rules.
|
||||
|
||||
If the `site.baseurl` is specified, change the first filtering rule to `ga:pagePath=~^/BASE_URL/posts/.*/$`, where `BASE_URL` is the value of `site.baseurl`.
|
||||
|
||||
After <kbd>Run Query</kbd>, copy the generated contents of **API Query URI** at the bottom of the page and fill in the **Encoded URI for the query** of SuperProxy on GAE.
|
||||
|
||||
After the query is saved on GAE, a **Public Endpoint** (public access address) will be generated, and we will get the query result in JSON format when accessing it. Finally, click <kbd>Enable Endpoint</kbd> in **Public Request Endpoint** to make the query effective, and click <kbd>Start Scheduling</kbd> in **Scheduling** to start the scheduled task.
|
||||
|
||||
{: width="1100" height="126"}
|
||||
|
||||
## Configure Chirpy to Display Page View
|
||||
|
||||
Once all the hard part is done, it is very easy to enable the Page View on Chirpy theme. Your superProxy dashboard should look something like below and you can grab the required values.
|
||||
|
||||
{: width="1210" height="694"}
|
||||
|
||||
Update the `_config.yml`{: .filepath} file of [**Chirpy**][chirpy-homepage] project with the values from your dashboard, to look similar to the following:
|
||||
|
||||
```yaml
|
||||
google_analytics:
|
||||
id: 'G-V6XXXXXXX' # fill in your Google Analytics ID
|
||||
pv:
|
||||
proxy_endpoint: 'https://PROJECT_ID.REGION_ID.r.appspot.com/query?id=<ID FROM SUPER PROXY>'
|
||||
cache_path: # the local PV cache data, friendly to visitors from GFW region
|
||||
```
|
||||
{: file="_config.yml"}
|
||||
|
||||
Now, you should see the Page View enabled on your blog.
|
||||
|
||||
## Reference
|
||||
|
||||
[^ga-filters]: [Google Analytics Core Reporting API: Filters](https://developers.google.com/analytics/devguides/reporting/core/v3/reference#filters)
|
||||
|
||||
[chirpy-homepage]: https://github.com/cotes2020/jekyll-theme-chirpy/
|
||||
@@ -1,6 +1,4 @@
|
||||
/*
|
||||
The common styles
|
||||
*/
|
||||
/* The common styles */
|
||||
|
||||
html {
|
||||
@media (prefers-color-scheme: light) {
|
||||
@@ -73,52 +71,11 @@ img {
|
||||
height: auto;
|
||||
transition: all 0.35s ease-in-out;
|
||||
|
||||
&[data-src] {
|
||||
&[data-lqip='true'] {
|
||||
&.lazyload,
|
||||
&.lazyloading {
|
||||
-webkit-filter: blur(20px);
|
||||
filter: blur(20px);
|
||||
}
|
||||
}
|
||||
.blur & {
|
||||
$blur: 20px;
|
||||
|
||||
&:not([data-lqip='true']) {
|
||||
&.lazyload,
|
||||
&.lazyloading {
|
||||
background: var(--img-bg);
|
||||
}
|
||||
|
||||
&.lazyloaded {
|
||||
-webkit-animation: fade-in 0.35s ease-in;
|
||||
animation: fade-in 0.35s ease-in;
|
||||
}
|
||||
}
|
||||
|
||||
&.shadow {
|
||||
-webkit-filter: drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.08));
|
||||
filter: drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.08));
|
||||
box-shadow: none !important; /* cover the Bootstrap 4.6.1 styles */
|
||||
}
|
||||
|
||||
@extend %img-caption;
|
||||
}
|
||||
|
||||
@-webkit-keyframes fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
-webkit-filter: blur($blur);
|
||||
filter: blur($blur);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,6 +84,10 @@ blockquote {
|
||||
padding-left: 1rem;
|
||||
color: var(--blockquote-text-color);
|
||||
|
||||
> p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&[class^='prompt-'] {
|
||||
border-left: 0;
|
||||
position: relative;
|
||||
@@ -144,10 +105,6 @@ blockquote {
|
||||
text-rendering: auto;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
> p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@include prompt('tip', '\f0eb', 'regular');
|
||||
@@ -173,27 +130,25 @@ kbd {
|
||||
}
|
||||
|
||||
footer {
|
||||
font-size: 0.8rem;
|
||||
background-color: var(--main-bg);
|
||||
height: $footer-height;
|
||||
border-top: 1px solid var(--main-border-color);
|
||||
|
||||
div.d-flex {
|
||||
height: $footer-height;
|
||||
line-height: 1.2rem;
|
||||
padding-bottom: 1rem;
|
||||
border-top: 1px solid var(--main-border-color);
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
@extend %text-xs;
|
||||
|
||||
a {
|
||||
@extend %text-color;
|
||||
@extend %text-highlight;
|
||||
|
||||
&:hover {
|
||||
@extend %link-hover;
|
||||
}
|
||||
}
|
||||
|
||||
em {
|
||||
@extend %text-highlight;
|
||||
}
|
||||
|
||||
p {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
@@ -220,7 +175,7 @@ i {
|
||||
position: sticky;
|
||||
}
|
||||
|
||||
> div {
|
||||
> section {
|
||||
padding-left: 1rem;
|
||||
border-left: 1px solid var(--main-border-color);
|
||||
|
||||
@@ -229,7 +184,7 @@ i {
|
||||
}
|
||||
}
|
||||
|
||||
.post-content {
|
||||
.content {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
}
|
||||
@@ -237,13 +192,15 @@ i {
|
||||
#panel-wrapper {
|
||||
/* the headings */
|
||||
.panel-heading {
|
||||
font-family: inherit;
|
||||
line-height: inherit;
|
||||
|
||||
@include label(inherit);
|
||||
}
|
||||
|
||||
.post-tag {
|
||||
line-height: 1.05rem;
|
||||
font-size: 0.85rem;
|
||||
border: 1px solid var(--btn-border-color);
|
||||
border-radius: 0.8rem;
|
||||
padding: 0.3rem 0.5rem;
|
||||
margin: 0 0.35rem 0.5rem 0;
|
||||
@@ -255,16 +212,6 @@ i {
|
||||
}
|
||||
|
||||
#access-lastmod {
|
||||
li {
|
||||
height: 1.8rem;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
a {
|
||||
&:hover {
|
||||
@extend %link-hover;
|
||||
@@ -285,21 +232,13 @@ i {
|
||||
margin-bottom: 0.3rem;
|
||||
}
|
||||
|
||||
@extend %sup-fn-target;
|
||||
|
||||
> p {
|
||||
margin-left: 0.25em;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* [scroll-focus] added by `smooth-scroll.js` */
|
||||
&:target:not([scroll-focus]),
|
||||
&[scroll-focus='true'] > p {
|
||||
background-color: var(--footnote-target-bg);
|
||||
width: -moz-fit-content;
|
||||
width: -webkit-fit-content;
|
||||
width: fit-content;
|
||||
transition: background-color 1.5s ease-in-out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,14 +248,11 @@ i {
|
||||
@include pl-pr(2px);
|
||||
|
||||
border-bottom-style: none !important;
|
||||
transition: background-color 1.5s ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
/* [scroll-focus] added by `smooth-scroll.js` */
|
||||
@at-root sup:target:not([scroll-focus]),
|
||||
sup[scroll-focus='true'] > a#{&} {
|
||||
background-color: var(--footnote-target-bg);
|
||||
}
|
||||
sup {
|
||||
@extend %sup-fn-target;
|
||||
}
|
||||
|
||||
.reversefootnote {
|
||||
@@ -372,6 +308,31 @@ i {
|
||||
|
||||
/* --- post --- */
|
||||
|
||||
.preview-img {
|
||||
aspect-ratio: 40 / 21;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
@extend %rounded;
|
||||
|
||||
&:not(.no-bg) {
|
||||
background: var(--img-bg);
|
||||
}
|
||||
|
||||
img {
|
||||
height: 100%;
|
||||
-o-object-fit: cover;
|
||||
object-fit: cover;
|
||||
|
||||
@extend %rounded;
|
||||
|
||||
@at-root #post-list & {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.post-preview {
|
||||
@extend %rounded;
|
||||
|
||||
@@ -398,28 +359,33 @@ i {
|
||||
}
|
||||
}
|
||||
|
||||
.post {
|
||||
main {
|
||||
line-height: 1.75;
|
||||
|
||||
h1 {
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
p {
|
||||
> img[data-src],
|
||||
> a.popup {
|
||||
&:not(.normal):not(.left):not(.right) {
|
||||
@include align-center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pageviews .fa-spinner {
|
||||
font-size: 80%;
|
||||
.categories,
|
||||
#tags,
|
||||
#archives {
|
||||
a:not(:hover) {
|
||||
@extend %no-bottom-border;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.post-meta {
|
||||
font-size: 0.85rem;
|
||||
@extend %text-sm;
|
||||
|
||||
a {
|
||||
&:not([class]):hover {
|
||||
@@ -432,7 +398,7 @@ i {
|
||||
}
|
||||
}
|
||||
|
||||
.post-content {
|
||||
.content {
|
||||
font-size: 1.08rem;
|
||||
margin-top: 2rem;
|
||||
overflow-wrap: break-word;
|
||||
@@ -514,7 +480,7 @@ i {
|
||||
::marker {
|
||||
color: var(--text-muted-color);
|
||||
}
|
||||
} /* .post-content */
|
||||
} /* .content */
|
||||
|
||||
.tag:hover {
|
||||
@extend %tag-hover;
|
||||
@@ -524,9 +490,10 @@ i {
|
||||
display: inline-block;
|
||||
min-width: 2rem;
|
||||
text-align: center;
|
||||
border-radius: 0.3rem;
|
||||
border-radius: 0.5rem;
|
||||
border: 1px solid var(--btn-border-color);
|
||||
padding: 0 0.4rem;
|
||||
color: inherit;
|
||||
color: var(--text-muted-color);
|
||||
line-height: 1.3rem;
|
||||
|
||||
&:not(:last-child) {
|
||||
@@ -554,14 +521,15 @@ i {
|
||||
background: var(--shimmer-bg);
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
-webkit-animation: shimmer 1s infinite;
|
||||
animation: shimmer 1s infinite;
|
||||
-webkit-animation: shimmer 1.3s infinite;
|
||||
animation: shimmer 1.3s infinite;
|
||||
}
|
||||
|
||||
@-webkit-keyframes shimmer {
|
||||
0% {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
@@ -571,6 +539,7 @@ i {
|
||||
0% {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
@@ -584,7 +553,8 @@ i {
|
||||
|
||||
@extend %rounded;
|
||||
|
||||
&.youtube {
|
||||
&.youtube,
|
||||
&.bilibili {
|
||||
aspect-ratio: 16 / 9;
|
||||
}
|
||||
|
||||
@@ -632,7 +602,7 @@ i {
|
||||
}
|
||||
|
||||
.btn-box-shadow {
|
||||
box-shadow: 0 0 8px 0 var(--btn-box-shadow) !important;
|
||||
box-shadow: var(--card-shadow);
|
||||
}
|
||||
|
||||
/* overwrite bootstrap muted */
|
||||
@@ -673,12 +643,12 @@ i {
|
||||
|
||||
.left {
|
||||
float: left;
|
||||
margin: 0.75rem 1rem 1rem 0 !important;
|
||||
margin: 0.75rem 1rem 1rem 0;
|
||||
}
|
||||
|
||||
.right {
|
||||
float: right;
|
||||
margin: 0.75rem 0 1rem 1rem !important;
|
||||
margin: 0.75rem 0 1rem 1rem;
|
||||
}
|
||||
|
||||
/* --- Overriding --- */
|
||||
@@ -709,7 +679,6 @@ mjx-container {
|
||||
/* --- sidebar layout --- */
|
||||
|
||||
$sidebar-display: 'sidebar-display';
|
||||
$btn-gap: 0.8rem; // for the bottom icons
|
||||
$btn-border-width: 3px;
|
||||
$btn-mb: 0.5rem;
|
||||
|
||||
@@ -724,6 +693,7 @@ $btn-mb: 0.5rem;
|
||||
width: $sidebar-width;
|
||||
z-index: 99;
|
||||
background: var(--sidebar-bg);
|
||||
border-right: 1px solid var(--sidebar-border-color);
|
||||
|
||||
/* Hide scrollbar for Chrome, Safari and Opera */
|
||||
&::-webkit-scrollbar {
|
||||
@@ -771,23 +741,25 @@ $btn-mb: 0.5rem;
|
||||
}
|
||||
|
||||
.site-title {
|
||||
font-family: inherit;
|
||||
font-weight: 900;
|
||||
font-size: 1.75rem;
|
||||
line-height: 1.2;
|
||||
letter-spacing: 0.25px;
|
||||
color: rgba(134, 133, 133, 0.99);
|
||||
margin-top: 1.25rem;
|
||||
margin-bottom: 0.5rem;
|
||||
|
||||
a {
|
||||
@extend %clickable-transition;
|
||||
@extend %sidebar-link-hover;
|
||||
|
||||
color: var(--site-title-color);
|
||||
}
|
||||
}
|
||||
|
||||
.site-subtitle {
|
||||
font-size: 95%;
|
||||
color: var(--sidebar-muted-color);
|
||||
color: var(--site-subtitle-color);
|
||||
margin-top: 0.25rem;
|
||||
word-spacing: 1px;
|
||||
-webkit-user-select: none;
|
||||
@@ -847,13 +819,15 @@ $btn-mb: 0.5rem;
|
||||
}
|
||||
|
||||
.sidebar-bottom {
|
||||
@include pl-pr(2rem);
|
||||
|
||||
padding-left: 2rem;
|
||||
padding-right: 1rem;
|
||||
margin-bottom: 1.5rem;
|
||||
|
||||
$btn-size: 1.75rem;
|
||||
|
||||
%button {
|
||||
width: 1.75rem;
|
||||
height: 1.75rem;
|
||||
width: $btn-size;
|
||||
height: $btn-size;
|
||||
margin-bottom: $btn-mb; // multi line gap
|
||||
border-radius: 50%;
|
||||
color: var(--sidebar-btn-color);
|
||||
@@ -862,6 +836,7 @@ $btn-mb: 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: var(--sidebar-border-color) 0 0 0 1px;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--sidebar-hover-bg);
|
||||
@@ -874,12 +849,12 @@ $btn-mb: 0.5rem;
|
||||
@extend %clickable-transition;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: $btn-gap;
|
||||
margin-right: $sb-btn-gap;
|
||||
}
|
||||
}
|
||||
|
||||
i {
|
||||
line-height: 1.75rem;
|
||||
line-height: $btn-size;
|
||||
}
|
||||
|
||||
.mode-toggle {
|
||||
@@ -893,9 +868,9 @@ $btn-mb: 0.5rem;
|
||||
|
||||
.icon-border {
|
||||
@extend %no-cursor;
|
||||
@include ml-mr(calc(($btn-gap - $btn-border-width) / 2));
|
||||
@include ml-mr(calc(($sb-btn-gap - $btn-border-width) / 2));
|
||||
|
||||
background-color: var(--sidebar-muted-color);
|
||||
background-color: var(--sidebar-btn-color);
|
||||
content: '';
|
||||
width: $btn-border-width;
|
||||
height: $btn-border-width;
|
||||
@@ -925,7 +900,7 @@ $btn-mb: 0.5rem;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
|
||||
.post-content {
|
||||
.content {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
}
|
||||
@@ -938,14 +913,13 @@ $btn-mb: 0.5rem;
|
||||
}
|
||||
|
||||
#topbar {
|
||||
/* icons */
|
||||
i {
|
||||
button i {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
#breadcrumb {
|
||||
font-size: 1rem;
|
||||
color: gray;
|
||||
color: var(--text-muted-color);
|
||||
padding-left: 0.5rem;
|
||||
|
||||
a:hover {
|
||||
@@ -963,16 +937,51 @@ $btn-mb: 0.5rem;
|
||||
}
|
||||
} /* #topbar */
|
||||
|
||||
#sidebar-trigger,
|
||||
#search-trigger {
|
||||
display: none;
|
||||
::-webkit-input-placeholder {
|
||||
@include placeholder;
|
||||
}
|
||||
|
||||
#search-wrapper {
|
||||
::-moz-placeholder {
|
||||
@include placeholder;
|
||||
}
|
||||
|
||||
:-ms-input-placeholder {
|
||||
@include placeholder;
|
||||
}
|
||||
|
||||
::-ms-input-placeholder {
|
||||
@include placeholder;
|
||||
}
|
||||
|
||||
::placeholder {
|
||||
@include placeholder;
|
||||
}
|
||||
|
||||
:focus::-webkit-input-placeholder {
|
||||
@include placeholder-focus;
|
||||
}
|
||||
|
||||
:focus::-moz-placeholder {
|
||||
@include placeholder-focus;
|
||||
}
|
||||
|
||||
:focus:-ms-input-placeholder {
|
||||
@include placeholder-focus;
|
||||
}
|
||||
|
||||
:focus::-ms-input-placeholder {
|
||||
@include placeholder-focus;
|
||||
}
|
||||
|
||||
:focus::placeholder {
|
||||
@include placeholder-focus;
|
||||
}
|
||||
|
||||
search {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
border-radius: 1rem;
|
||||
border: 1px solid var(--search-wrapper-border-color);
|
||||
border: 1px solid var(--search-border-color);
|
||||
background: var(--main-bg);
|
||||
padding: 0 0.5rem;
|
||||
|
||||
@@ -983,11 +992,16 @@ $btn-mb: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
#sidebar-trigger,
|
||||
#search-trigger {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* 'Cancel' link */
|
||||
#search-cancel {
|
||||
color: var(--link-color);
|
||||
margin-left: 1rem;
|
||||
display: none;
|
||||
white-space: nowrap;
|
||||
|
||||
@extend %cursor-pointer;
|
||||
}
|
||||
@@ -1002,24 +1016,6 @@ $btn-mb: 0.5rem;
|
||||
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
|
||||
&.form-control {
|
||||
&::-moz-placeholder {
|
||||
@include input-placeholder;
|
||||
}
|
||||
&::-webkit-input-placeholder {
|
||||
@include input-placeholder;
|
||||
}
|
||||
&:-ms-input-placeholder {
|
||||
@include input-placeholder;
|
||||
}
|
||||
&::-ms-input-placeholder {
|
||||
@include input-placeholder;
|
||||
}
|
||||
&::placeholder {
|
||||
@include input-placeholder;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1065,7 +1061,7 @@ $btn-mb: 0.5rem;
|
||||
line-height: 2.5rem;
|
||||
}
|
||||
|
||||
> div {
|
||||
> article {
|
||||
width: 100%;
|
||||
|
||||
&:not(:last-child) {
|
||||
@@ -1103,22 +1099,6 @@ $btn-mb: 0.5rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#core-wrapper {
|
||||
line-height: 1.75;
|
||||
|
||||
.categories,
|
||||
#tags,
|
||||
#archives {
|
||||
a:not(:hover) {
|
||||
@extend %no-bottom-border;
|
||||
}
|
||||
}
|
||||
|
||||
@at-root .row:only-child > #{&} {
|
||||
padding-bottom: 3rem;
|
||||
}
|
||||
}
|
||||
|
||||
#mask {
|
||||
display: none;
|
||||
position: fixed;
|
||||
@@ -1132,38 +1112,44 @@ $btn-mb: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* --- main wrapper --- */
|
||||
/* --- basic wrappers --- */
|
||||
|
||||
#main-wrapper {
|
||||
background-color: var(--main-bg);
|
||||
position: relative;
|
||||
min-height: calc(100vh - $footer-height-mobile);
|
||||
|
||||
@include pl-pr(0);
|
||||
|
||||
> .container {
|
||||
min-height: 100vh;
|
||||
}
|
||||
}
|
||||
|
||||
#topbar-wrapper.row,
|
||||
#main > .row,
|
||||
#main-wrapper > .container > .row,
|
||||
#search-result-wrapper > .row {
|
||||
@include ml-mr(0);
|
||||
}
|
||||
|
||||
#tail-wrapper {
|
||||
> :not(script) {
|
||||
margin-top: 3rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* --- button back-to-top --- */
|
||||
|
||||
#back-to-top {
|
||||
$size: 3rem;
|
||||
|
||||
display: none;
|
||||
z-index: 1;
|
||||
cursor: pointer;
|
||||
position: fixed;
|
||||
right: 1rem;
|
||||
bottom: 2rem;
|
||||
bottom: calc($footer-height-large - $back2top-size / 2);
|
||||
background: var(--button-bg);
|
||||
color: var(--btn-backtotop-color);
|
||||
padding: 0;
|
||||
width: $size;
|
||||
height: $size;
|
||||
width: $back2top-size;
|
||||
height: $back2top-size;
|
||||
border-radius: 50%;
|
||||
border: 1px solid var(--btn-backtotop-border-color);
|
||||
transition: transform 0.2s ease-out;
|
||||
@@ -1175,7 +1161,7 @@ $btn-mb: 0.5rem;
|
||||
}
|
||||
|
||||
i {
|
||||
line-height: $size;
|
||||
line-height: $back2top-size;
|
||||
position: relative;
|
||||
bottom: 2px;
|
||||
}
|
||||
@@ -1241,18 +1227,10 @@ $btn-mb: 0.5rem;
|
||||
*/
|
||||
|
||||
@media all and (max-width: 576px) {
|
||||
#main-wrapper {
|
||||
min-height: calc(100vh - #{$footer-height-mobile});
|
||||
}
|
||||
|
||||
#core-wrapper {
|
||||
min-height: calc(
|
||||
100vh - #{$topbar-height} - #{$footer-height-mobile}
|
||||
) !important;
|
||||
|
||||
.post-content {
|
||||
main {
|
||||
.content {
|
||||
> blockquote[class^='prompt-'] {
|
||||
@include ml-mr(-1.25rem);
|
||||
@include ml-mr(-1rem);
|
||||
|
||||
border-radius: 0;
|
||||
max-width: none;
|
||||
@@ -1275,7 +1253,7 @@ $btn-mb: 0.5rem;
|
||||
@extend %full-width;
|
||||
}
|
||||
|
||||
#main {
|
||||
#main-wrapper > .container {
|
||||
@extend %full-width;
|
||||
@include pl-pr(0);
|
||||
}
|
||||
@@ -1293,21 +1271,11 @@ $btn-mb: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
footer {
|
||||
@include slide;
|
||||
|
||||
height: $footer-height-mobile;
|
||||
|
||||
div.d-flex {
|
||||
padding: 1.5rem 0;
|
||||
line-height: 1.65;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
height: $footer-height-large;
|
||||
padding: 1.5rem 0;
|
||||
}
|
||||
|
||||
[#{$sidebar-display}] {
|
||||
@@ -1315,9 +1283,8 @@ $btn-mb: 0.5rem;
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
#main-wrapper,
|
||||
footer {
|
||||
transform: translateX(#{$sidebar-width});
|
||||
#main-wrapper {
|
||||
transform: translateX($sidebar-width);
|
||||
}
|
||||
|
||||
#back-to-top {
|
||||
@@ -1328,8 +1295,8 @@ $btn-mb: 0.5rem;
|
||||
#sidebar {
|
||||
@include slide;
|
||||
|
||||
transform: translateX(-#{$sidebar-width}); /* hide */
|
||||
-webkit-transform: translateX(-#{$sidebar-width});
|
||||
transform: translateX(-$sidebar-width); /* hide */
|
||||
-webkit-transform: translateX(-$sidebar-width);
|
||||
}
|
||||
|
||||
#main-wrapper {
|
||||
@@ -1337,8 +1304,7 @@ $btn-mb: 0.5rem;
|
||||
}
|
||||
|
||||
#topbar,
|
||||
#main,
|
||||
footer > .container {
|
||||
#main-wrapper > .container {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
@@ -1347,7 +1313,7 @@ $btn-mb: 0.5rem;
|
||||
}
|
||||
|
||||
#breadcrumb,
|
||||
#search-wrapper {
|
||||
search {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -1357,7 +1323,7 @@ $btn-mb: 0.5rem;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#core-wrapper,
|
||||
main,
|
||||
#panel-wrapper {
|
||||
margin-top: 0;
|
||||
}
|
||||
@@ -1368,7 +1334,7 @@ $btn-mb: 0.5rem;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#search-result-wrapper .post-content {
|
||||
#search-result-wrapper .content {
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
@@ -1379,19 +1345,12 @@ $btn-mb: 0.5rem;
|
||||
h1.dynamic-title {
|
||||
display: none;
|
||||
|
||||
~ .post-content {
|
||||
~ .content {
|
||||
margin-top: 2.5rem;
|
||||
}
|
||||
}
|
||||
} /* max-width: 849px */
|
||||
|
||||
/* Phone & Pad */
|
||||
@media all and (min-width: 577px) and (max-width: 1199px) {
|
||||
footer .d-flex > div {
|
||||
width: 312px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sidebar is visible */
|
||||
@media all and (min-width: 850px) {
|
||||
/* Solved jumping scrollbar */
|
||||
@@ -1399,26 +1358,8 @@ $btn-mb: 0.5rem;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
#main-wrapper,
|
||||
footer {
|
||||
margin-left: $sidebar-width;
|
||||
}
|
||||
|
||||
#main-wrapper {
|
||||
min-height: calc(100vh - $footer-height);
|
||||
}
|
||||
|
||||
footer {
|
||||
p {
|
||||
width: auto;
|
||||
&:last-child {
|
||||
&::before {
|
||||
content: '-';
|
||||
margin: 0 0.75rem;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
margin-left: $sidebar-width;
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
@@ -1431,7 +1372,7 @@ $btn-mb: 0.5rem;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#search-wrapper {
|
||||
search {
|
||||
max-width: $search-max-width;
|
||||
}
|
||||
|
||||
@@ -1440,20 +1381,20 @@ $btn-mb: 0.5rem;
|
||||
justify-content: start !important;
|
||||
}
|
||||
|
||||
.post {
|
||||
main {
|
||||
h1 {
|
||||
margin-top: 3rem;
|
||||
}
|
||||
}
|
||||
|
||||
div.post-content .table-wrapper > table {
|
||||
div.content .table-wrapper > table {
|
||||
min-width: 70%;
|
||||
}
|
||||
|
||||
/* button 'back-to-Top' position */
|
||||
#back-to-top {
|
||||
bottom: 5.5rem;
|
||||
right: 5%;
|
||||
bottom: calc($footer-height - $back2top-size / 2);
|
||||
}
|
||||
|
||||
#topbar-title {
|
||||
@@ -1463,7 +1404,7 @@ $btn-mb: 0.5rem;
|
||||
|
||||
/* Pad horizontal */
|
||||
@media all and (min-width: 992px) and (max-width: 1199px) {
|
||||
#main .col-lg-11 {
|
||||
#main-wrapper > .container .col-lg-11 {
|
||||
flex: 0 0 96%;
|
||||
max-width: 96%;
|
||||
}
|
||||
@@ -1490,7 +1431,7 @@ $btn-mb: 0.5rem;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#main > div.row {
|
||||
#main-wrapper > .container > div.row {
|
||||
justify-content: center !important;
|
||||
}
|
||||
}
|
||||
@@ -1498,11 +1439,7 @@ $btn-mb: 0.5rem;
|
||||
/* --- desktop mode, both sidebar and panel are visible --- */
|
||||
|
||||
@media all and (min-width: 1200px) {
|
||||
#back-to-top {
|
||||
bottom: 6.5rem;
|
||||
}
|
||||
|
||||
#search-wrapper {
|
||||
search {
|
||||
margin-right: 4rem;
|
||||
}
|
||||
|
||||
@@ -1510,8 +1447,8 @@ $btn-mb: 0.5rem;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
#search-results > div {
|
||||
width: 46%;
|
||||
#search-results > article {
|
||||
width: 45%;
|
||||
|
||||
&:nth-child(odd) {
|
||||
margin-right: 1.5rem;
|
||||
@@ -1527,28 +1464,21 @@ $btn-mb: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.post-content {
|
||||
.content {
|
||||
font-size: 1.03rem;
|
||||
}
|
||||
|
||||
footer {
|
||||
div.d-felx {
|
||||
width: 85%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (min-width: 1400px) {
|
||||
#back-to-top {
|
||||
right: calc((100vw - #{$sidebar-width} - 1140px) / 2 + 3rem);
|
||||
right: calc((100vw - $sidebar-width - 1140px) / 2 + 3rem);
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (min-width: 1650px) {
|
||||
$icon-gap: 1rem;
|
||||
|
||||
#main-wrapper,
|
||||
footer {
|
||||
#main-wrapper {
|
||||
margin-left: $sidebar-width-large;
|
||||
}
|
||||
|
||||
@@ -1556,35 +1486,32 @@ $btn-mb: 0.5rem;
|
||||
left: $sidebar-width-large;
|
||||
}
|
||||
|
||||
#search-wrapper {
|
||||
search {
|
||||
margin-right: calc(
|
||||
#{$main-content-max-width} * 0.25 - #{$search-max-width} - 0.75rem
|
||||
$main-content-max-width / 4 - $search-max-width - 0.75rem
|
||||
);
|
||||
}
|
||||
|
||||
#main,
|
||||
footer > .container {
|
||||
#main-wrapper > .container {
|
||||
max-width: $main-content-max-width;
|
||||
padding-left: 1.75rem !important;
|
||||
padding-right: 1.75rem !important;
|
||||
}
|
||||
|
||||
#core-wrapper,
|
||||
main.col-12,
|
||||
#tail-wrapper {
|
||||
padding-right: 4.5rem !important;
|
||||
}
|
||||
|
||||
#back-to-top {
|
||||
right: calc(
|
||||
(100vw - #{$sidebar-width-large} - #{$main-content-max-width}) / 2 + 2rem
|
||||
(100vw - $sidebar-width-large - $main-content-max-width) / 2 + 2rem
|
||||
);
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
width: $sidebar-width-large;
|
||||
|
||||
$icon-gap: 1rem; // for the bottom icons
|
||||
|
||||
.profile-wrapper {
|
||||
margin-top: 3.5rem;
|
||||
margin-bottom: 2.5rem;
|
||||
@@ -1602,11 +1529,11 @@ $btn-mb: 0.5rem;
|
||||
margin-bottom: 1.75rem;
|
||||
|
||||
a:not(:last-child) {
|
||||
margin-right: $icon-gap;
|
||||
margin-right: $sb-btn-gap-lg;
|
||||
}
|
||||
|
||||
.icon-border {
|
||||
@include ml-mr(calc(($icon-gap - $btn-border-width) / 2));
|
||||
@include ml-mr(calc(($sb-btn-gap-lg - $btn-border-width) / 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
}
|
||||
|
||||
%section {
|
||||
#core-wrapper & {
|
||||
main & {
|
||||
margin-top: 2.5rem;
|
||||
margin-bottom: 1.25rem;
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
}
|
||||
|
||||
%sidebar-links {
|
||||
color: rgba(117, 117, 117, 0.9);
|
||||
color: var(--sidebar-muted-color);
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
@@ -122,6 +122,29 @@
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
%text-highlight {
|
||||
color: var(--text-muted-hightlight-color);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
%text-sm {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
%text-xs {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
%sup-fn-target {
|
||||
&:target {
|
||||
background-color: var(--footnote-target-bg);
|
||||
width: -moz-fit-content;
|
||||
width: -webkit-fit-content;
|
||||
width: fit-content;
|
||||
transition: background-color 1.75s ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------- scss mixin --------- */
|
||||
|
||||
@mixin mt-mb($value) {
|
||||
@@ -144,7 +167,11 @@
|
||||
padding-right: $val;
|
||||
}
|
||||
|
||||
@mixin input-placeholder {
|
||||
@mixin placeholder {
|
||||
color: var(--text-muted-color) !important;
|
||||
}
|
||||
|
||||
@mixin placeholder-focus {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* The syntax highlight.
|
||||
*/
|
||||
|
||||
@import 'colors/light-syntax';
|
||||
@import 'colors/dark-syntax';
|
||||
@import 'colors/syntax-light';
|
||||
@import 'colors/syntax-dark';
|
||||
|
||||
html {
|
||||
@media (prefers-color-scheme: light) {
|
||||
@@ -55,8 +55,7 @@ html {
|
||||
}
|
||||
|
||||
overflow: auto;
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 1rem;
|
||||
padding-bottom: 0.75rem;
|
||||
|
||||
pre {
|
||||
margin-bottom: 0;
|
||||
@@ -66,15 +65,25 @@ html {
|
||||
}
|
||||
|
||||
table {
|
||||
td pre {
|
||||
overflow: visible; /* Fixed iOS safari overflow-x */
|
||||
word-break: normal; /* Fixed iOS safari linenos code break */
|
||||
td {
|
||||
&:first-child {
|
||||
display: inline-block;
|
||||
margin-left: 1rem;
|
||||
margin-right: 0.75rem;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
padding-right: 2rem !important;
|
||||
}
|
||||
|
||||
pre {
|
||||
overflow: visible; /* Fixed iOS safari overflow-x */
|
||||
word-break: normal; /* Fixed iOS safari linenos code break */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.lineno {
|
||||
padding-right: 0.5rem;
|
||||
min-width: 2.2rem;
|
||||
text-align: right;
|
||||
color: var(--highlight-lineno-color);
|
||||
-webkit-user-select: none;
|
||||
@@ -89,6 +98,7 @@ code {
|
||||
-webkit-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
color: var(--code-color);
|
||||
|
||||
&.highlighter-rouge {
|
||||
font-size: $code-font-size;
|
||||
@@ -139,11 +149,16 @@ div[class^='language-'] {
|
||||
|
||||
box-shadow: var(--language-border-color) 0 0 0 1px;
|
||||
|
||||
.post-content > & {
|
||||
@include ml-mr(-1.25rem);
|
||||
.content > & {
|
||||
@include ml-mr(-1rem);
|
||||
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hide line numbers for default, console, and terminal code snippets */
|
||||
@@ -152,12 +167,13 @@ div {
|
||||
&.language-plaintext,
|
||||
&.language-console,
|
||||
&.language-terminal {
|
||||
pre.lineno {
|
||||
display: none;
|
||||
}
|
||||
td:first-child {
|
||||
padding: 0 !important;
|
||||
margin-right: 0;
|
||||
|
||||
td.rouge-code {
|
||||
padding-left: 1.5rem;
|
||||
.lineno {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,21 +181,21 @@ div {
|
||||
.code-header {
|
||||
@extend %no-cursor;
|
||||
|
||||
$code-header-height: 2.25rem;
|
||||
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: $code-header-height;
|
||||
margin-left: 1rem;
|
||||
margin-right: 0.5rem;
|
||||
margin-left: 0.75rem;
|
||||
margin-right: 0.25rem;
|
||||
|
||||
/* the label block */
|
||||
span {
|
||||
line-height: $code-header-height;
|
||||
|
||||
/* label icon */
|
||||
i {
|
||||
font-size: 1rem;
|
||||
margin-right: 0.5rem;
|
||||
width: $code-icon-width;
|
||||
color: var(--code-header-icon-color);
|
||||
|
||||
&.small {
|
||||
@@ -242,7 +258,7 @@ div {
|
||||
|
||||
@media all and (min-width: 576px) {
|
||||
div[class^='language-'] {
|
||||
.post-content > & {
|
||||
.content > & {
|
||||
@include ml-mr(0);
|
||||
|
||||
border-radius: $base-radius;
|
||||
@@ -251,19 +267,25 @@ div {
|
||||
.code-header {
|
||||
@include ml-mr(0);
|
||||
|
||||
&::before {
|
||||
$dot-size: 0.75rem;
|
||||
$dot-margin: 0.5rem;
|
||||
$dot-margin: 1rem;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
margin-left: 1rem;
|
||||
width: $dot-size;
|
||||
height: $dot-size;
|
||||
margin-left: $dot-margin;
|
||||
width: $code-dot-size;
|
||||
height: $code-dot-size;
|
||||
border-radius: 50%;
|
||||
background-color: var(--code-header-muted-color);
|
||||
box-shadow: ($dot-size + $dot-margin) 0 0 var(--code-header-muted-color),
|
||||
($dot-size + $dot-margin) * 2 0 0 var(--code-header-muted-color);
|
||||
box-shadow: ($code-dot-size + $code-dot-gap) 0 0
|
||||
var(--code-header-muted-color),
|
||||
($code-dot-size + $code-dot-gap) * 2 0 0
|
||||
var(--code-header-muted-color);
|
||||
}
|
||||
|
||||
span {
|
||||
// center the text of label
|
||||
margin-left: calc(($dot-margin + $code-dot-size) / 2 * -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,22 +6,28 @@
|
||||
|
||||
$sidebar-width: 260px !default; /* the basic width */
|
||||
$sidebar-width-large: 300px !default; /* screen width: >= 1650px */
|
||||
$sb-btn-gap: 0.8rem !default;
|
||||
$sb-btn-gap-lg: 1rem !default;
|
||||
|
||||
/* other framework sizes */
|
||||
|
||||
$topbar-height: 3rem !default;
|
||||
$search-max-width: 210px !default;
|
||||
$search-max-width: 200px !default;
|
||||
$footer-height: 5rem !default;
|
||||
$footer-height-mobile: 6rem !default; /* screen width: < 850px */
|
||||
$footer-height-large: 6rem !default; /* screen width: < 850px */
|
||||
$main-content-max-width: 1250px !default;
|
||||
$bottom-min-height: 35rem !default;
|
||||
$base-radius: 0.5rem;
|
||||
$base-radius: 0.625rem !default;
|
||||
$back2top-size: 2.75rem !default;
|
||||
|
||||
/* syntax highlight */
|
||||
|
||||
$code-font-size: 0.85rem !default;
|
||||
$code-header-height: 2.25rem !default;
|
||||
$code-dot-size: 0.75rem !default;
|
||||
$code-dot-gap: 0.5rem !default;
|
||||
$code-icon-width: 1.75rem !default;
|
||||
|
||||
/* fonts */
|
||||
|
||||
$font-family-base: 'Source Sans Pro', 'Microsoft Yahei', sans-serif;
|
||||
$font-family-heading: Lato, 'Microsoft Yahei', sans-serif;
|
||||
$font-family-base: 'Source Sans Pro', 'Microsoft Yahei', sans-serif !default;
|
||||
$font-family-heading: Lato, 'Microsoft Yahei', sans-serif !default;
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* The syntax dark mode styles.
|
||||
*/
|
||||
|
||||
@mixin dark-syntax {
|
||||
--language-border-color: rgba(84, 83, 83, 0.27);
|
||||
--highlight-bg-color: #252525;
|
||||
--highlighter-rouge-color: #de6b18;
|
||||
--highlight-lineno-color: #6c6c6d;
|
||||
--inline-code-bg: #272822;
|
||||
--code-header-text-color: #6a6a6a;
|
||||
--code-header-muted-color: rgb(60, 60, 60);
|
||||
--code-header-icon-color: rgb(86, 86, 86);
|
||||
--clipboard-checked-color: #2bcc2b;
|
||||
--filepath-text-color: #bdbdbd;
|
||||
|
||||
/* override Bootstrap */
|
||||
pre {
|
||||
color: #bfbfbf;
|
||||
}
|
||||
|
||||
.highlight .gp {
|
||||
color: #818c96;
|
||||
}
|
||||
|
||||
/* syntax highlight colors from https://raw.githubusercontent.com/jwarby/pygments-css/master/monokai.css */
|
||||
|
||||
.highlight pre { background-color: var(--highlight-bg-color); }
|
||||
.highlight .hll { background-color: var(--highlight-bg-color); }
|
||||
.highlight .c { color: #75715e; } /* Comment */
|
||||
.highlight .err { color: #960050; background-color: #1e0010; } /* Error */
|
||||
.highlight .k { color: #66d9ef; } /* Keyword */
|
||||
.highlight .l { color: #ae81ff; } /* Literal */
|
||||
.highlight .n { color: #f8f8f2; } /* Name */
|
||||
.highlight .o { color: #f92672; } /* Operator */
|
||||
.highlight .p { color: #f8f8f2; } /* Punctuation */
|
||||
.highlight .cm { color: #75715e; } /* Comment.Multiline */
|
||||
.highlight .cp { color: #75715e; } /* Comment.Preproc */
|
||||
.highlight .c1 { color: #75715e; } /* Comment.Single */
|
||||
.highlight .cs { color: #75715e; } /* Comment.Special */
|
||||
.highlight .ge { color: inherit; font-style: italic; } /* Generic.Emph */
|
||||
.highlight .gs { font-weight: bold; } /* Generic.Strong */
|
||||
.highlight .kc { color: #66d9ef; } /* Keyword.Constant */
|
||||
.highlight .kd { color: #66d9ef; } /* Keyword.Declaration */
|
||||
.highlight .kn { color: #f92672; } /* Keyword.Namespace */
|
||||
.highlight .kp { color: #66d9ef; } /* Keyword.Pseudo */
|
||||
.highlight .kr { color: #66d9ef; } /* Keyword.Reserved */
|
||||
.highlight .kt { color: #66d9ef; } /* Keyword.Type */
|
||||
.highlight .ld { color: #e6db74; } /* Literal.Date */
|
||||
.highlight .m { color: #ae81ff; } /* Literal.Number */
|
||||
.highlight .s { color: #e6db74; } /* Literal.String */
|
||||
.highlight .na { color: #a6e22e; } /* Name.Attribute */
|
||||
.highlight .nb { color: #f8f8f2; } /* Name.Builtin */
|
||||
.highlight .nc { color: #a6e22e; } /* Name.Class */
|
||||
.highlight .no { color: #66d9ef; } /* Name.Constant */
|
||||
.highlight .nd { color: #a6e22e; } /* Name.Decorator */
|
||||
.highlight .ni { color: #f8f8f2; } /* Name.Entity */
|
||||
.highlight .ne { color: #a6e22e; } /* Name.Exception */
|
||||
.highlight .nf { color: #a6e22e; } /* Name.Function */
|
||||
.highlight .nl { color: #f8f8f2; } /* Name.Label */
|
||||
.highlight .nn { color: #f8f8f2; } /* Name.Namespace */
|
||||
.highlight .nx { color: #a6e22e; } /* Name.Other */
|
||||
.highlight .py { color: #f8f8f2; } /* Name.Property */
|
||||
.highlight .nt { color: #f92672; } /* Name.Tag */
|
||||
.highlight .nv { color: #f8f8f2; } /* Name.Variable */
|
||||
.highlight .ow { color: #f92672; } /* Operator.Word */
|
||||
.highlight .w { color: #f8f8f2; } /* Text.Whitespace */
|
||||
.highlight .mf { color: #ae81ff; } /* Literal.Number.Float */
|
||||
.highlight .mh { color: #ae81ff; } /* Literal.Number.Hex */
|
||||
.highlight .mi { color: #ae81ff; } /* Literal.Number.Integer */
|
||||
.highlight .mo { color: #ae81ff; } /* Literal.Number.Oct */
|
||||
.highlight .sb { color: #e6db74; } /* Literal.String.Backtick */
|
||||
.highlight .sc { color: #e6db74; } /* Literal.String.Char */
|
||||
.highlight .sd { color: #e6db74; } /* Literal.String.Doc */
|
||||
.highlight .s2 { color: #e6db74; } /* Literal.String.Double */
|
||||
.highlight .se { color: #ae81ff; } /* Literal.String.Escape */
|
||||
.highlight .sh { color: #e6db74; } /* Literal.String.Heredoc */
|
||||
.highlight .si { color: #e6db74; } /* Literal.String.Interpol */
|
||||
.highlight .sx { color: #e6db74; } /* Literal.String.Other */
|
||||
.highlight .sr { color: #e6db74; } /* Literal.String.Regex */
|
||||
.highlight .s1 { color: #e6db74; } /* Literal.String.Single */
|
||||
.highlight .ss { color: #e6db74; } /* Literal.String.Symbol */
|
||||
.highlight .bp { color: #f8f8f2; } /* Name.Builtin.Pseudo */
|
||||
.highlight .vc { color: #f8f8f2; } /* Name.Variable.Class */
|
||||
.highlight .vg { color: #f8f8f2; } /* Name.Variable.Global */
|
||||
.highlight .vi { color: #f8f8f2; } /* Name.Variable.Instance */
|
||||
.highlight .il { color: #ae81ff; } /* Literal.Number.Integer.Long */
|
||||
.highlight .gu { color: #75715e; } /* Generic.Subheading & Diff Unified/Comment? */
|
||||
.highlight .gd { color: #f92672; background-color: #561c08; } /* Generic.Deleted & Diff Deleted */
|
||||
.highlight .gi { color: #a6e22e; background-color: #0b5858; } /* Generic.Inserted & Diff Inserted */
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* The syntax light mode code snippet colors.
|
||||
*/
|
||||
|
||||
@mixin light-syntax {
|
||||
/* see: <https://raw.githubusercontent.com/jwarby/pygments-css/master/github.css> */
|
||||
.highlight .hll { background-color: #ffffcc; }
|
||||
.highlight .c { color: #999988; font-style: italic; } /* Comment */
|
||||
.highlight .err { color: #a61717; background-color: #e3d2d2; } /* Error */
|
||||
.highlight .k { color: #000000; font-weight: bold; } /* Keyword */
|
||||
.highlight .o { color: #000000; font-weight: bold; } /* Operator */
|
||||
.highlight .cm { color: #999988; font-style: italic; } /* Comment.Multiline */
|
||||
.highlight .cp { color: #999999; font-weight: bold; font-style: italic; } /* Comment.Preproc */
|
||||
.highlight .c1 { color: #999988; font-style: italic; } /* Comment.Single */
|
||||
.highlight .cs { color: #999999; font-weight: bold; font-style: italic; } /* Comment.Special */
|
||||
.highlight .gd { color: #d01040; background-color: #ffdddd; } /* Generic.Deleted */
|
||||
.highlight .ge { color: #000000; font-style: italic; } /* Generic.Emph */
|
||||
.highlight .gr { color: #aa0000; } /* Generic.Error */
|
||||
.highlight .gh { color: #999999; } /* Generic.Heading */
|
||||
.highlight .gi { color: #008080; background-color: #ddffdd; } /* Generic.Inserted */
|
||||
.highlight .go { color: #888888; } /* Generic.Output */
|
||||
.highlight .gp { color: #555555; } /* Generic.Prompt */
|
||||
.highlight .gs { font-weight: bold; } /* Generic.Strong */
|
||||
.highlight .gu { color: #aaaaaa; } /* Generic.Subheading */
|
||||
.highlight .gt { color: #aa0000; } /* Generic.Traceback */
|
||||
.highlight .kc { color: #000000; font-weight: bold; } /* Keyword.Constant */
|
||||
.highlight .kd { color: #000000; font-weight: bold; } /* Keyword.Declaration */
|
||||
.highlight .kn { color: #000000; font-weight: bold; } /* Keyword.Namespace */
|
||||
.highlight .kp { color: #000000; font-weight: bold; } /* Keyword.Pseudo */
|
||||
.highlight .kr { color: #000000; font-weight: bold; } /* Keyword.Reserved */
|
||||
.highlight .kt { color: #445588; font-weight: bold; } /* Keyword.Type */
|
||||
.highlight .m { color: #009999; } /* Literal.Number */
|
||||
.highlight .s { color: #d01040; } /* Literal.String */
|
||||
.highlight .na { color: #008080; } /* Name.Attribute */
|
||||
.highlight .nb { color: #0086b3; } /* Name.Builtin */
|
||||
.highlight .nc { color: #445588; font-weight: bold; } /* Name.Class */
|
||||
.highlight .no { color: #008080; } /* Name.Constant */
|
||||
.highlight .nd { color: #3c5d5d; font-weight: bold; } /* Name.Decorator */
|
||||
.highlight .ni { color: #800080; } /* Name.Entity */
|
||||
.highlight .ne { color: #990000; font-weight: bold; } /* Name.Exception */
|
||||
.highlight .nf { color: #990000; font-weight: bold; } /* Name.Function */
|
||||
.highlight .nl { color: #990000; font-weight: bold; } /* Name.Label */
|
||||
.highlight .nn { color: #555555; } /* Name.Namespace */
|
||||
.highlight .nt { color: #000080; } /* Name.Tag */
|
||||
.highlight .nv { color: #008080; } /* Name.Variable */
|
||||
.highlight .ow { color: #000000; font-weight: bold; } /* Operator.Word */
|
||||
.highlight .w { color: #bbbbbb; } /* Text.Whitespace */
|
||||
.highlight .mf { color: #009999; } /* Literal.Number.Float */
|
||||
.highlight .mh { color: #009999; } /* Literal.Number.Hex */
|
||||
.highlight .mi { color: #009999; } /* Literal.Number.Integer */
|
||||
.highlight .mo { color: #009999; } /* Literal.Number.Oct */
|
||||
.highlight .sb { color: #d01040; } /* Literal.String.Backtick */
|
||||
.highlight .sc { color: #d01040; } /* Literal.String.Char */
|
||||
.highlight .sd { color: #d01040; } /* Literal.String.Doc */
|
||||
.highlight .s2 { color: #d01040; } /* Literal.String.Double */
|
||||
.highlight .se { color: #d01040; } /* Literal.String.Escape */
|
||||
.highlight .sh { color: #d01040; } /* Literal.String.Heredoc */
|
||||
.highlight .si { color: #d01040; } /* Literal.String.Interpol */
|
||||
.highlight .sx { color: #d01040; } /* Literal.String.Other */
|
||||
.highlight .sr { color: #009926; } /* Literal.String.Regex */
|
||||
.highlight .s1 { color: #d01040; } /* Literal.String.Single */
|
||||
.highlight .ss { color: #990073; } /* Literal.String.Symbol */
|
||||
.highlight .bp { color: #999999; } /* Name.Builtin.Pseudo */
|
||||
.highlight .vc { color: #008080; } /* Name.Variable.Class */
|
||||
.highlight .vg { color: #008080; } /* Name.Variable.Global */
|
||||
.highlight .vi { color: #008080; } /* Name.Variable.Instance */
|
||||
.highlight .il { color: #009999; } /* Literal.Number.Integer.Long */
|
||||
|
||||
/* --- custom light colors --- */
|
||||
--language-border-color: rgba(172, 169, 169, 0.2);
|
||||
--highlight-bg-color: #f7f7f7;
|
||||
--highlighter-rouge-color: #3f596f;
|
||||
--highlight-lineno-color: #c2c6cc;
|
||||
--inline-code-bg: #f6f6f7;
|
||||
--code-header-text-color: #a3a3b1;
|
||||
--code-header-muted-color: #ebebeb;
|
||||
--code-header-icon-color: #d1d1d1;
|
||||
--clipboard-checked-color: #43c743;
|
||||
|
||||
[class^='prompt-'] {
|
||||
--inline-code-bg: #fbfafa;
|
||||
}
|
||||
} /* light-syntax */
|
||||
164
_sass/colors/syntax-dark.scss
Normal file
164
_sass/colors/syntax-dark.scss
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* The syntax dark mode styles.
|
||||
*/
|
||||
|
||||
@mixin dark-syntax {
|
||||
--language-border-color: #2d2d2d;
|
||||
--highlight-bg-color: #151515;
|
||||
--highlighter-rouge-color: #c9def1;
|
||||
--highlight-lineno-color: #808080;
|
||||
--inline-code-bg: #323238;
|
||||
--code-color: #b0b0b0;
|
||||
--code-header-text-color: #6a6a6a;
|
||||
--code-header-muted-color: #353535;
|
||||
--code-header-icon-color: #565656;
|
||||
--clipboard-checked-color: #2bcc2b;
|
||||
--filepath-text-color: #cacaca;
|
||||
|
||||
.highlight .gp {
|
||||
color: #87939d;
|
||||
}
|
||||
|
||||
/* --- Syntax highlight theme from `rougify style base16.dark` --- */
|
||||
|
||||
.highlight table td {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.highlight table pre {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.highlight,
|
||||
.highlight .w {
|
||||
color: #d0d0d0;
|
||||
background-color: #151515;
|
||||
}
|
||||
|
||||
.highlight .err {
|
||||
color: #151515;
|
||||
background-color: #ac4142;
|
||||
}
|
||||
|
||||
.highlight .c,
|
||||
.highlight .ch,
|
||||
.highlight .cd,
|
||||
.highlight .cm,
|
||||
.highlight .cpf,
|
||||
.highlight .c1,
|
||||
.highlight .cs {
|
||||
color: #848484;
|
||||
}
|
||||
|
||||
.highlight .cp {
|
||||
color: #f4bf75;
|
||||
}
|
||||
|
||||
.highlight .nt {
|
||||
color: #f4bf75;
|
||||
}
|
||||
|
||||
.highlight .o,
|
||||
.highlight .ow {
|
||||
color: #d0d0d0;
|
||||
}
|
||||
|
||||
.highlight .p,
|
||||
.highlight .pi {
|
||||
color: #d0d0d0;
|
||||
}
|
||||
|
||||
.highlight .gi {
|
||||
color: #90a959;
|
||||
}
|
||||
|
||||
.highlight .gd {
|
||||
color: #f08a8b;
|
||||
background-color: #320000;
|
||||
}
|
||||
|
||||
.highlight .gh {
|
||||
color: #6a9fb5;
|
||||
background-color: #151515;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.highlight .k,
|
||||
.highlight .kn,
|
||||
.highlight .kp,
|
||||
.highlight .kr,
|
||||
.highlight .kv {
|
||||
color: #aa759f;
|
||||
}
|
||||
|
||||
.highlight .kc {
|
||||
color: #d28445;
|
||||
}
|
||||
|
||||
.highlight .kt {
|
||||
color: #d28445;
|
||||
}
|
||||
|
||||
.highlight .kd {
|
||||
color: #d28445;
|
||||
}
|
||||
|
||||
.highlight .s,
|
||||
.highlight .sb,
|
||||
.highlight .sc,
|
||||
.highlight .dl,
|
||||
.highlight .sd,
|
||||
.highlight .s2,
|
||||
.highlight .sh,
|
||||
.highlight .sx,
|
||||
.highlight .s1 {
|
||||
color: #90a959;
|
||||
}
|
||||
|
||||
.highlight .sa {
|
||||
color: #aa759f;
|
||||
}
|
||||
|
||||
.highlight .sr {
|
||||
color: #75b5aa;
|
||||
}
|
||||
|
||||
.highlight .si {
|
||||
color: #b76d45;
|
||||
}
|
||||
|
||||
.highlight .se {
|
||||
color: #b76d45;
|
||||
}
|
||||
|
||||
.highlight .nn {
|
||||
color: #f4bf75;
|
||||
}
|
||||
|
||||
.highlight .nc {
|
||||
color: #f4bf75;
|
||||
}
|
||||
|
||||
.highlight .no {
|
||||
color: #f4bf75;
|
||||
}
|
||||
|
||||
.highlight .na {
|
||||
color: #6a9fb5;
|
||||
}
|
||||
|
||||
.highlight .m,
|
||||
.highlight .mb,
|
||||
.highlight .mf,
|
||||
.highlight .mh,
|
||||
.highlight .mi,
|
||||
.highlight .il,
|
||||
.highlight .mo,
|
||||
.highlight .mx {
|
||||
color: #90a959;
|
||||
}
|
||||
|
||||
.highlight .ss {
|
||||
color: #90a959;
|
||||
}
|
||||
}
|
||||
214
_sass/colors/syntax-light.scss
Normal file
214
_sass/colors/syntax-light.scss
Normal file
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* The syntax light mode code snippet colors.
|
||||
*/
|
||||
|
||||
@mixin light-syntax {
|
||||
/* --- custom light colors --- */
|
||||
--language-border-color: #ececec;
|
||||
--highlight-bg-color: #f6f8fa;
|
||||
--highlighter-rouge-color: #3f596f;
|
||||
--highlight-lineno-color: #9e9e9e;
|
||||
--inline-code-bg: #f6f6f7;
|
||||
--code-color: #3a3a3a;
|
||||
--code-header-text-color: #a3a3a3;
|
||||
--code-header-muted-color: #e5e5e5;
|
||||
--code-header-icon-color: #c9c8c8;
|
||||
--clipboard-checked-color: #43c743;
|
||||
|
||||
[class^='prompt-'] {
|
||||
--inline-code-bg: #fbfafa;
|
||||
}
|
||||
|
||||
/* --- Syntax highlight theme from `rougify style github` --- */
|
||||
|
||||
.highlight table td {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.highlight table pre {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.highlight,
|
||||
.highlight .w {
|
||||
color: #24292f;
|
||||
background-color: #f6f8fa;
|
||||
}
|
||||
|
||||
.highlight .k,
|
||||
.highlight .kd,
|
||||
.highlight .kn,
|
||||
.highlight .kp,
|
||||
.highlight .kr,
|
||||
.highlight .kt,
|
||||
.highlight .kv {
|
||||
color: #cf222e;
|
||||
}
|
||||
|
||||
.highlight .gr {
|
||||
color: #f6f8fa;
|
||||
}
|
||||
|
||||
.highlight .gd {
|
||||
color: #82071e;
|
||||
background-color: #ffebe9;
|
||||
}
|
||||
|
||||
.highlight .nb {
|
||||
color: #953800;
|
||||
}
|
||||
|
||||
.highlight .nc {
|
||||
color: #953800;
|
||||
}
|
||||
|
||||
.highlight .no {
|
||||
color: #953800;
|
||||
}
|
||||
|
||||
.highlight .nn {
|
||||
color: #953800;
|
||||
}
|
||||
|
||||
.highlight .sr {
|
||||
color: #116329;
|
||||
}
|
||||
|
||||
.highlight .na {
|
||||
color: #116329;
|
||||
}
|
||||
|
||||
.highlight .nt {
|
||||
color: #116329;
|
||||
}
|
||||
|
||||
.highlight .gi {
|
||||
color: #116329;
|
||||
background-color: #dafbe1;
|
||||
}
|
||||
|
||||
.highlight .kc {
|
||||
color: #0550ae;
|
||||
}
|
||||
|
||||
.highlight .l,
|
||||
.highlight .ld,
|
||||
.highlight .m,
|
||||
.highlight .mb,
|
||||
.highlight .mf,
|
||||
.highlight .mh,
|
||||
.highlight .mi,
|
||||
.highlight .il,
|
||||
.highlight .mo,
|
||||
.highlight .mx {
|
||||
color: #0550ae;
|
||||
}
|
||||
|
||||
.highlight .sb {
|
||||
color: #0550ae;
|
||||
}
|
||||
|
||||
.highlight .bp {
|
||||
color: #0550ae;
|
||||
}
|
||||
|
||||
.highlight .ne {
|
||||
color: #0550ae;
|
||||
}
|
||||
|
||||
.highlight .nl {
|
||||
color: #0550ae;
|
||||
}
|
||||
|
||||
.highlight .py {
|
||||
color: #0550ae;
|
||||
}
|
||||
|
||||
.highlight .nv,
|
||||
.highlight .vc,
|
||||
.highlight .vg,
|
||||
.highlight .vi,
|
||||
.highlight .vm {
|
||||
color: #0550ae;
|
||||
}
|
||||
|
||||
.highlight .o,
|
||||
.highlight .ow {
|
||||
color: #0550ae;
|
||||
}
|
||||
|
||||
.highlight .gh {
|
||||
color: #0550ae;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.highlight .gu {
|
||||
color: #0550ae;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.highlight .s,
|
||||
.highlight .sa,
|
||||
.highlight .sc,
|
||||
.highlight .dl,
|
||||
.highlight .sd,
|
||||
.highlight .s2,
|
||||
.highlight .se,
|
||||
.highlight .sh,
|
||||
.highlight .sx,
|
||||
.highlight .s1,
|
||||
.highlight .ss {
|
||||
color: #0a3069;
|
||||
}
|
||||
|
||||
.highlight .nd {
|
||||
color: #8250df;
|
||||
}
|
||||
|
||||
.highlight .nf,
|
||||
.highlight .fm {
|
||||
color: #8250df;
|
||||
}
|
||||
|
||||
.highlight .err {
|
||||
color: #f6f8fa;
|
||||
background-color: #82071e;
|
||||
}
|
||||
|
||||
.highlight .c,
|
||||
.highlight .ch,
|
||||
.highlight .cd,
|
||||
.highlight .cm,
|
||||
.highlight .cp,
|
||||
.highlight .cpf,
|
||||
.highlight .c1,
|
||||
.highlight .cs {
|
||||
color: #68717a;
|
||||
}
|
||||
|
||||
.highlight .gl {
|
||||
color: #68717a;
|
||||
}
|
||||
|
||||
.highlight .gt {
|
||||
color: #68717a;
|
||||
}
|
||||
|
||||
.highlight .ni {
|
||||
color: #24292f;
|
||||
}
|
||||
|
||||
.highlight .si {
|
||||
color: #24292f;
|
||||
}
|
||||
|
||||
.highlight .ge {
|
||||
color: #24292f;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.highlight .gs {
|
||||
color: #24292f;
|
||||
font-weight: bold;
|
||||
}
|
||||
} /* light-syntax */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user