Compare commits

...

247 Commits

Author SHA1 Message Date
Xin
d35a471e7b chore: prepare release 2025-08-14 22:25:49 +08:00
Xin
b9bcf5b470 chore: update fa and ja translations 2025-08-14 22:07:15 +08:00
Xin
24debf9b0c chore: update ja translation 2025-08-14 19:28:16 +08:00
Xin
f79b1d262c chore: update zh-cn translation 2025-08-14 19:07:25 +08:00
Xin
8773081fae Add notable new features to v0.10.md, including dropdown menu support, enhanced search experience, and blog list pagination. Updated FlexSearch upgrade details for clarity and improved migration guide by removing redundant breaking change notes. 2025-08-14 17:11:37 +08:00
Xin
273e1e3db9 Update v0.10.md to enhance upgrade instructions, clarify breaking changes, and improve overall readability. Adjusted formatting for consistency and added details on asset management and user experience improvements. 2025-08-14 16:28:36 +08:00
Xin
477b98e151 Enhance v0.10 release documentation with detailed upgrade instructions and migration guide. Added Tailwind theme variable customization section and clarified breaking changes. Improved clarity on CSS class prefix changes for better user experience. 2025-08-14 14:49:55 +08:00
Xin
d6dd2550b1 Update v0.10.md to refine upgrade instructions and enhance blog features. Added synchronized tab switching and pagination controls, while improving the search experience and table of contents navigation. 2025-08-14 09:32:58 +08:00
Xin
cc6d7e6e94 Update v0.10.md 2025-08-14 01:48:52 +08:00
Xin
7d9d07bfdf docs(blog): prepare for v0.10 release post 2025-08-14 01:43:35 +08:00
Xin
8025de9d9d docs(getting-started): fix instructions for using git submodule (#693)
* docs(getting-started): fix instructions for using git submodule

* docs(getting-started): update instructions for adding Hextra theme as a Git submodule
2025-08-14 00:14:53 +08:00
Xin
9f70e8a87b refactor(mermaid): enhance Mermaid JS loading logic for flexibility (#745)
* refactor(mermaid): enhance Mermaid JS loading logic for flexibility

- Updated the Mermaid JS loader to support configurable remote or local asset loading based on site parameters.
- Improved error handling for asset retrieval and added comments for clarity on behavior based on different configurations.
- Ensured that the default behavior falls back to a CDN if no base is provided, enhancing usability and maintainability.

* chore: clean up comments

* fix: comment typo
2025-08-14 00:00:03 +08:00
Xin
6823cc1fe8 refactor(css): add prefix to component classes for consistency (#744)
* refactor(navbar): add hextra prefix to navbar and hamburger menu classes

- Updated CSS class names from `nav-container` to `hextra-nav-container` and `hamburger-menu` to `hextra-hamburger-menu` for improved clarity and consistency across the project.
- Adjusted related JavaScript and documentation to reflect the new class names.

* refactor(search): update class names for search components

- Renamed CSS classes from `search-wrapper`, `search-input`, `active`, `no-result`, `prefix`, `excerpt`, and `match` to `hextra-search-wrapper`, `hextra-search-input`, `hextra-search-active`, `hextra-search-no-result`, `hextra-search-prefix`, `hextra-search-excerpt`, and `hextra-search-match` for improved clarity and consistency.
- Updated JavaScript selectors to match the new class names, ensuring functionality remains intact.
- Adjusted HTML structure to reflect the new class naming convention.

* refactor(search): update search component class names for consistency

- Renamed existing search-related CSS classes to include the `hextra` prefix for improved clarity and consistency.
- Added optional nested classes for enhanced customization of the search UI, including titles, active states, and result snippets.
- Removed outdated breadcrumb section as no specific class is available.

* refactor(sidebar): rename sidebar classes for consistency

- Updated CSS and JavaScript to replace `sidebar-container` with `hextra-sidebar-container` and `sidebar-active-item` with `hextra-sidebar-active-item` for improved clarity and consistency across the project.
- Adjusted related documentation to reflect the new class names.

* refactor(language & theme): update class names for consistency

- Renamed language switcher and theme toggle classes to include the `hextra` prefix for improved clarity and consistency across the project.
- Updated related JavaScript selectors and documentation to reflect the new class names.

* refactor(css & html): rename classes for consistency and clarity

- Updated various CSS class names to include the `hextra` prefix, enhancing consistency across the project. This includes renaming classes such as `content` to `hextra-content`, `filename` to `hextra-code-filename`, and `steps` to `hextra-steps`.
- Adjusted related HTML and JavaScript to reflect the new class names, ensuring functionality and styling remain intact.
- Updated documentation to include the new class names for better clarity.

* refactor(language): update class names for language options

- Renamed the `language-options` class to `hextra-language-options` for consistency with the existing `hextra` prefix convention.
- Updated the corresponding HTML to reflect the new class name, ensuring clarity and uniformity across the project.

* refactor(css & html): rename classes for consistency and clarity

- Renamed CSS classes to include the `hextra` prefix, such as changing `subheading-anchor` to `hextra-subheading-anchor` and `footnotes` to `hextra-footnotes`, enhancing consistency across the project.
- Updated related HTML and documentation to reflect the new class names, ensuring clarity and uniformity.

* feat(typography): add styling for horizontal lines

- Introduced new styles for horizontal lines to enhance visual separation in content. The styles apply margin and border color adjustments, ensuring consistency with the overall design.

* feat(blog): add draft release announcement for Hextra v0.10.0

- Created a new markdown file for the draft release announcement of Hextra v0.10.0, including upgrade instructions and author details.
- The announcement is currently marked as a draft and may be updated before the official release.

* refactor(css & html): rename `hextra-content` class to `content` for consistency

- Updated the `hextra-content` class to simply `content` across various HTML files and CSS, enhancing clarity and consistency in the codebase.
- Adjusted the `package.json` script for the development server to include the `-F` flag for better functionality.

* refactor(typography & markdown): enhance table styling and markdown syntax

- Updated CSS for tables to improve styling, including adjustments to margins, borders, and text properties for better readability.
- Revised markdown documentation to standardize table formatting and improve clarity, including consistent syntax for headers and lists.
- Enhanced examples in the documentation to reflect the updated styling and ensure accurate representation of output.

* fix(blog): update text color for improved accessibility

- Modified the text color in the blog single layout to enhance readability in dark mode by adding a dark text color class.
- Ensured consistency in styling for better user experience across different themes.

* docs(blog): update draft release announcement for Hextra v0.10.0

- Revised the "What's New" section to include a TODO placeholder for future updates.
- Added a comprehensive migration guide detailing the CSS class prefix changes to enhance consistency and avoid conflicts.
- Updated the announcement to reflect the new class naming conventions for various components.

* chore: rebuild css
2025-08-13 22:55:38 +08:00
Xin
953042a0c0 docs(customization): add docs for layout css vars 2025-08-13 16:01:09 +08:00
Xin
b4d7d982f9 docs(config): add documentation for navbar dropdown menu 2025-08-13 15:41:37 +08:00
Xin
9a20f07d4e feat(math): support local katex assets and improve docs (#742)
* refactor(math): update LaTeX guide and enhance KaTeX integration

- Revised the LaTeX documentation for clarity and improved structure, changing section titles and descriptions for better understanding.
- Added support for chemistry expressions using the mhchem extension.
- Introduced a new KaTeX CSS loader partial to streamline the integration of KaTeX, allowing for configurable remote or local asset loading.
- Updated the head partial to utilize the new KaTeX loader, enhancing the flexibility of math rendering options.

* refactor(mathjax): simplify MathJax script URL configuration

- Removed the dynamic version assignment for MathJax and set a fixed version in the script URL for consistency and clarity.

* docs(latex): enhance LaTeX guide and clarify chemistry expressions

- Updated section titles for better clarity, changing "Supported Functions" to "Chemistry Expressions."
- Improved description of the mhchem extension for rendering chemistry equations.
- Removed redundant instructions regarding the passthrough extension in Hugo.
- Corrected minor typographical errors in references to MathJax.
2025-08-13 15:14:46 +08:00
Ludovic Fernandez
b6864a0c19 fix(search): unescape title (#741) 2025-08-12 20:02:35 +08:00
Ludovic Fernandez
532cbcce10 feat: search in all headings (#740) 2025-08-12 08:52:21 +08:00
Xin
30866e328c chore: enhance tags appearance in toc and minor updates (#739)
* chore: remove standard development mode command from CLAUDE.md

* docs(toc): add TOC scroll functionality documentation

- Added detailed comments to toc-scroll.js explaining the purpose and functionality of the TOC scroll spy feature.
- Clarified the requirements for proper operation, including the need for a .hextra-toc element and matching heading IDs.

* refactor(fragments): enhance fragment processing and documentation

- Improved the fragments.html partial to better handle page content splitting into searchable fragments based on headings.
- Added comprehensive documentation within the file, detailing parameters, return values, and examples for clarity.
- Updated content handling to ensure whitespace is trimmed

* refactor(tags): enhance tag rendering and styling in toc

- Updated the tags.html partial to utilize a context variable for improved accessibility.
- Enhanced the styling of tag links for better visual consistency across different themes.
- Modified toc.html and list.html to pass the context to the tags partial, ensuring consistent rendering.

* chore: run `task css`
2025-08-11 17:36:37 +08:00
Xin
0bb59d6f49 feat(toc): add Table of Contents scroll highlighting (#738)
* feat(toc): add Table of Contents scroll highlighting

- Introduced a new toc.css file for styling the Table of Contents with active link highlighting.
- Implemented toc-scroll.js to manage scroll behavior and link activation based on viewport visibility.
- Updated core.html to include the new JavaScript file and ensure proper loading of the Table of Contents functionality.

* chore: lower root heading font weight for TOC

* chore: run `task css`

* chore: update dependencies in package.json and package-lock.json to version 4.1.11 for @tailwindcss/postcss and tailwindcss, and update @jridgewell packages to latest versions
2025-08-11 16:04:53 +08:00
Ludovic Fernandez
025dd1f211 fix: search results linking to wrong spot on page (#737) 2025-08-11 14:23:30 +08:00
Xin
af78002014 feat: support llms.txt output (#736)
* feat(llms): add llms txt output format

- Introduced a new output format 'llms' in the configuration.
- Updated the example site to utilize the new 'llms' format for the home output.
- Added a new layout file 'llms.txt' for rendering content in the LLMS format.

* docs: add llms.txt support documentation

- Introduced a new section in the configuration guide detailing how to enable the llms.txt output format for improved accessibility to large language models.
- Provided example configuration for adding the 'llms' output format in the site's hugo.yaml.
- Explained the content structure of the generated llms.txt file, including site title, section listings, page summaries, and direct links.

* Update configuration.md
2025-08-10 23:15:21 +08:00
Xin
096f0d9c22 fix(favicon): dynamic favicon switching based on color scheme in js (#735)
* fix(favicon): dynamic favicon switching based on color scheme in js

* refactor(favicon): simplify favicon logic and ensure dynamic switching based on color scheme

* docs(favicon): enhance favicon setup instructions with dark mode support and adaptive SVG guidance
2025-08-10 23:04:19 +08:00
Xin
7ac1d59e9f chore: add CLAUDE.md 2025-08-09 14:58:54 +08:00
lzmyhzy
ea17ae6cbd fix: giscus theme will be switched to dark when no 'color-theme' field (#723) 2025-08-06 09:01:00 +09:00
Xin
1081ab8d7f fix: tab not switching on non-synced mode (#732)
* fix: tab not switching on non-synced mode

* fix(tabs): improve tab synchronization logic and clean up data attributes

* refactor(tabs): streamline tab synchronization logic
2025-08-05 21:37:42 +09:00
Xin
46290e10e7 feat(pagination): add blog pagination component (#725)
* feat(pagination): add blog pagination component

- Introduced a new blog pagination component for improved navigation on list pages.
- Updated the blog list layout to utilize pagination, allowing for better content organization.
- Added a new parameter for pagination size in the configuration file.

* chore: increase pager size for blog
2025-07-24 22:26:17 +01:00
Xin
7b27743159 feat(tabs): implement synchronized tabs switching (#700)
* Sync tabs across groups

* feat(tabs): add optional synchronization

* Move tabs sync setting under page params

* fix: spacing between title and site title (#704)

* docs: document configure opengraph image (#706)

* [Docs] document using og:image

* Make example title page match others

* clarify wording

* chore: update tailwind css to latest version 4.1.8 (#703)

* fix: wrong SRI hash for katex.css (#702)

* Correct URL given in 'dev.toml'

* stylesheet 'katex.css': fix SRI hash

* fix(build): run npm update to fix postcss complaint

* feat(tags): improve usability of tags (#698)

* feat(tags): improve usability of tags

* Tags can be shown also at docs
* Documented tag-related config flags
* Added example tags to the site
* Made rendered tags active

* Move tags listing to ToC

* Hide tags section on no tags

* feat(math): add optional MathJax support (#707)

* feat: add MathJax option

* docs: move math engine note

* refactor: update LaTeX documentation and improve MathJax integration

- Adjusted LaTeX documentation for clarity and formatting.
- Enhanced MathJax configuration in the templates to support both KaTeX and MathJax rendering.
- Removed deprecated comments and streamlined the script loading process for MathJax.
- Updated the passthrough extension settings in the Hugo configuration for better compatibility with LaTeX math expressions.

* docs: simplify LaTeX documentation and clarify configuration steps

- Updated LaTeX documentation to reflect that KaTeX is enabled by default, removing the need for manual activation.
- Added examples for using LaTeX math expressions and clarified the configuration for the passthrough extension in Hugo.
- Enhanced MathJax section to emphasize its use as an alternative rendering engine.

* fix(tabs): add null check for panels container and update example items

* fix(tabs): improve tab group key handling and add validation for items parameter

* refactor(tabs): comment out sync option in configuration and adjust tab formatting in documentation

---------

Co-authored-by: hobobandy <30026704+hobobandy@users.noreply.github.com>
Co-authored-by: Matt Dodson <47385188+MattDodsonEnglish@users.noreply.github.com>
Co-authored-by: Andreas Deininger <adeininger@urbanonline.de>
Co-authored-by: yuri <1969yuri1969@gmail.com>
2025-07-21 21:16:44 +01:00
Floren Munteanu
c9795867c4 refactor: extract navbar title as individual partial component (#718)
* feat: navbar title

* fix: navbar title

---------

Co-authored-by: Floren Munteanu <19806136+fmunteanu@users.noreply.github.com>
2025-07-21 20:43:21 +01:00
Jaechan Lee
7610118c04 fix(i18n): Update translation in ko.yaml (#720) 2025-07-19 16:01:39 +01:00
yuri
05fd0129c2 fix(i18n): add missing tags translations (#708) 2025-06-15 10:29:43 +01:00
Xin
7031718449 feat(math): add optional MathJax support (#707)
* feat: add MathJax option

* docs: move math engine note

* refactor: update LaTeX documentation and improve MathJax integration

- Adjusted LaTeX documentation for clarity and formatting.
- Enhanced MathJax configuration in the templates to support both KaTeX and MathJax rendering.
- Removed deprecated comments and streamlined the script loading process for MathJax.
- Updated the passthrough extension settings in the Hugo configuration for better compatibility with LaTeX math expressions.

* docs: simplify LaTeX documentation and clarify configuration steps

- Updated LaTeX documentation to reflect that KaTeX is enabled by default, removing the need for manual activation.
- Added examples for using LaTeX math expressions and clarified the configuration for the passthrough extension in Hugo.
- Enhanced MathJax section to emphasize its use as an alternative rendering engine.
2025-06-14 14:36:10 +01:00
yuri
e22b8d5c0e feat(tags): improve usability of tags (#698)
* feat(tags): improve usability of tags

* Tags can be shown also at docs
* Documented tag-related config flags
* Added example tags to the site
* Made rendered tags active

* Move tags listing to ToC

* Hide tags section on no tags
2025-06-13 22:09:05 +01:00
Xin
32a55bb8ee fix(build): run npm update to fix postcss complaint 2025-06-13 21:57:08 +01:00
Andreas Deininger
b43870a538 fix: wrong SRI hash for katex.css (#702)
* Correct URL given in 'dev.toml'

* stylesheet 'katex.css': fix SRI hash
2025-06-10 23:48:03 +01:00
Andreas Deininger
9c2a9f600b chore: update tailwind css to latest version 4.1.8 (#703) 2025-06-10 23:46:53 +01:00
Matt Dodson
7385fe9e2a docs: document configure opengraph image (#706)
* [Docs] document using og:image

* Make example title page match others

* clarify wording
2025-06-10 23:45:19 +01:00
hobobandy
b1d40c4a2d fix: spacing between title and site title (#704) 2025-06-07 14:31:25 +01:00
Xin
40b1c5f2f1 docs: update hugo version in deploy guide (#699) 2025-06-04 00:38:38 +01:00
Xin
3a13d44d3c chore: update Hugo version to 0.147.7 and improve nav-menu script 2025-06-01 17:37:37 +01:00
Xin
c24d55ee40 feat: child menu support in navbar (#695)
* feat: implement child menu support in main navbar

- Added a new JavaScript file for handling dropdown functionality in the navbar.
- Implemented event listeners for toggling dropdowns, closing them on outside clicks, and dismissing with the Escape key.
- Updated navbar HTML to support dropdown items with children, enhancing the navigation experience.
- Adjusted core script imports to include the new dropdown functionality.

* chore: update menu identifiers and add missing translations for development versions

* chore: update hugo stats

* chore: update script name

* chore: update menu item names to include arrows for external links
2025-06-01 17:33:45 +01:00
yuri
a44de285b2 chore: adapt theme to new template system (#696)
* Adapted theme's layout to [Hugo v0.146.0](https://gohugo.io/templates/new-templatesystem-overview/)
* Bumped minimal Hugo version to v0.146.0
2025-06-01 00:25:39 +01:00
yuri
c8a231b650 fix(build): update NPM to resolve postcss issue (#694)
`npm update` fixed broken development which logged:

>  postcss: Error: Loading PostCSS Plugin failed: Cannot find module '../lightningcss.linux-x64-gnu.node
2025-05-31 22:38:43 +01:00
Xin
5a6fa55d0a fix: missing variables and custom styles css imports for theme dev 2025-05-31 19:58:09 +01:00
Andreas Deininger
c497ef700e docs(chore): switch to new template system (Hugo v0.146.0) (#681) 2025-05-31 16:48:23 +01:00
Xin
41140af6fa fix: CSS loading logic for production and theme dev environments (#691)
* fix: CSS loading logic for production and theme dev environments

- Updated the CSS loading logic to differentiate between production and theme environments.

* fix: streamline CSS loading logic for production and development environments

- Refactored the CSS loading logic to ensure proper handling of stylesheets in both production and development modes.
- Consolidated the CSS concatenation and minification process for production, while simplifying the development loading process.

* fix: simplify development CSS loading in head partial

- Updated the CSS loading logic in head.html to streamline the process for development environments by renaming the variable for clarity and ensuring proper handling of stylesheets.
2025-05-31 00:56:32 +01:00
PrintN
33129ca59f docs(showcase): Add Beginner Privacy (#688)
* docs(showcase): Add Beginner Privacy

* docs(showcase): Add Beginner Privacy

* docs(showcase): Add Beginner Privacy
2025-05-31 00:18:11 +01:00
Keith Stockdale
72c383ef5c feat: allow authors to set the value of reversePagination in page front matter (#674)
* Allow authors to set the reverse pagination setting of a page using front matter

* Adding some documentation of the reversePagination front matter custom parameter along with an example of how to use it and why you might want to use it
2025-05-23 01:23:25 +01:00
miniwater
51b5de23c7 fix: alternative text of images should not be repeated as text (#669)
* Add centering for custom footers

* Update layouts/partials/footer.html

* Fix alt duplication

* Update navbar.html

---------

Co-authored-by: Xin <fuxin1997@gmail.com>
Co-authored-by: Xin <xin@imfing.com>
2025-05-23 01:09:38 +01:00
Xin
befce4cd9a refactor: improve width handling and introduce CSS variables (#678)
* refactor: update page width handling and CSS structure

- Changed the default page width from 1280px to 80rem in hugo.yaml.
- Replaced dynamic page width partials with a new CSS class 'hextra-max-page-width' across multiple layout files for consistency.
- Introduced a new head-config-css.html partial for managing CSS styles related to page width.
- Removed the outdated page-width utility partial to streamline the codebase.

* feat: introduce CSS variables for layout widths and update footer/navbar styles

- Added a new configs.css file to define CSS variables for page, navbar, and footer widths.
- Updated footer and navbar partials to utilize the new CSS classes for consistent width management.
- Refactored head-config-css.html to include the new navbar width variable.
- Enhanced the overall styling structure for better maintainability and responsiveness.

* Refactor: Rename configs.css to variables.css and update references

Remove head-config-css.html and update references to use variables.css instead of configs.css

* Update assets/css/variables.css

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update layouts/partials/head.html

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-05-23 00:57:12 +01:00
Matt Dodson
128235e7e2 feat(seo): add page param to block Google indexing
Add a `noindex` param to page front matter to block Google indexing for specific pages or directories. This is useful for avoiding duplicate content in search results or preventing indexing of pages that shouldn't appear in search engines.

- Adjust `head.html` for optional `noindex` param (default: false)
- Document usage in `configuration.md` and clarify Flexsearch section
2025-05-17 22:35:26 +01:00
miniwater
f194bc64e4 fix: centering custom footers (#649)
* Add centering for custom footers

* Update layouts/partials/footer.html

---------

Co-authored-by: Xin <fuxin1997@gmail.com>
2025-04-13 10:35:39 +01:00
Zabriskije
1cc02a6931 fix: phantom scroll when params.footer.enable is set to false (#658)
* Phantom scroll fix

* fix: adjust menu height in CSS and update sidebar max height reference

* chore: regenerate css

---------

Co-authored-by: Xin <xin@imfing.com>
2025-04-09 23:11:19 +01:00
Justin Chen
1eb4b9ea23 fix: link render hook produces dangling links when base URL has additional segments (#660)
* fix: link render hook produces dangling links when base URL has additional segments

* fix: incorrect fragment character in image render hook
2025-04-09 22:47:02 +01:00
Justin Chen
d08b077acd feat: make image render hook aware of assets directory (#657) 2025-04-04 00:14:05 +01:00
Justin Chen
1f88cff7d4 fix: KaTeX fonts are not fetched from CDN (#656) 2025-04-04 00:07:12 +01:00
Xin
83fda0109f fix: enhanced encoder for CJK mixed content (#653) 2025-03-31 08:43:41 +01:00
Xin
7fdb6a3a07 chore: upgrade flexsearch to 0.8 (#652)
* chore: upgrade flexsearch to 0.8.x

- use cdn to download flexsearch js bundle

* chore: remove flexsearch.bundle.min.js
2025-03-30 21:52:41 +01:00
Xin
8021437f77 chore: use CDN to download mermaid js (#651)
* chore: download js assets during build time

* chore: remove CDN asset download task and update Mermaid script fingerprinting
2025-03-30 21:20:50 +01:00
Andreas Deininger
b700825943 chore: server side rendering of math equations (#589) 2025-03-30 18:05:35 +01:00
Xin
c74d44492e chore: migrate to Tailwind CSS v4.0 (#632)
* chore: migrate PostCSS configuration to v4

* chore: update dependencies in package.json and package-lock.json

- Bump versions for autoprefixer, postcss, postcss-cli, prettier, and tailwindcss.
- Remove unused dependencies to streamline the project.

* chore: add @tailwindcss/postcss and update package-lock.json

* fix: update import paths in CSS files for consistency

* fix: change prefix from `hx-` to `hx:`

* chore: migrate primary color theme variables to CSS

* fix: remove unnecessary text decoration property from anchor styles in typography CSS

* fix: update CSS styles for improved consistency and clarity across components

* chore: clean up package.json and package-lock.json, remove unused dependencies, and update CSS imports for better organization

* fix: bulk replace prefix `hx-` with `hx:`

* fix: update tailwind css prefix

* fix: styling consistent issues

- steps counter fix in v4
- removed tailwind.css
- update hr border colors
- fix button cursor in v4
- fix border colors in various places

* fix: update class prefixes for consistency in menu and sidebar components

* fix: refine CSS classes and transitions for navbar and sidebar components

- Updated hamburger menu styles for improved animation and structure.
- Adjusted sidebar transition duration for smoother effects.
- Standardized class prefixes for consistency across components.

* fix: update border color in hero badge component for improved styling consistency

* fix: update tab button cursor style for improved user interaction

* chore: recompile css

* fix: dark mode color not applied for before / after elements

* fix: docs navigation

* chore: recompile CSS

* chore: update Tailwind CSS and PostCSS dependencies to version 4.0.17, recompile CSS, and add safelist

* fix: typo in class name and add back decoration-from-font for typography a tags

* fix: update class syntax for Tailwind CSS compatibility in mermaid code block
2025-03-29 12:51:42 +00:00
Ajay Kidave
32f7f6d33f docs(showcase): update Clace image url (#646) 2025-03-29 12:43:01 +00:00
Xin
38c8ee1168 fix: mermaid script was skipped on home page (#637) 2025-03-27 22:40:24 +00:00
Xin
17de708c9f chore(build): build main docs site from v0.9.6 2025-03-27 22:23:38 +00:00
Xin
a338c363ed chore(ci): add support for building docs for multiple versions (#633)
* chore(ci): add support for building docs for multiple versions

* chore(ci): enable fetching tags in GitHub Actions workflow

* chore(build): add v0.8.6 version to build script
2025-03-26 21:55:31 +00:00
Ajay Kidave
c3ce3b67e6 docs(showcase): Added Clace to showcase (#623) 2025-03-23 10:12:13 +00:00
Xin
9d57dbd9cd chore: update hugo to 0.145.0 in devcontainer.json
[skip ci]
2025-03-11 21:43:41 +00:00
Xin
a2718d8aa3 fix: use InnerDeindent for filetree shortcode rendering (#613) 2025-03-11 21:42:16 +00:00
Xin
2b83a3762f Merge pull request #607 from maxbischoff/fix-codeblock-copy-button-in-details
fix: copy-button not being rendered in details blocks
2025-03-10 23:05:43 +00:00
Maximilian Bischoff
aad859d72e fix copy-button not being rendered in details blocks 2025-03-10 20:12:30 +01:00
Pat David
6a2f11d780 fix: sidebar more menu item link with multilingual (#594)
* sidebar: fix more menu item with multilingual

Fixes #593

Correctly parses multilingual URL in sidebar, particularly if
lang code follows a nested sub directory.

For instance, GH pages hosting where the baseurl might be of the
format `https://<USERNAME>.github.io/<REPO>/`.

* Update sidebar.html

---------

Co-authored-by: Xin <xin@imfing.com>
2025-03-01 08:39:36 +00:00
Xin
662d9202dc chore: bump minimum hugo version 2025-02-26 23:33:11 +00:00
Xin
9f9ddd69ab fix: sanitize heading title to prevent html tags displayed on mobile (#591) 2025-02-26 23:26:21 +00:00
Xin
96b2f6145d feat: add optional pagination control for blog articles (#590) 2025-02-26 23:13:43 +00:00
Xin
c2286c9dd1 refactor: modularize scripts partial into separate components (#587)
* refactor: modularize scripts partial into separate components

* fix: conditionally load Mermaid and KaTeX scripts
2025-02-26 08:39:26 +00:00
Xin
49b1cd11ee feat: hide navbar on mobile when heading links clicked (#584) 2025-02-25 18:48:25 +00:00
Xin
b2e6c30c7f chore: remove unused hx-mx-2 margin utility class 2025-02-25 08:12:44 +00:00
Nick Gracilla
8eb348323d docs: fix typo in documentation on customization.md (#582) 2025-02-23 10:06:25 +00:00
Connor Lanigan
ab56c66ae5 fix: misaligned page title when logo is not displayed (#578) 2025-02-17 17:15:35 +00:00
yuri
ddc017b8dc docs: mention Hugo Figure shortcode (#572) 2025-02-13 11:22:41 +08:00
Khosrow Moossavi
ce837dca42 docs(showcase): add Regolith Desktop (#568) 2025-02-13 11:21:59 +08:00
yuri
c60d1f5de7 docs: describe page last modification date (#562) 2025-01-23 20:58:03 +00:00
Mir Sobhan
bbe3c46320 chore: add telegram icon (#558)
* Update icons.yaml | add telegram icon

* chore: update telegram icon

---------

Co-authored-by: Xin <xin@imfing.com>
2025-01-21 21:57:43 +00:00
Gaëtan Steininger
cb3373d500 fix: missing doctype error on 404 page with htmltest scan (#554)
* Fix missing doctype error on 404 page with htmltest scan

* format 404.html

---------

Co-authored-by: Xin <xin@imfing.com>
2025-01-19 19:35:24 +00:00
Xin
56f28e6f14 chore: 2024 -> 2025 2025-01-19 11:50:14 +00:00
Xin
14036ffea6 feat: enhance FlexSearch encoding for CJK support (#553)
- Added support for CJK (Chinese, Japanese, Korean) languages in FlexSearch encoding.
- Introduced `isCJK` function to detect language and select appropriate encoding method.
- Implemented `encodeCJK` and `encodeDefault` functions for different tokenization strategies.
2025-01-18 18:54:54 +00:00
Jan Zerfowski
a1232ecf9f fix: skip image process on svgs and remote images (#551) 2025-01-18 17:05:13 +00:00
Nikolay Dubina
a933f464f5 docs: fix wrong param footer (#543)
it has changed 709a407b2e/layouts/partials/footer.html (L40C40-L40C56)
2025-01-07 10:51:00 +00:00
Xin
709a407b2e feat: add tags support (#542)
* feat: basic tags support

* feat: add term page

* chore: update css
2025-01-05 20:33:56 +00:00
Xin
876eb3abff chore(docs): remove redundant backticks 2025-01-05 19:03:13 +00:00
Jan Zerfowski
a27f6eef5e refactor: use generic .Process for card processing and allow bundled images (#538)
* Change processing method to more generic hugo .Process and allow resources from local .Page.Resources as well as global resources

* Add comments

* Fix double curly brackets error

Co-authored-by: Xin <fuxin1997@gmail.com>

* Maintain backward compatibility by using defaulting $process to $methd $options

https://github.com/imfing/hextra/pull/538#discussion_r1903250264

* Use printf instead of delimit

Co-authored-by: Xin <fuxin1997@gmail.com>

---------

Co-authored-by: Xin <fuxin1997@gmail.com>
2025-01-05 19:00:00 +00:00
stoic-hugo
323f4c4b44 i18n: update sw.yaml (#541) 2025-01-05 18:59:20 +00:00
Xin
b8f617f1b0 docs(i18n): add ja translation
- translated via llm
2024-12-31 01:01:56 +00:00
Xin
9632c4d05a docs: update zh-cn translations 2024-12-31 00:34:20 +00:00
Xin
594b1f190c docs: add instruction for enable and configure passthrough for latex (#530) 2024-12-30 23:13:23 +00:00
Xin
12815aaddc docs: documentation updates for alerts and syntax highlighting 2024-12-28 16:23:58 +00:00
Xin
e532637cbc fix: correct tabs button color on hover in dark mode (#526)
* fix: tabs toggle button color in dark mode

* chore: update css
2024-12-28 15:51:35 +00:00
Xin
79bb4504a0 feat: add support for icon in badge shortcode (#525)
* feat: add icon support to badge shortcodes

- Introduced an optional icon parameter to both badge.html files.
- Updated the badge rendering to include the icon alongside the content.
- Enhanced the layout for better alignment of icon and text.

* feat: add new feature shortcode

* docs: update badge doc
2024-12-28 13:50:22 +00:00
strowk
26a298da5d feat: support link in code block title (#523)
* feat: support link in code block title

* refactor: simplify code block filename link implementation

* docs: update syntax-highlighting.md

* chore: rename `filename_uri_base` to `base_url`

[skip ci]

* refactor: use `base_url` int code block implementation

---------

Co-authored-by: Xin <xin@imfing.com>
2024-12-28 12:41:23 +00:00
Xin
cf61e606c1 docs: update customization instructions for footer section 2024-12-26 23:50:18 +00:00
Wonchae Yang
0716533699 feat: add giscus theme customization (#522)
Co-authored-by: Xin <xin@imfing.com>
2024-12-26 12:29:21 +00:00
Attila Greguss
9efcda2fdd feat: support custom footer section (#518)
* Add support for custom footer

* amend how the custom footer section is displayed

* Add missing class

* add missing class

* Remove context variable and flag in hugo.yaml

* update hugo_stats

* Only show footer section for copyright and PoweredBy if they are enabled

* Add missing compiled css

* Added necessary variables for correct styling of the custom footer in some cases

* make padding consistent for copyright section and custom footer

* chore: update css

* chore: clean up css

* docs: update customization instructions

* fix: footer padding

---------

Co-authored-by: Xin <xin@imfing.com>
2024-12-25 21:25:47 +00:00
Attila Greguss
655148f329 docs: add advanced theme customization instruction (#519)
Some checks failed
Deploy Hugo site to Pages / build (push) Has been cancelled
Deploy Hugo site to Pages / deploy (push) Has been cancelled
* Add docs on how to customize theme

* fix heading level

* extend description

* Add missing classes

* Update exampleSite/content/docs/advanced/customization.md

---------

Co-authored-by: Xin <fuxin1997@gmail.com>
2024-12-18 22:48:42 +00:00
Xin
b6d14afca3 docs(showcase): update link for lutheran-confessions
fixes #520
2024-12-18 22:35:52 +00:00
Attila Greguss
bc778ee243 fix: only display footer switches section if it actually has content (#517)
Some checks failed
Deploy Hugo site to Pages / build (push) Has been cancelled
Deploy Hugo site to Pages / deploy (push) Has been cancelled
2024-12-16 22:21:15 +00:00
Xin
f377609eba docs: update HUGO_VERSION to 0.138.0 in deployment documentation
Some checks are pending
Deploy Hugo site to Pages / build (push) Waiting to run
Deploy Hugo site to Pages / deploy (push) Blocked by required conditions
2024-12-15 20:32:54 +00:00
Xin
a9b992436e chore: update HUGO_VERSION to 0.138.0 in GitHub Actions workflow
* add FUNDING.yml
2024-12-15 20:26:11 +00:00
dependabot[bot]
7f5a7f2f5a chore(deps-dev): bump cross-spawn from 7.0.3 to 7.0.6 (#515) 2024-12-15 16:33:44 +00:00
dependabot[bot]
30fddec3fa chore(deps): bump nanoid from 3.3.7 to 3.3.8 (#514)
Some checks are pending
Deploy Hugo site to Pages / build (push) Waiting to run
Deploy Hugo site to Pages / deploy (push) Blocked by required conditions
2024-12-15 14:20:52 +00:00
Xin
68dd327312 feat: support github style alerts (#513)
Some checks are pending
Deploy Hugo site to Pages / build (push) Waiting to run
Deploy Hugo site to Pages / deploy (push) Blocked by required conditions
* feat: basic github style alerts support

* feat: implement github style alert

* chore: re-generate css

* chore: add missing prettier config

* docs: add alerts instructions to markdown

* chore: revert "docs: add alerts instructions to markdown"

This reverts commit 3a70540e0b.

* chore: redo "docs: add alerts instructions to markdown""

This reverts commit 8399373747.

* chore(build): bump hugo version
2024-12-14 23:44:10 +00:00
Floren Munteanu
0c90c1aa50 feat: add hextra hero-section shortcode (#390)
Some checks failed
Deploy Hugo site to Pages / build (push) Has been cancelled
Deploy Hugo site to Pages / deploy (push) Has been cancelled
* Implement hextra hero-section

* Implement header size

* Update layouts/shortcodes/hextra/hero-section.html

* Update layouts/shortcodes/hextra/hero-section.html

* Update layouts/shortcodes/hextra/hero-section.html

* Update layouts/shortcodes/hextra/hero-section.html

---------

Co-authored-by: Xin <fuxin1997@gmail.com>
2024-12-10 23:58:36 +00:00
Xin
fe2271b60b docs(showcase): add "Model Context Protocol Specification"
Some checks failed
Deploy Hugo site to Pages / build (push) Has been cancelled
Deploy Hugo site to Pages / deploy (push) Has been cancelled
2024-12-08 12:38:44 +00:00
Torbjørn Pedersen
bd34a5bad3 fix: rerender mermaid diagrams on theme change (#509)
Make mermaid render diagrams on manual toggle between themes, after initial page load
2024-12-08 12:29:28 +00:00
Nishant Srivastava
0dcf7e7a40 chore(icons): add bluesky icon (#505)
Some checks failed
Deploy Hugo site to Pages / build (push) Has been cancelled
Deploy Hugo site to Pages / deploy (push) Has been cancelled
* Update icons.yaml to add bsky icon

Added BlueSky icon to socials

* update the fill color to current color

* Update data/icons.yaml

---------

Co-authored-by: Xin <fuxin1997@gmail.com>
2024-12-04 07:34:02 +00:00
Jonas Pleyer
86a1f3fd96 docs(showcase): add cellular_raza (#498)
Some checks failed
Deploy Hugo site to Pages / build (push) Has been cancelled
Deploy Hugo site to Pages / deploy (push) Has been cancelled
* add cellular_raza to showcase exampleSite

* use link from github PR to store image

Co-authored-by: Xin <fuxin1997@gmail.com>

---------

Co-authored-by: Xin <fuxin1997@gmail.com>
2024-11-14 11:18:59 +00:00
Xin
4c4f43779c build(ci): build doc site from latest release instead of main
Some checks failed
Deploy Hugo site to Pages / build (push) Has been cancelled
Deploy Hugo site to Pages / deploy (push) Has been cancelled
- bump hugo version in workflow
- bump github actions deps versions
- minor update to head.html to remove empty spaces
2024-11-03 16:53:18 +00:00
Xin
ff85e6951d chore: update bug report template 2024-11-03 16:08:29 +00:00
Xin
ec37876f4d docs(showcase): add Sidekick 2024-11-03 15:35:32 +00:00
Todd Zhou
f65aca556d fix: typo in ref="noreferrer" (#489)
Some checks failed
Deploy Hugo site to Pages / build (push) Has been cancelled
Deploy Hugo site to Pages / deploy (push) Has been cancelled
2024-11-01 10:12:14 +00:00
Xin
7b7eb0f1f3 fix: add back empty content filter in search-data.json (#482)
Some checks failed
Deploy Hugo site to Pages / build (push) Has been cancelled
Deploy Hugo site to Pages / deploy (push) Has been cancelled
2024-10-21 22:22:56 +01:00
PurpleBabar
80fae9f86d feat: update mermaid to 11.3.0 (#477)
Some checks failed
Deploy Hugo site to Pages / build (push) Has been cancelled
Deploy Hugo site to Pages / deploy (push) Has been cancelled
* feat: update hextra version

* feat: adding mermaid lib

---------

Co-authored-by: LALUNG Alexandre <LB6572@engie.com>
2024-10-18 09:55:14 +01:00
Azat Khasanov
1358c5b945 i18n: add russian language + fix GitHub capitalization (#476)
Some checks failed
Deploy Hugo site to Pages / build (push) Has been cancelled
Deploy Hugo site to Pages / deploy (push) Has been cancelled
2024-10-16 19:17:54 +01:00
Evan Huang
b4d292010b docs: updated translation in the Chinese README
Some checks are pending
Deploy Hugo site to Pages / build (push) Waiting to run
Deploy Hugo site to Pages / deploy (push) Blocked by required conditions
2024-10-15 18:12:56 +01:00
Attila Greguss
37089d237a feat: add customizable primary lightness support (#470)
Some checks are pending
Deploy Hugo site to Pages / build (push) Waiting to run
Deploy Hugo site to Pages / deploy (push) Blocked by required conditions
* Add support for setting lightness for primary color

* Add comment

* change multiplier to just adding percentages

* amend comment

* add to docs

* Fix lightness overflow
2024-10-14 23:11:37 +01:00
Xin
2565f372d1 feat: make cards as partial (#474) 2024-10-14 23:03:22 +01:00
Attila Greguss
a97a1791cc feat: show breadcrumbs in search results (#473)
* Show crumbs in search results

* remove unnecessary console.log

* amend comment

* amend comment again

* Implement requested changes
2024-10-14 22:42:55 +01:00
yuri
97ea67198b feat: scroll selected sidebar entry into view (#471)
Some checks failed
Deploy Hugo site to Pages / build (push) Has been cancelled
Deploy Hugo site to Pages / deploy (push) Has been cancelled
Long sidebars did not scroll to show the selected entry. This made
working with such long sidebars quite confusing.
2024-10-12 19:55:39 +01:00
Welding Torch
94624bcac6 docs(showcase): add Install C (#463)
Some checks failed
Deploy Hugo site to Pages / build (push) Has been cancelled
Deploy Hugo site to Pages / deploy (push) Has been cancelled
* Add Install C to Showcase

* fix: malformed image link

---------

Co-authored-by: Xin <xin@imfing.com>
2024-09-29 10:27:03 +01:00
Andreas Deininger
f1f84b1bf9 docs: fix typos (#462)
Some checks failed
Deploy Hugo site to Pages / build (push) Has been cancelled
Deploy Hugo site to Pages / deploy (push) Has been cancelled
2024-09-25 23:17:11 +02:00
icannotfly
d367a443f1 docs: add cols parameter for cards shortcode (#459)
Some checks failed
Deploy Hugo site to Pages / build (push) Has been cancelled
Deploy Hugo site to Pages / deploy (push) Has been cancelled
documentation was missing
2024-09-23 23:10:38 +02:00
Xin
36ab5287b5 docs: fix favicon customization instruction
Some checks are pending
Deploy Hugo site to Pages / build (push) Waiting to run
Deploy Hugo site to Pages / deploy (push) Blocked by required conditions
2024-09-22 22:41:07 +01:00
Xin
9173f59392 fix: replace deprecated resources.PostCSS (#458) 2024-09-22 22:16:33 +01:00
Xin
c70900c25f feat: add badge shortcode (#457)
* feat: move badge to a separate partial

* feat: badge shortcode

* docs: add badge shortcode examples

* chore: generate css

* docs: add spaces between badges
2024-09-22 22:12:22 +01:00
icannotfly
cabdb421e3 Update cards.md (#456)
Some checks are pending
Deploy Hugo site to Pages / build (push) Waiting to run
Deploy Hugo site to Pages / deploy (push) Blocked by required conditions
Fix incorrect icon in example
2024-09-22 09:59:21 +01:00
Xin
de9f9b312e fix: jupyter styling not applied (#454)
Some checks failed
Deploy Hugo site to Pages / build (push) Has been cancelled
Deploy Hugo site to Pages / deploy (push) Has been cancelled
2024-09-14 23:53:43 +01:00
Xin
2af73b3d7e feat: shortcode for Jupyter Notebook (#337)
Some checks are pending
Deploy Hugo site to Pages / build (push) Waiting to run
Deploy Hugo site to Pages / deploy (push) Blocked by required conditions
* feat: shortcode for Jupyter Notebook

* chore: update generated CSS files

* chore: add example Jupyter Notebook file

* chore: update doc

* chore: enhance jupyter notebook styling

- use raw markdown for contents like code block and markdown text

* feat: support load notebook from assets and remote

- update docs accordingly
- add example notebook file

* chore: rename example file
2024-09-14 14:29:55 +01:00
Filefabrik
d1c3c40a95 optional Title in md Head (#442)
Co-authored-by: RT Filefabrik <rt@filefabriik.com>
2024-09-14 14:28:30 +01:00
dependabot[bot]
086af4d173 chore(deps): bump micromatch from 4.0.7 to 4.0.8 (#453)
Some checks failed
Deploy Hugo site to Pages / build (push) Has been cancelled
Deploy Hugo site to Pages / deploy (push) Has been cancelled
2024-09-12 08:36:39 +01:00
August
c6de4b5b6b docs: update image examples with Lorem Picsum (#445)
Some checks failed
Deploy Hugo site to Pages / build (push) Has been cancelled
Deploy Hugo site to Pages / deploy (push) Has been cancelled
2024-08-22 10:05:30 +01:00
Xin
66d2bf57ba docs: additional shortcodes (#441)
Some checks failed
Deploy Hugo site to Pages / build (push) Has been cancelled
Deploy Hugo site to Pages / deploy (push) Has been cancelled
* Create pdf.md

* Update pdf.md

* Escape PDF shortcode examples

* Remove markdown syntax highlight

* chore: update Hugo and Go versions for deployment

* docs: add additional shortcodes

* chore: re-compile

---------

Co-authored-by: Shahar Naveh <50263213+ShaharNaveh@users.noreply.github.com>
2024-08-18 16:34:48 +01:00
Xin
526be88d7b fix: tabs styling in steps shortcode (#440)
* fix: tabs styling in steps shortcode

* docs: add notes for intended usage
2024-08-18 15:38:06 +01:00
Xin
2863a3a029 fix: remove deprecated site.GoogleAnalytics (#438)
Some checks are pending
Deploy Hugo site to Pages / build (push) Waiting to run
Deploy Hugo site to Pages / deploy (push) Blocked by required conditions
* fix: remove deprecated site.GoogleAnalytics

* ci: bump netlify Hugo version
2024-08-18 14:41:40 +01:00
Erik Skopp
852a07b15e fix: remove deprecated google analytics reference in head.html (#435)
ERROR deprecated: .Site.GoogleAnalytics was deprecated in Hugo v0.120.0 and will be removed in Hugo 0.133.0. Use .Site.Config.Services.GoogleAnalytics.ID instead.
2024-08-18 12:31:50 +01:00
Xin
e83c11f31a chore: improve tags styling on card (#431)
Some checks failed
Deploy Hugo site to Pages / build (push) Has been cancelled
Deploy Hugo site to Pages / deploy (push) Has been cancelled
* chore: improve tags styling on card

* chore: npm run build:css
2024-08-11 18:47:03 +01:00
Julia March
f439e6bb87 feat: add tag support for card shortcode (#427)
* styles: accept tags on cards with default and custom colors

* styles: compile css
2024-08-11 17:30:19 +01:00
Xin
9c0ba06db4 chore: bump hugo versions 2024-08-11 16:28:59 +00:00
Xin
5c6ed19c34 chore: bump npm package versions 2024-08-11 16:28:19 +00:00
yuri
0986b9ee84 docs: add missing Markdown syntax examples (#415) 2024-08-11 17:03:51 +01:00
jinzhongjia
d2d2a62d5a docs: fix typo in chinese doc (#430) 2024-08-11 17:01:12 +01:00
Xin
e3b582676e fix: properly handle tabs overflow (#422)
Some checks failed
Deploy Hugo site to Pages / build (push) Has been cancelled
Deploy Hugo site to Pages / deploy (push) Has been cancelled
* fix: properly handle tabs overflow

* chore: rebuild css
2024-07-10 01:11:51 +01:00
yuri
56f6f19978 docs: list code block copy button config (#412)
Some checks failed
Deploy Hugo site to Pages / build (push) Has been cancelled
Deploy Hugo site to Pages / deploy (push) Has been cancelled
* fix: list code block copy button config

* Mention copy button config in the guide
2024-07-07 13:33:12 +01:00
loenvom
1313415c8b feat: add customize flexsearch tokenize feature instruction to docs (#322)
* feat: add customize flexsearch tokenize feature instruction to docs

* Update configuration.md

* Update configuration.md

* Update configuration.zh-cn.md

---------

Co-authored-by: loenvom <loenvom@qq.com>
Co-authored-by: Xin <xin@imfing.com>
2024-06-02 13:53:38 +01:00
George Gecewicz
3cba6b9820 feat: add support for breadcrumbs param in front matter for showing/hiding breadcrumbs on specific pages (#367)
* feat: add support for `hideBreadcrumbs` front-matter param

* docs(en): add some docs about breadcrumb nav, including new hideBreadcrumbs param

* fix: fix typo in hideBreadcrumbs param check in breadcrumbs.html partial

* docs(en): tidy up the Breadcrumb Navigation documentation

* fix: rework hideBreadcrumbs param to breadcrumbs; update docs accordingly

* fix: use relpermalink in breadcrumb

---------

Co-authored-by: Xin <xin@imfing.com>
2024-06-02 11:01:06 +01:00
Shahar Naveh
6ee6ddeacb i18n: add Hebrew translation (#405) 2024-05-29 22:27:34 +01:00
Serhii Pryimachuk
db92de0f1b i18n: add Ukrainian translation (#403) 2024-05-29 09:13:24 +01:00
Andreas Deininger
b2bc4f7098 fix: use hugo.IsMultilingual to replace deprecated .Site.IsMultiLingual (#404) 2024-05-29 09:11:25 +01:00
Floren Munteanu
857c4e4ca1 chore: update AXIVO docs image format (#402) 2024-05-26 18:38:55 +01:00
Floren Munteanu
d3f251b621 chore(showcase): add AXIVO docs (#400) 2024-05-25 10:19:14 +01:00
Floren Munteanu
d43ac66494 feat: add hextra hero-container shortcode (#389)
* Implement hextra hero-container

* Fix width

* Fix width

* Fix width

* Set number of columns

* Fix display for mobile devices

* Trim image prefix

* Implement image card

* Fix width

* Fix css
2024-05-23 23:36:46 +01:00
Lucas
4eca719b0b docs(fix): correct a mistake in markdown guide (#394)
Fix code mistake by making sure backticks are inserted at start and end of example text
2024-05-21 10:09:03 +01:00
Sebastian Broekhoven
daaf281012 i18n: add Dutch translation (#383)
Added Dutch translation.
2024-05-06 01:46:22 +01:00
Maxwell Jay
ba7707d4d9 docs: add showcase - HITSZ OpenAuto (#373)
* docs: add showcase - HITSZ OpenAuto

* alter showcase image

* Update index.md

* Update index.zh-cn.md

---------

Co-authored-by: Xin <xin@imfing.com>
2024-04-28 11:30:06 +01:00
longlin li
25da2baf7f chore: add i18n links in README (#374)
* docs: add i18n README links

* Update README.md

* Update README.fa.md

* Update README.zh-cn.md

---------

Co-authored-by: Xin <xin@imfing.com>
2024-04-28 11:24:21 +01:00
Kowyo
234fd39254 docs: fix deploy-site zh-cn lang filename (#371) 2024-04-24 12:39:32 +02:00
Xin
4a7ab16695 docs: fix deploy site title 2024-04-23 22:20:01 +02:00
Xin
19852552c6 docs: update zh-cn sidebar titles 2024-04-23 22:16:55 +02:00
Xin
80a1692ade docs: fix deploy-site zh-cn lang filename 2024-04-23 22:08:06 +02:00
纳兰音韵
81720c7727 docs: update zh-cn translation (#365) 2024-04-21 11:46:21 +01:00
Xin
f98fa8c389 ci: use actions/configure-pages and bump hugo version 2024-04-17 22:48:30 +00:00
Xin
3503b4c4f1 chore(deps): add taskfile and bump assets lib versions (#362)
* chore: add Taskfile for automating common tasks

* chore(deps): bump versions of third-party libraries in assets

* katex 0.16.8 -> 0.16.10
* mermaid -> 10.9.0
2024-04-17 23:14:37 +01:00
Xin
bf38320797 chore: 2023 -> 2024 2024-04-17 21:36:25 +00:00
Xin
6a9117ae7c chore(deps): bump npm package versions (#361)
* chore(deps): bump npm package versions

* recompile css

* chore: recompile css
2024-04-17 22:30:01 +01:00
Robb Shecter
be7e0d3f40 fix: js scripts not in body element (#356) 2024-04-11 14:54:59 +02:00
Kowyo
e4cdabff12 docs(i18n): add zh-cn translation of RSS button (#353)
I notice that RSS button is missed when switching language to Chinese in the documentation of Hextra. It's added now in this PR, hope it helps.
2024-04-06 09:59:27 +02:00
Xin
2f127a2f2f chore: revert adding homebrew to devcontainer
* bloat up the image size and increase the cold start time

[skip ci]
2024-04-04 22:56:04 +02:00
Xin
781e7000c4 chore: add homebrew to devcontainer
[skip ci]
2024-04-04 22:39:15 +02:00
Xin
8e98791082 chore: bump hugo version to 0.124.1 in devcontainer 2024-04-04 22:37:43 +02:00
Xin
6d4bbac085 feat: support sort blog post list page (#348) 2024-04-02 08:52:26 +01:00
Xin
5103da4cd5 chore: improve search bar shortcut display (#346)
* chore: improve search bar shortcut display

* chore: remove focusout handler
2024-04-01 19:34:57 +01:00
Xin
9f2b67c08c feat: pdf shortcode (unstable) (#345) 2024-04-01 15:55:11 +01:00
Xin
0d6cbba9df feat: add styles for definition list (#344)
* feat: dd styles for definition list

* chore: re-generate css
2024-04-01 00:18:43 +01:00
Xin
1936b46af4 docs: add more projects to showcase 2024-03-31 23:31:27 +01:00
Xin
ab9e40effd chore: add quicklink script to head in doc site 2024-03-31 22:24:24 +01:00
Xin
5080877576 feat: configurable cols for feature-grid shortcode (#342)
* feat: configurable cols for feature-grid shortcode

* chore: update css files

* chore: add hextra prefix to cards css var

* chore: rebuild css
2024-03-31 22:06:26 +01:00
Xin
24fb13b221 refactor: extract card shortcode to partial (#339)
* refactor: extract card shortcode to partial

* chore: update hugo stats
2024-03-31 11:06:47 +01:00
Xin
a5b59b61f1 fix: indented callouts rendered incorrectly (#338) 2024-03-30 17:26:40 +01:00
Xin
ef536af9e8 fix: typo in code-copy.css
* regenerate css and update hugo stats json
2024-03-28 09:33:35 +00:00
Xin
d8351aa432 feat: allow enable/disable code block copy button (#331)
* refactor: move codeblock to a partial component

* feat: add flags for code block copy button

* allow disable code copy button completely
* allow make the copy button always visible

* chore: run build:css
2024-03-28 07:32:51 +00:00
Xin
741a640b1a fix: update dead link for Porter 2024-03-20 10:38:35 +00:00
Xin
935ff7f719 feat: add title utility to get page or section title (#325)
* feat: add title utility to get page or section title

* with graceful fallback to using the directory or filename

* chore: update link titles in breadcrumb, pager, and sidebar
2024-03-19 22:16:10 +00:00
Xin
29e70c8b21 fix: code copy button is invisible when hover (#323)
* fix: code copy button is invisible when hover

* chore: update hugo_stats.json file
2024-03-18 18:37:47 +00:00
loenvom
c634cb83eb feat: support customize flexsearch tokenize option (#319)
Co-authored-by: loenvom <loenvom@qq.com>
2024-03-17 18:50:22 +00:00
Goudarz Jafari
22d4737b99 fix: RTL Steps FileTree, feat: Add Persian number for ol label counter and Steps (#314)
* fix: RTL Steps in steps.html file

* feat: Add bidirectional support

* fix: RTL problem

* fix: RTL problem, feat: Add Persian CSS counter

* feat: Add Persian for ol counter

* fix: styling text

* Add ol output example

* fix: RTL problem

* fix some issue

* fix some issue

* fix some issue
2024-03-05 07:47:29 +00:00
inter
fba95d5336 chore(i18n): add Romanian translation (#313) 2024-03-05 07:41:21 +00:00
Xin
07b67ff112 fix: module imports should be array in hugo config 2024-03-01 23:40:55 +00:00
Xin
5c7303bee7 feat: add hx- prefix to Hextra Tailwind CSS classes (#300)
* feat: add prefix to tailwind css classes

* fix: remove unnecessary prefixes

* fix: add missing prefix in other places

* chore: regenerate hugo_stats.json

* chore: run `npm run build:css`

* chore: add `hx-` prefix to _index.fa.md

* fix: lang switcher display issue

* fix: add `hx-` prefix to showcase/index.fa.md

* fix: lang switch param mistake
2024-02-20 22:59:31 +00:00
Xin
0e312d3476 docs: update GitHub Action deploy template 2024-02-20 22:55:54 +00:00
Xin
98546e66b9 chore: add slack icon
from https://icon-sets.iconify.design/simple-icons/slack/
2024-02-20 22:38:56 +00:00
Goudarz Jafari
b1f49c091f fix: RTL chevron rotation (#302)
* Fix right-to-left chevron in breadcrumb.html file

* Fix right-to-left chevron in pager.html file

* Update file
2024-02-20 22:27:23 +00:00
Inter
8e6cc68e88 chore: add BitBucket icon (#303)
* chore: add BitBucket icon

* Update icons.yaml

---------

Co-authored-by: Xin <xin@imfing.com>
2024-02-20 22:20:36 +00:00
Goudarz Jafari
9995617c66 docs(i18n): add Persian translation and support rtl languageDirection (#301)
* feat: add persian translation

* Add Persian translation

* Add fa support, languageDirection method in hugo.yaml

* Add languageDirection method

* Update hugo.yaml

* Update baseof.html
2024-02-19 21:40:50 +00:00
Xin
10907cdc25 fix: resolve padding issue for code blocks with filenames but without lang highlight (#297)
* fix: resolve padding issue for code blocks with filenames but without lang highlighting

* chore: run `npm run build:css`

* chore: update `node_modules/caniuse-lite`
2024-02-17 23:06:46 +00:00
Goudarz Jafari
6bd2cfbd6b chore(i18n): add Persian translation (#294) 2024-02-17 18:51:40 +00:00
vinnciane
2d8f42f4c5 chore: add gitlab icon to icons.yaml (#285)
Gitlab svg icon with fill to curentColor has been added to the icon set.
2024-02-13 09:29:35 +00:00
Xin
716af59393 fix: clear top margin for nested list recursively (#280)
* fix: clear top margin for nested list children

* chore: run `npm run build:css`
2024-02-06 22:04:37 +00:00
Xin
7191e25958 fix: set top margin to zero for nested list (#276) 2024-02-03 09:09:16 -05:00
Xin
c630805511 fix: details toggle display issue (#273)
when more than two lines of summary are provided
2024-02-02 23:37:54 +00:00
mafendi
cb274c8ac5 feat: add canonical to head.html (#269)
By adding `canonical` parameter to the front matter and specifying the URL, the canonical URL is added. 
If no canonical URL is needed to be specified, the layout will use the current page address for canonical tag. 

Example: 

```
---
title: "Page Title"
description: "Page description"
canonical: "https://canonicalurl.com"
---
2024-02-01 22:52:41 +00:00
Achim Krämer
fbe1aac123 i18n: add german translation (#271)
Signed-off-by: Achim Krämer <39946364+pxlfrk@users.noreply.github.com>
2024-02-01 22:48:22 +00:00
Xin
ff8f2537ca fix: accurate editURL resolution in translated sites (#264) 2024-01-21 10:33:49 +00:00
David Legrand
728fe21ef1 chore: add canonical URL to head template (#261) 2024-01-19 21:56:21 +00:00
Julia March
fc964f11a6 showcase: clever cloud documentation (#262) 2024-01-19 21:34:32 +00:00
Pavel Francírek
09e9f52019 chore(i18n): add Czech translation (#246)
Czech translation
2024-01-10 14:52:58 +00:00
verbumfeit
f5e4283961 chore: add rel="me" attribute to Mastodon navbar icon (#243)
* Add rel="me" attribute to Mastodon navbar icon

The rel="me" attribute enables verified links on the linked Mastodon profile

* Set $rel based on icon name
2024-01-08 18:25:54 +00:00
纳兰音韵
10f1d85ab4 docs: update zh-cn translation (#236)
* Update customization.zh-cn.md

* Translate: Update translation of outdated docs

* Fix error
2024-01-08 18:24:38 +00:00
John Hogenmiller
fd9a87a86a fix(docs): add editURL.enable = true (#245)
The MR documents the requirement to enable editURL setting.


[A  prior commit](04a5c7378a (diff-5311bf4e1519696010f8298385d9de30210dfcd9dee8785f6deba3a084b62eecL26)) the behavior changed from a default of "disable = false" to a default of "enabled = false".
2024-01-08 18:22:15 +00:00
verbumfeit
1f9e7c8b39 chore: add Codeberg icon (#244) 2024-01-08 18:19:37 +00:00
longlin li
7772313a53 docs: correct editURL config instruction (#215)
* docs: fix the documentation error about editURL

* docs: fix the documentation error about editURL

* Update configuration.md

* Update configuration.zh-cn.md

---------

Co-authored-by: Xin <xin@imfing.com>
2023-11-21 20:50:29 +00:00
Arnaud Levy
7f0a35ab48 chore: add Osuny to showcase (#218) 2023-11-21 08:36:06 -05:00
c2tz
35c733b7ee chore: increase time for "copied" animation duration (#214)
* align-logo-footer

add vertical align 2px for logo footer

* modify logo align in footer

* noobie things

* modify logo & vertical align

* build css

* revert change in icons.yaml

* increase duration for copied button effect

* Update hugo_stats.json

* Update main.css

* Update footer.html

* modify timeout to 1000 (1sec)
2023-11-21 00:07:14 +00:00
c2tz
aad68d8afd chore(style): better footer logo alignment (#212) 2023-11-18 15:31:30 +00:00
Xin
d58a8b5469 feat: exclude page from sidebar (#209)
* feat: allow excluding page from sidebar

* chore: tidy up

* docs: add instruction for excluding a page from sidebar

* feat: allow hiding sidebar for pages

* chore: add comment
2023-11-17 23:00:05 +00:00
Xin
64ac97b2d6 feat: allow overriding poweredBy in footer (#207) 2023-11-17 02:03:40 +00:00
Xin
27c976bcc1 feat: display author avatar images in blog post (#204)
* feat: support displaying author images in blog post

* chore: fix typo

* chore: run build:css

* refactor: support both plain author list

* chore: run build:css

* chore: add support for local avatar images

* chore: update css classes
2023-11-17 01:49:18 +00:00
Xin
d675d3bc7b feat: support separator in sidebar (#199)
* feat: support adding pages as separator for sidebar

* Update sidebar.html
2023-11-12 14:03:30 +00:00
xiln7
456c96921a typo: fix typos in sidebar.html (#203)
@OliverWu515 finds this issue, I help pr this. Hope it helps. The theme helps a lot for our org to build our documents. We found this issue when we use it.
2023-11-12 13:47:20 +00:00
Xin
c2d7ba8ce5 fix: code copy issue for code blocks in shortcode (#201)
* chore: add translation key for copy code button title

* chore: remove id from code block elements

* fix: copy the correct code target in code-copy.js

* chore: update details.md

* chore: remove console.log :)

* chore: remove `$` in shell commands

* chore: update docs
2023-11-12 01:14:39 +00:00
Xin
8801a04ebe feat: add include shortcode (#198) 2023-11-11 00:10:32 +00:00
Xin
21b0acdec5 chore: improve cards compatibility with steps (#197) 2023-11-10 23:45:42 +00:00
Xin
c0a1bc32dd fix: ensure relref in search index is properly rendered (#196)
* fix: ensure relref in search index is properly rendered

* chore: remove empty whitespace
2023-11-10 22:21:54 +00:00
Xin
4ea18168e3 fix: correctly set editURL in front-matter (#195) 2023-11-10 22:03:08 +00:00
Xin
23c84e124c fix: navbar url for multi-lang site (#193)
* fix: image URL in feature card

* fix: use relLangURL of pageRef for navbar entries
2023-11-10 17:45:44 +00:00
Xin
678f0b86ee fix: htmlUnescape toc title (#190) 2023-11-05 10:26:00 +00:00
Saurabh Mishra
defc9bc11b fix(docs): showcase starter template URL (#189)
* Update URl for Hextra Starter Template

* Update index.md

---------

Co-authored-by: Saurabh Mishra <saurabh.m@mailfence.com>
Co-authored-by: Xin <xin@imfing.com>
2023-11-05 10:09:58 +00:00
Xin
363c8c91ee fix: scroll bug due to incorrect toggle state (#186)
* fix: add mobile menu overlay to toggle body scroll

* chore: update styles
2023-11-03 20:39:36 +00:00
Xin
088e9f7821 fix(style): add backdrop to code copy button (#185)
* fix(style): add backdrop to code copy button

* chore: run build:css
2023-11-02 22:43:50 +00:00
Tehuel
7be079f504 i18n: update es.yaml (#180)
* Update es.yaml

Update spanish translations, using keys from `zh-cn.yaml`.

* Update es.yaml

---------

Co-authored-by: Xin <xin@imfing.com>
2023-11-01 20:28:29 +00:00
Xin
10ba5533e5 i18n: refactor translations for docs site (#181)
* i18n: move some translations under example site

* chore: update i18n/ja.yaml

* i18n: update zh-tw.yaml

* i18n: update fr.yaml

* i18n: update pt.yaml

* i18n: update ko.yaml

* i18n: update nb.yaml and nn.yaml

* i18n: update sw.yaml

* i18n: update vi.yaml

* i18n: update sw.yaml

* docs: clean up ja site as it's incomplete
2023-11-01 20:26:54 +00:00
Xin
433beed666 fix: plainify Toc headings (#178) 2023-10-31 23:14:42 +00:00
Pedro Lima
56a87e559d i18n: update pt.yaml (#174)
Update the Portuguese translation.
2023-10-31 09:15:51 +00:00
Xin
9d68f7c71a docs: minor update deploy site doc 2023-10-31 09:14:46 +00:00
Xin
e3f6069968 chore: support services.googleAnalytics.ID (#173)
* chore: support `services.googleAnalytics.ID`

and deprecate `site.googleAnalytics`

* chore: remove warning
2023-10-30 23:48:48 +00:00
Bjørn Erik Pedersen
de1286c7fc i18n: Add language strings for Norwegian bokmål and Norwegian nynorsk (#172)
The two main written languages in Norway.
2023-10-30 22:42:30 +00:00
c2tz
c0a1d5cb67 chore(i18n): add French translation (#166)
* Create fr-fr.yaml

* Rename fr-fr.yaml to fr.yaml

* Modify Showcase

showcase ressemble a vitrine mais je pense que laissé showcase n'est pas problématique

* Remove comments

* Resolve duplicate

duplicate

Co-authored-by: Xin <fuxin1997@gmail.com>

* correction

résultats à la place de résulats (classique)

Co-authored-by: Xin <fuxin1997@gmail.com>

---------

Co-authored-by: Xin <fuxin1997@gmail.com>
2023-10-29 17:57:45 +00:00
Xin
50f1b084ae chore(icons): add linkedin
[skip ci]
2023-10-29 17:55:27 +00:00
Xin
0d629b67b9 docs: add instructions for configuring layouts (#167) 2023-10-29 17:52:34 +00:00
Xin
7c902b4eb9 chore(style): enhance not-prose elements styling (#163)
* chore(css): improve not-prose tags styling

* fix: typo

* chore(style): improve appearance in prose

* feat: support icon in callout shortcode

* chore: add RSS badge to blog list page

* chore: run build:css

* chore: run build:css

* chore: remove unused CSS

* chore: add footer.enable explicitly to config

* chore: use `where` pseudo class for more prose elements

* chore: run build:css

* chore: remove blank space

* chore: rebuild css

* chore: update figure css
2023-10-29 15:19:31 +00:00
385 changed files with 15876 additions and 8808 deletions

View File

@@ -3,7 +3,7 @@
"features": {
"ghcr.io/devcontainers/features/hugo:1": {
"extended": true,
"version": "0.119.0"
"version": "0.147.7"
},
"ghcr.io/devcontainers/features/node:1": {}
},
@@ -18,5 +18,7 @@
}
},
"postCreateCommand": "npm install",
"forwardPorts": [1313]
}
"forwardPorts": [
1313
]
}

View File

@@ -57,7 +57,7 @@ We recommend that you search existing [issues][issues] or discussions before ope
### Local development setup
- [Hugo][hugo] >= v0.115.0 (extended version)
- [Hugo][hugo] >= v0.124.0 (extended version)
- [Node.js][nodejs]
- [Go][go]

15
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,15 @@
# These are supported funding model platforms
github: imfing
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
polar: # Replace with a single Polar username
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
thanks_dev: # Replace with a single thanks.dev username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@@ -17,6 +17,8 @@ assignees: ''
2.
3.
<!-- Provide a minimal example or link to a repository that reproduces the bug -->
**Expected Behavior**
<!-- What should have happened? -->

View File

@@ -1,5 +1,5 @@
# Sample workflow for building and deploying a Hugo site to GitHub Pages
name: Deploy Hugo site to Pages
# Build and deploy Hextra docs site to GitHub Pages
name: Deploy Hextra docs site to Pages
on:
# Runs on pushes targeting the default branch
@@ -31,35 +31,43 @@ jobs:
build:
runs-on: ubuntu-latest
env:
HUGO_VERSION: 0.117.0
HUGO_VERSION: 0.147.7
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
fetch-depth: 0 # fetch all history for .GitInfo and .Lastmod
fetch-tags: true
submodules: recursive
- name: Setup Go
uses: actions/setup-go@v4
uses: actions/setup-go@v5
with:
go-version: '1.20'
go-version: "1.24"
- name: Setup Pages
id: pages
uses: actions/configure-pages@v5
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: ${{ env.HUGO_VERSION }}
extended: true
- name: Build with Hugo
run: |
wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \
&& sudo dpkg -i ${{ runner.temp }}/hugo.deb
- name: Make build script executable
run: chmod +x ./build.sh
- name: Build all site versions
env:
# For maximum backward compatibility with Hugo modules
HUGO_ENVIRONMENT: production
HUGO_ENV: production
run: |
hugo \
--minify \
--themesDir=../.. --source=exampleSite \
--baseURL "https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/"
./build.sh "${{ steps.pages.outputs.base_url }}"
- name: Upload artifact
uses: actions/upload-pages-artifact@v2
uses: actions/upload-pages-artifact@v3
with:
path: ./exampleSite/public
path: ./public
# Deployment job
deploy:
@@ -71,4 +79,4 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2
uses: actions/deploy-pages@v4

View File

@@ -1,4 +1,7 @@
{
"plugins": [
"prettier-plugin-go-template"
],
"goTemplateBracketSpacing": true,
"htmlWhitespaceSensitivity": "css",
"printWidth": 200,

161
CLAUDE.md Normal file
View File

@@ -0,0 +1,161 @@
# CLAUDE.md
This file provides guidance to [Claude Code](claude.ai/code) when working with code in this repository.
## Project Overview
Hextra is a modern, responsive Hugo theme designed for creating documentation websites, technical blogs, and static sites. Built with Tailwind CSS and inspired by Nextra, it offers features like full-text search, dark mode, multi-language support, and extensive customization options.
## Development Commands
### Development Server
```bash
# Start development server with theme reloading (recommended for theme development)
npm run dev:theme
# Using Task runner
task dev
```
### Building
```bash
# Build the example site
npm run build
# or
task build
# Build CSS assets only
npm run build:css
# or
task css
```
### Alternative Task Commands
The project uses Task runner (`taskfile.yaml`) for simplified commands:
- `task dev` - Start development server (runs `npm run dev:theme`)
- `task build` - Build example site
- `task css` - Compile CSS (depends on build)
## Architecture Overview
### Hugo Theme Structure
- **Base Layout**: `layouts/baseof.html` wraps all pages
- **Specialized Layouts**: `layouts/docs/`, `layouts/blog/`, `layouts/hextra-home.html`
- **Partials**: Reusable components in `layouts/_partials/`
- Core UI: `navbar.html`, `sidebar.html`, `footer.html`, `breadcrumb.html`, `toc.html`
- Utilities: `layouts/_partials/utils/` for helper functions
- Custom overrides: `layouts/_partials/custom/` for user customizations
- **Shortcodes**: Custom Markdown extensions in `layouts/_shortcodes/`
- **Render Hooks**: Custom Markdown rendering in `layouts/_markup/` for codeblocks, headings, images, and links
### Asset Organization
```
assets/
├── css/
│ ├── styles.css # Main stylesheet
│ ├── compiled/main.css # Built CSS output (generated)
│ ├── components/ # Component-specific styles
│ └── chroma/ # Syntax highlighting themes
├── js/ # JavaScript components
└── lib/ # External libraries
```
### Key Components
- **Search**: FlexSearch-powered full-text search (`assets/js/flexsearch.js`)
- **Navigation**: Responsive navbar and auto-generated sidebar
- **Theme Toggle**: Dark/light mode switching
- **Internationalization**: 20+ language support in `i18n/`
### Content Features
- **Shortcodes**: `callout`, `card`, `cards`, `tabs`, `details`, `steps`, `jupyter`, `filetree`
- **Code Features**: Syntax highlighting (Chroma), copy buttons, line numbers via render hooks
- **SEO**: Open Graph, Twitter Cards, structured data
- **Performance**: Minimal JavaScript, optimized CSS with Tailwind
## Development Workflow
### Example Site Development
The `exampleSite/` directory serves as both documentation and testing ground:
- Test new features here before releasing
- Configuration examples in `exampleSite/hugo.yaml` showing multi-language setup
- Content examples demonstrate all theme capabilities
- Run from exampleSite with: `hugo server --themesDir=../..`
### CSS Development Workflow
- Source: `assets/css/styles.css` (main stylesheet)
- Build process: Tailwind CSS → PostCSS → `assets/css/compiled/main.css`
- Component styles organized in `assets/css/components/`
- Chroma syntax highlighting themes in `assets/css/chroma/`
- CSS compilation requires Node.js dependencies (PostCSS, Tailwind CSS v4+)
### Customization Points
- Custom partials: `layouts/_partials/custom/`
- Custom CSS: `assets/css/custom.css`
- Site-specific overrides: Copy any layout to your site's `layouts/` directory
## Configuration & Requirements
### Theme Requirements
- Hugo minimum version: 0.146.0 (extended version required - see `theme.toml`)
- Go 1.20+ (as specified in `go.mod`)
- Node.js for CSS compilation (PostCSS, Tailwind CSS v4+)
### Key Configuration Files
- `exampleSite/hugo.yaml` - Example Hugo configuration with multi-language setup
- `postcss.config.mjs` - PostCSS configuration for CSS processing
- `package.json` - Node.js dependencies and build scripts
- `taskfile.yaml` - Task runner configuration
### Development Environment
- Default Hugo development server: Port 1313
- Development server runs with `--disableFastRender -D` for better development experience
- Theme development uses `--logLevel=debug` for detailed logging
### Multi-language Support
- Configure languages in `hugo.yaml` (supports 20+ languages including RTL)
- Translation files in `i18n/` directory (e.g., `en.yaml`, `fa.yaml`, `ja.yaml`, `zh-cn.yaml`)
- Example supports English, Persian (RTL), Japanese, and Simplified Chinese
## Theme Development Guidelines
### Hugo Theme Conventions
- Theme files in this repository override Hugo defaults
- Follow Hugo's theme development guidelines for compatibility
- Maintain backward compatibility with existing configurations
### JavaScript & Performance
- All JavaScript components are designed to have minimal footprint
- Core JS components: `theme.js`, `search.js`, `nav-menu.js`, `code-copy.js`
- FlexSearch powers offline full-text search functionality
### CSS Architecture
- Uses Tailwind CSS v4+ with PostCSS processing
- Component-based CSS organization in `assets/css/components/`
- Compiled output goes to `assets/css/compiled/main.css`
- Prettier formatting for Go templates and code consistency
### Testing & Quality Assurance
- Test all changes in `exampleSite/` before releasing
- Use `npm run dev:theme` for theme development with hot reloading
- Format code with `npx prettier --write .` before committing
- Verify multi-language functionality across supported languages

48
README.fa.md Normal file
View File

@@ -0,0 +1,48 @@
<div align="center">
<h1 align="center">هگزترا</h1>
<sup align="center"><a href="README.md">English</a> | <a href="README.zh-cn.md">简体中文</a> <a href="README.fa.md">فارسی</a></sup>
<p align="center">تم هیوگو مدرن، پاسخگو و دارای امکانات کامل برای ایجاد وب‌سایت‌های استاتیک زیبا.</p>
نسخه‌ی نمایشی → [imfing.github.io/hextra](https://imfing.github.io/hextra/fa)
</div>
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/5097752/263550533-c18343ca-3848-4230-b5c0-ee989d7916da.png">
<img alt="Hextra" src="https://user-images.githubusercontent.com/5097752/263550528-663599f9-17a1-4686-b5c4-3da233b5034d.png">
</picture>
<div align="right">
<a href="https://github.com/imfing/hextra/actions/workflows/pages.yml"><img alt="GitHub Actions Status" src="https://github.com/imfing/hextra/actions/workflows/pages.yml/badge.svg"></a> <a href="https://app.netlify.com/sites/hugo-hextra/deploys"><img alt="Netlify Status" src="https://api.netlify.com/api/v1/badges/61d6e55a-2447-487e-b59f-c9537e5df175/deploy-status"></a>
</div>
## ویژگی‌ها
- **طراحی زیبا** - با الهام از Nextra، هگزترا از Tailwind CSS برای ارائه یک طراحی مدرن که سایت شما را برجسته می‌کند، استفاده می‌کند.
- **طراحی واکنش‌گرا و حالت تیره** - در تمام دستگاه‌ها، از تلفن همراه، تبلت تا دسکتاپ، عالی به نظر می‌رسد. حالت تیره نیز برای انطباق با شرایط مختلف روشنایی پشتیبانی می‌شود.
- **سریع و سبک** - طراحی شده توسط Hugo، یک ایجادکننده سایت استاتیک سریع مثل رعد و برق که در یک فایل باینری قرار گرفته است، هگزترا ردپای خود را به حداقل می‌رساند. برای استفاده از آن به جاوااسکریپت یا Node.js نیازی ندارید.
- **جستجوی متن کامل** - جستجوی متن کاملا آفلاین داخلی طراحی شده توسط FlexSearch، بدون نیاز به پیکربندی اضافی.
- **امکانات کامل** - برای بهتر کردن محتوای شما مارک‌داون، برجسته‌کردن سینتکس، فرمول‌های ریاضی LaTeX، نمودارها و عناصر Shortcodeها را شامل میشه. فهرست مطالب، بردکرامب، صفحه‌بندی، پیمایش نوار کناری و موارد دیگر همه به صورت خودکار تولید می‌شوند.
- **چند زبانه و سئو آماده** - سایت‌های چند زبانه با حالت چند زبانه Hugo راحت ساخته می‌شوند. پشتیبانی خارج از جعبه برای برچسب‌های سئو، Open Graph و کارت‌های توییتر گنجانده شده است.
## شروع کنید
### شروع سریع از طریق Template
استفاده از [Hextra Starter Template](https://github.com/imfing/hextra-starter-template) ساده‌ترین روش برای راه‌اندازی سریع یک وب‌سایت جدید با تم هگزترا است. با کلیک بر روی دکمه "Use this template" در بالای صفحه مخزن شروع کنید.
مخزن تم همچنین شامل یک [گردش کار گیت‌هاب Actions](https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site#publishing-with-a-custom-github-actions-workflow) رای به‌کاراندازی وب‌سایت شما در گیت‌هاب Pages است.
<img alt="Hextra Starter Template" src="https://user-images.githubusercontent.com/5097752/263551418-c403b9a9-a76c-47a6-8466-513d772ef0b7.jpg" width=600/>
### استفاده
برای اطلاعات بیشتر به بخش [مستندات](https://imfing.github.io/hextra/fa/docs) مراجعه کنید.
## مشارکت کردن
از مشارکت افراد جدید استقبال می‌کنیم.
برای شروع، [راهنمای مشارکت](.github/CONTRIBUTING.md) را بررسی کنید.
## مجوز
[مجوز MIT](./LICENSE)

View File

@@ -1,5 +1,6 @@
<div align="center">
<h1 align="center">Hextra</h1>
<sup align="center"><a href="README.md">English</a> | <a href="README.zh-cn.md">简体中文</a> <a href="README.fa.md">فارسی</a></sup>
<p align="center">Modern, responsive, batteries-included Hugo theme for creating beautiful static websites.</p>
Demo → [imfing.github.io/hextra](https://imfing.github.io/hextra/)

View File

@@ -1,5 +1,6 @@
<div align="center">
<h1 align="center">Hextra</h1>
<sup align="center"><a href="README.md">English</a> | <a href="README.zh-cn.md">简体中文</a> <a href="README.fa.md">فارسی</a></sup>
<p align="center">用于创建美观的静态站点的现代化, 响应式, 功能强大的 Hugo 主题.</p>
演示 → [imfing.github.io/hextra](https://imfing.github.io/hextra/)
@@ -20,7 +21,7 @@
- **响应式布局和深色模式支持** - 在任何设备上看起来都足够美观, 无论是手机, 平板电脑或者电脑. 深色模式的支持使 Hextra 可以应对各种照明环境.
- **快速且轻量** - 由 Hugo 强力支持, Hugo 是一个快如闪电的静态站点生成器, 这一切都只需一个可执行文件, Hextra 始终保持最小化, 无需 Javascript 或者 Node.js.
- **全文搜索** - 集成了 Flexsearch 的全文搜索, 无需额外的配置.
- **网站中的瑞士军刀** - Markdown, 代码高亮, LaTex 数学公式, diagrams 图表和 Shortcodes 都可以用于丰富你的内容. 目录, 面包屑导航, 分页, 侧边栏等均由 Hextra 自动生成。
- **功能齐全** - Markdown, 代码高亮, LaTex 数学公式, diagrams 图表和 Shortcodes 都可以用于丰富你的内容. 目录, 面包屑导航, 分页, 侧边栏等均由 Hextra 自动生成。
- **多语言和 SEO Ready** - Hugo 的多语言模式使得构建多语言网站更简单. 具有 SEO tags, Open Graph, 和 Twitter Cards 等诸多开箱即用的功能.
## 快速开始

View File

@@ -74,7 +74,7 @@
/* CommentPreprocFile */ .chroma .cpf { color: #8b949e; font-weight: bold; font-style: italic }
/* Generic */ .chroma .g { }
/* GenericDeleted */ .chroma .gd { color: #ffa198; background-color: #490202 }
/* GenericEmph */ .chroma .ge { font-style: italic }
/* GenericEmph */ .chroma .ge { color: inherit; font-style: italic }
/* GenericError */ .chroma .gr { color: #ffa198 }
/* GenericHeading */ .chroma .gh { color: #79c0ff; font-weight: bold }
/* GenericInserted */ .chroma .gi { color: #56d364; background-color: #0f5323 }

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
.hextra-badge {
@apply hx:inline-flex hx:items-center;
}

View File

@@ -1,5 +1,9 @@
.hextra-cards {
grid-template-columns: repeat(auto-fill, minmax(max(250px, calc((100% - 1rem * 2) / var(--rows))), 1fr));
grid-template-columns: repeat(auto-fill, minmax(max(250px, calc((100% - 1rem * 2) / var(--hextra-cards-grid-cols))), 1fr));
}
.hextra-card {
position: relative;
}
.hextra-card img {
@@ -18,6 +22,7 @@
.hextra-card p {
margin-top: 0.5rem;
position: relative;
}
.dark .hextra-card svg {
@@ -27,3 +32,10 @@
.dark .hextra-card:hover svg {
color: currentColor;
}
.hextra-card-tag {
position: absolute;
top: 5px;
right: 5px;
z-index: 10;
}

View File

@@ -0,0 +1,7 @@
@supports (
(-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))
) {
.hextra-code-copy-btn {
@apply hx:backdrop-blur-md hx:opacity-85 hx:dark:opacity-80;
}
}

View File

@@ -0,0 +1,5 @@
.hextra-feature-grid {
@media (min-width: 1024px) {
grid-template-columns: repeat(var(--hextra-feature-grid-cols), minmax(0, 1fr));
}
}

View File

@@ -0,0 +1,17 @@
.hextra-jupyter-code-cell {
scrollbar-gutter: auto;
@apply hx:mt-6;
.hextra-jupyter-code-cell-outputs-container {
@apply hx:text-xs hx:overflow-hidden;
.hextra-jupyter-code-cell-outputs {
@apply hx:overflow-auto hx:max-h-[50vh];
pre {
@apply hx:text-xs hx:overflow-auto hx:max-w-full;
}
}
}
}

View File

@@ -1,55 +1,50 @@
nav {
.search-wrapper {
@apply hidden md:inline-block;
@apply hx:hidden hx:md:inline-block;
}
}
@supports (
(-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))
) {
.nav-container-blur {
@apply backdrop-blur-md bg-white/[.85] dark:!bg-dark/80;
.hextra-nav-container-blur {
@apply hx:backdrop-blur-md hx:bg-white/[.85] hx:dark:bg-dark/80!;
}
}
.hamburger-menu svg {
g {
@apply origin-center;
transition: transform 0.2s cubic-bezier(0.25, 1, 0.5, 1);
}
path {
opacity: 1;
transition:
transform 0.2s cubic-bezier(0.25, 1, 0.5, 1) 0.2s,
opacity 0.2s ease 0.2s;
}
&.open {
path {
transition:
transform 0.2s cubic-bezier(0.25, 1, 0.5, 1),
opacity 0s ease 0.2s;
}
g {
transition: transform 0.2s cubic-bezier(0.25, 1, 0.5, 1) 0.2s;
}
}
&.open > {
path {
@apply opacity-0;
}
g:nth-of-type(1) {
@apply rotate-45;
path {
transform: translate3d(0, 4px, 0);
}
}
g:nth-of-type(2) {
@apply -rotate-45;
path {
transform: translate3d(0, -4px, 0);
}
}
}
/* Hamburger Menu - Flattened Structure */
.hextra-hamburger-menu svg g {
@apply hx:origin-center hx:transition-all hx:duration-100 hx:ease-out;
}
.hextra-hamburger-menu svg path {
@apply hx:opacity-100 hx:transition-all hx:duration-100 hx:ease-out hx:delay-100;
}
.hextra-hamburger-menu svg.open path {
@apply hx:transition-transform hx:duration-100 hx:ease-out hx:delay-0;
}
.hextra-hamburger-menu svg.open g {
@apply hx:transition-transform hx:duration-100 hx:ease-out hx:delay-100;
}
.hextra-hamburger-menu svg.open > path {
@apply hx:opacity-0;
}
.hextra-hamburger-menu svg.open > g:nth-of-type(1) {
@apply hx:rotate-45;
}
.hextra-hamburger-menu svg.open > g:nth-of-type(1) path {
@apply hx:translate-y-1;
}
.hextra-hamburger-menu svg.open > g:nth-of-type(2) {
@apply hx:-rotate-45;
}
.hextra-hamburger-menu svg.open > g:nth-of-type(2) path {
@apply hx:-translate-y-1;
}

View File

@@ -1,21 +1,21 @@
.hextra-scrollbar {
.hextra-scrollbar, .hextra-scrollbar * {
scrollbar-width: thin; /* Firefox */
scrollbar-color: oklch(55.55% 0 0 / 40%) transparent; /* Firefox */
scrollbar-gutter: stable;
&::-webkit-scrollbar {
@apply w-3 h-3;
@apply hx:w-3 hx:h-3;
}
&::-webkit-scrollbar-track {
@apply bg-transparent;
@apply hx:bg-transparent;
}
&::-webkit-scrollbar-thumb {
@apply rounded-[10px];
@apply hx:rounded-[10px];
}
&:hover::-webkit-scrollbar-thumb {
border: 3px solid transparent;
background-color: var(--tw-shadow-color);
background-clip: content-box;
@apply shadow-neutral-500/20 hover:shadow-neutral-500/40;
@apply hx:shadow-neutral-500/20 hx:hover:shadow-neutral-500/40;
}
}

View File

@@ -1,38 +1,38 @@
.search-wrapper {
.hextra-search-wrapper {
li {
@apply mx-2.5 break-words rounded-md contrast-more:border text-gray-800 contrast-more:border-transparent dark:text-gray-300;
@apply hx:mx-2.5 hx:break-words hx:rounded-md hx:contrast-more:border hx:text-gray-800 hx:contrast-more:border-transparent hx:dark:text-gray-300;
a {
@apply block scroll-m-12 px-2.5 py-2;
@apply hx:block hx:scroll-m-12 hx:px-2.5 hx:py-2;
}
.title {
@apply text-base font-semibold leading-5;
.hextra-search-title {
@apply hx:text-base hx:font-semibold hx:leading-5;
}
.active {
@apply rounded-md bg-primary-500/10 contrast-more:border-primary-500;
.hextra-search-active {
@apply hx:rounded-md hx:bg-primary-500/10 hx:contrast-more:border-primary-500;
}
}
.no-result {
@apply block select-none p-8 text-center text-sm text-gray-400;
.hextra-search-no-result {
@apply hx:block hx:select-none hx:p-8 hx:text-center hx:text-sm hx:text-gray-400;
}
.prefix {
@apply mx-2.5 mb-2 mt-6 select-none border-b border-black/10 px-2.5 pb-1.5 text-xs font-semibold
uppercase text-gray-500 first:mt-0 dark:border-white/20 dark:text-gray-300 contrast-more:border-gray-600
contrast-more:text-gray-900 contrast-more:dark:border-gray-50 contrast-more:dark:text-gray-50;
.hextra-search-prefix {
@apply hx:mx-2.5 hx:mb-2 hx:mt-6 hx:select-none hx:border-b hx:border-black/10 hx:px-2.5 hx:pb-1.5 hx:text-xs hx:font-semibold
hx:uppercase hx:text-gray-500 hx:first:mt-0 hx:dark:border-white/20 hx:dark:text-gray-300 hx:contrast-more:border-gray-600
hx:contrast-more:text-gray-900 hx:contrast-more:dark:border-gray-50 hx:contrast-more:dark:text-gray-50;
}
.excerpt {
@apply overflow-hidden text-ellipsis mt-1 text-sm leading-[1.35rem] text-gray-600 dark:text-gray-400 contrast-more:dark:text-gray-50;
.hextra-search-excerpt {
@apply hx:overflow-hidden hx:text-ellipsis hx:mt-1 hx:text-sm hx:leading-[1.35rem] hx:text-gray-600 hx:dark:text-gray-400 hx:contrast-more:dark:text-gray-50;
display: -webkit-box;
line-clamp: 1;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
}
.match {
@apply text-primary-600;
.hextra-search-match {
@apply hx:text-primary-600;
}
}

View File

@@ -1,21 +1,21 @@
@media (max-width: 767px) {
.sidebar-container {
@apply fixed pt-[calc(var(--navbar-height))] top-0 w-full bottom-0 z-[15] overscroll-contain bg-white dark:bg-dark;
transition: transform 0.8s cubic-bezier(0.52, 0.16, 0.04, 1);
@media (max-width: 48rem) {
.hextra-sidebar-container {
@apply hx:fixed hx:pt-[calc(var(--navbar-height))] hx:top-0 hx:w-full hx:bottom-0 hx:z-[15] hx:overscroll-contain hx:bg-white hx:dark:bg-dark;
transition: transform 0.4s cubic-bezier(0.52, 0.16, 0.04, 1);
will-change: transform, opacity;
contain: layout style;
backface-visibility: hidden;
}
}
.sidebar-container {
.hextra-sidebar-container {
li > div {
@apply h-0;
@apply hx:h-0;
}
li.open > div {
@apply h-auto pt-1;
@apply hx:h-auto hx:pt-1;
}
li.open > a > span > svg > path {
@apply rotate-90;
@apply hx:rotate-90;
}
}

View File

@@ -1,11 +1,22 @@
.steps h3 {
counter-increment: step;
&:before {
@apply absolute w-[33px] h-[33px];
@apply border-4 border-white bg-gray-100 dark:border-dark dark:bg-neutral-800;
@apply rounded-full text-neutral-400 text-base font-normal text-center -indent-px;
@apply mt-[3px] ml-[-41px];
content: counter(step);
.hextra-steps {
:where(h2, h3, h4, h5, h6):not(.no-step-marker) {
counter-increment: step;
@apply hx:ltr:before:ml-[-41px] hx:rtl:before:mr-[-44px];
/* https://github.com/tailwindlabs/tailwindcss/issues/15597#issuecomment-2582673546 */
@apply hx:before:bg-gray-100 hx:dark:before:bg-neutral-800;
@apply hx:before:border-4 hx:before:border-white hx:dark:before:border-dark;
&:before {
content: counter(step);
@apply hx:absolute hx:size-[33px];
@apply hx:rounded-full hx:text-neutral-400 hx:text-base hx:font-normal hx:text-center hx:-indent-px;
}
}
}
:lang(fa) .hextra-steps {
:where(h2, h3, h4, h5, h6):not(.no-step-marker) {
&:before {
content: counter(step, persian);
}
}
}

View File

@@ -0,0 +1,4 @@
/* Table of Contents Scroll Spy Styles */
.hextra-toc a.hextra-toc-active {
@apply hx:text-gray-900! hx:dark:text-gray-50! hx:transition-all hx:duration-200;
}

View File

@@ -1,48 +1,53 @@
/* Code syntax highlight */
@import "chroma/light.css";
@import "chroma/dark.css";
@import "./chroma/light.css";
@import "./chroma/dark.css";
.code-block {
@apply text-[.9em] leading-5;
.hextra-code-block {
@apply hx:text-[.9em] hx:leading-5;
pre {
@apply text-[.9em] bg-primary-700/5 overflow-x-auto font-medium subpixel-antialiased dark:bg-primary-300/10 contrast-more:border contrast-more:border-primary-900/20 contrast-more:contrast-150 contrast-more:dark:border-primary-100/40;
@apply hx:text-[.9em] hx:bg-primary-700/5 hx:overflow-x-auto hx:font-medium hx:subpixel-antialiased hx:dark:bg-primary-300/10 hx:contrast-more:border hx:contrast-more:border-primary-900/20 hx:contrast-more:contrast-150 hx:contrast-more:dark:border-primary-100/40;
}
.filename {
@apply absolute top-0 z-[1] w-full truncate rounded-t-xl bg-primary-700/5 py-2 px-4 text-xs text-gray-700 dark:bg-primary-300/10 dark:text-gray-200;
.hextra-code-filename {
@apply hx:absolute hx:top-0 hx:z-[1] hx:w-full hx:truncate hx:rounded-t-xl hx:bg-primary-700/5 hx:py-2 hx:px-4 hx:text-xs hx:text-gray-700 hx:dark:bg-primary-300/10 hx:dark:text-gray-200;
}
.hextra-code-filename + pre:not(.lntable pre) {
/* Override padding for code blocks with filename but no highlight */
@apply hx:pt-12;
}
}
.code-block pre:not(.lntable pre) {
@apply px-4 mb-4 py-4 rounded-xl;
.hextra-code-block pre:not(.lntable pre) {
@apply hx:px-4 hx:mb-4 hx:py-4 hx:rounded-xl;
}
.code-block div:nth-of-type(2) pre {
@apply pt-12 pb-4;
.hextra-code-block div:nth-of-type(2) pre {
@apply hx:pt-12 hx:pb-4;
}
.chroma {
.lntable {
@apply m-0 block w-auto overflow-auto rounded-xl;
@apply hx:m-0 hx:block hx:w-auto hx:overflow-auto hx:rounded-xl;
pre {
@apply pt-4 pb-4;
@apply hx:pt-4 hx:pb-4;
}
}
.ln,
.lnt:not(.hl > .lnt),
.hl:not(.line) {
@apply pl-4 pr-4 min-w-[2.6rem] text-neutral-600 dark:text-neutral-300;
@apply hx:pl-4 hx:pr-4 hx:min-w-[2.6rem] hx:text-neutral-600 hx:dark:text-neutral-300;
}
.lntd {
@apply p-0 align-top;
@apply hx:p-0 hx:align-top;
}
.lntd:last-of-type {
@apply w-full;
@apply hx:w-full;
}
/* LineHighlight */
.hl {
@apply block w-full bg-primary-800/10;
@apply hx:block hx:w-full hx:bg-primary-800/10;
}
}

1
assets/css/safelist.txt Normal file
View File

@@ -0,0 +1 @@
hx:max-w-full

View File

@@ -1,32 +1,53 @@
@import "tailwind.css";
@import "tailwindcss" prefix(hx);
@import "typography.css";
@import "highlight.css";
@import "components/cards.css";
@import "components/steps.css";
@import "components/search.css";
@import "components/sidebar.css";
@import "components/navbar.css";
@import "components/scrollbar.css";
@custom-variant dark (&:where(.dark, .dark *));
@theme {
--color-primary-50: hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 47));
--color-primary-100: hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 44));
--color-primary-200: hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 36));
--color-primary-300: hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 27));
--color-primary-400: hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 16));
--color-primary-500: hsl(var(--primary-hue) var(--primary-saturation) var(--primary-lightness));
--color-primary-600: hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 45));
--color-primary-700: hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 39));
--color-primary-800: hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 32));
--color-primary-900: hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 24));
--color-dark: #111;
}
html {
@apply text-base antialiased;
font-feature-settings: "rlig" 1, "calt" 1, "ss01" 1;
-webkit-tap-highlight-color: transparent;
@apply hx:text-base hx:antialiased;
}
body {
@apply w-full bg-white dark:bg-dark dark:text-gray-100;
@apply hx:w-full hx:bg-white hx:dark:bg-dark hx:dark:text-gray-100;
}
:root {
--primary-hue: 212deg;
--primary-saturation: 100%;
--primary-lightness: 50%;
--navbar-height: 4rem;
--menu-height: 3.75rem;
--menu-height: 3.75rem; /* 60px */
}
.dark {
--primary-hue: 204deg;
--primary-saturation: 100%;
--primary-lightness: 50%;
}
@import "./typography.css";
@import "./highlight.css";
@import "./components/cards.css";
@import "./components/steps.css";
@import "./components/search.css";
@import "./components/sidebar.css";
@import "./components/navbar.css";
@import "./components/scrollbar.css";
@import "./components/code-copy.css";
@import "./components/hextra/feature-grid.css";
@import "./components/jupyter.css";
@import "./components/badge.css";
@import "./components/toc.css";

View File

@@ -1,3 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@@ -1,157 +1,143 @@
.content {
h1 {
@apply mt-2 text-4xl font-bold tracking-tight text-slate-900 dark:text-slate-100;
:where(h1):not(:where([class~=not-prose],[class~=not-prose] *)) {
@apply hx:mt-2 hx:text-4xl hx:font-bold hx:tracking-tight hx:text-slate-900 hx:dark:text-slate-100;
}
h2 {
@apply font-semibold tracking-tight text-slate-900 dark:text-slate-100 mt-10 border-b pb-1 text-3xl border-neutral-200/70 contrast-more:border-neutral-400 dark:border-primary-100/10 contrast-more:dark:border-neutral-400;
:where(h2):not(:where([class~=not-prose],[class~=not-prose] *)) {
@apply hx:font-semibold hx:tracking-tight hx:text-slate-900 hx:dark:text-slate-100 hx:mt-10 hx:border-b hx:pb-1 hx:text-3xl hx:border-neutral-200/70 hx:contrast-more:border-neutral-400 hx:dark:border-primary-100/10 hx:contrast-more:dark:border-neutral-400;
}
h3 {
@apply font-semibold tracking-tight text-slate-900 dark:text-slate-100 mt-8 text-2xl;
:where(h3):not(:where([class~=not-prose],[class~=not-prose] *)) {
@apply hx:font-semibold hx:tracking-tight hx:text-slate-900 hx:dark:text-slate-100 hx:mt-8 hx:text-2xl;
}
h4 {
@apply font-semibold tracking-tight text-slate-900 dark:text-slate-100 mt-8 text-xl;
:where(h4):not(:where([class~=not-prose],[class~=not-prose] *)) {
@apply hx:font-semibold hx:tracking-tight hx:text-slate-900 hx:dark:text-slate-100 hx:mt-8 hx:text-xl;
}
h5 {
@apply font-semibold tracking-tight text-slate-900 dark:text-slate-100 mt-8 text-lg;
:where(h5):not(:where([class~=not-prose],[class~=not-prose] *)) {
@apply hx:font-semibold hx:tracking-tight hx:text-slate-900 hx:dark:text-slate-100 hx:mt-8 hx:text-lg;
}
h6 {
@apply font-semibold tracking-tight text-slate-900 dark:text-slate-100 mt-8 text-base;
:where(h6):not(:where([class~=not-prose],[class~=not-prose] *)) {
@apply hx:font-semibold hx:tracking-tight hx:text-slate-900 hx:dark:text-slate-100 hx:mt-8 hx:text-base;
}
p {
@apply mt-6 leading-7 first:mt-0;
:where(p):not(:where([class~=not-prose],[class~=not-prose] *)) {
@apply hx:mt-6 hx:leading-7 hx:first:mt-0;
}
.not-prose p {
@apply mt-0 leading-normal;
:where(a):not(:where([class~=not-prose],[class~=not-prose] *)) {
@apply hx:text-primary-600 hx:underline hx:decoration-from-font;
}
a {
@apply text-primary-600 underline decoration-from-font [text-underline-position:from-font];
:where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)) {
@apply hx:mt-6 hx:border-gray-300 hx:italic hx:text-gray-700 hx:dark:border-gray-700 hx:dark:text-gray-400 hx:first:mt-0 hx:ltr:border-l-2 hx:ltr:pl-6 hx:rtl:border-r-2 hx:rtl:pr-6;
}
.not-prose a {
@apply text-current no-underline;
:where(pre):not(:where(.hextra-code-block pre, [class~=not-prose],[class~=not-prose] *)) {
@apply hx:bg-primary-700/5 hx:mb-4 hx:overflow-x-auto hx:rounded-xl hx:font-medium hx:subpixel-antialiased hx:dark:bg-primary-300/10 hx:text-[.9em] hx:contrast-more:border hx:contrast-more:border-primary-900/20 hx:contrast-more:contrast-150 hx:contrast-more:dark:border-primary-100/40 hx:py-4;
}
blockquote {
@apply mt-6 border-gray-300 italic text-gray-700 dark:border-gray-700 dark:text-gray-400 first:mt-0 ltr:border-l-2 ltr:pl-6 rtl:border-r-2 rtl:pr-6;
:where(code):not(:where(.hextra-code-block code, [class~=not-prose],[class~=not-prose] *)) {
@apply hx:border-black/4 hx:bg-black/3 hx:break-words hx:rounded-md hx:border hx:py-0.5 hx:px-[.25em] hx:text-[.9em] hx:dark:border-white/10 hx:dark:bg-white/10;
}
pre:not(.code-block pre) {
@apply bg-primary-700/5 mb-4 overflow-x-auto rounded-xl font-medium subpixel-antialiased dark:bg-primary-300/10 text-[.9em] contrast-more:border contrast-more:border-primary-900/20 contrast-more:contrast-150 contrast-more:dark:border-primary-100/40 py-4;
}
code:not(.code-block code) {
@apply border-black border-opacity-[0.04] bg-opacity-[0.03] bg-black break-words rounded-md border py-0.5 px-[.25em] text-[.9em] dark:border-white/10 dark:bg-white/10;
}
table:not(.code-block table) {
@apply block overflow-x-auto mt-6 p-0 first:mt-0;
:where(table):not(:where(.hextra-code-block table, [class~=not-prose],[class~=not-prose] *)) {
@apply hx:block hx:overflow-x-auto hx:my-6 hx:p-0 hx:first:mt-0 hx:w-full hx:text-sm hx:leading-5;
tr {
@apply m-0 border-t border-gray-300 p-0 dark:border-gray-600 even:bg-gray-100 even:dark:bg-gray-600/20;
thead {
@apply hx:border-b hx:border-gray-200 hx:dark:border-neutral-800;
}
tbody tr {
@apply hx:m-0 hx:border-b hx:border-gray-100 hx:dark:border-neutral-800/50;
}
th {
@apply m-0 border border-gray-300 px-4 py-2 font-semibold dark:border-gray-600;
@apply hx:m-0 hx:p-2 hx:font-semibold hx:first:pl-0 hx:last:pr-0;
}
td {
@apply m-0 border border-gray-300 px-4 py-2 dark:border-gray-600;
@apply hx:m-0 hx:p-2 hx:first:pl-0 hx:last:pr-0;
}
}
ol {
@apply mt-6 list-decimal first:mt-0 ltr:ml-6 rtl:mr-6;
:where(ol):not(:where([class~=not-prose],[class~=not-prose] *)) {
@apply hx:mt-6 hx:list-decimal hx:first:mt-0 hx:ltr:ml-6 hx:rtl:mr-6;
li {
@apply my-2;
@apply hx:my-2;
}
}
ul {
@apply mt-6 list-disc first:mt-0 ltr:ml-6 rtl:mr-6;
:where(ul):not(:where([class~=not-prose],[class~=not-prose] *)) {
@apply hx:mt-6 hx:list-disc hx:first:mt-0 hx:ltr:ml-6 hx:rtl:mr-6;
li {
@apply my-2;
@apply hx:my-2;
}
}
.not-prose ul, .not-prose ol {
@apply m-0 list-none;
li {
@apply m-0;
}
/* This CSS rule targets the first nested unordered (ul) or ordered (ol) list
inside the list item (li) of any parent ul or ol.
The rule sets the top margin of the selected list to zero. */
:where(ul, ol) > li > :where(ul, ol):not(:where([class~=not-prose],[class~=not-prose] *)) {
@apply hx:mt-0;
}
kbd {
@apply border-black border-opacity-[0.04] bg-opacity-[0.03] bg-black break-words rounded-md border py-0.5 px-[.25em] text-[.9em] dark:border-white/10 dark:bg-white/10;
:where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)) {
@apply hx:border-black/4 hx:bg-black/3 hx:break-words hx:rounded-md hx:border hx:py-0.5 hx:px-[.25em] hx:text-[.9em] hx:dark:border-white/10 hx:dark:bg-white/10;
}
pre:not(.code-block pre).mermaid {
@apply bg-transparent rounded-none dark:bg-transparent;
:where(pre.mermaid):not(:where(.hextra-code-block pre, [class~=not-prose],[class~=not-prose] *)) {
@apply hx:bg-transparent hx:rounded-none hx:dark:bg-transparent;
}
img {
@apply mx-auto my-4 rounded-md;
:where(img):not(:where([class~=not-prose],[class~=not-prose] *)) {
@apply hx:mx-auto hx:my-4 hx:rounded-md;
}
.not-prose img {
@apply m-0 rounded-none;
}
figure {
:where(figure):not(:where([class~=not-prose],[class~=not-prose] *)) {
figcaption {
@apply text-sm text-gray-500 dark:text-gray-400 mt-2 block text-center;
@apply hx:text-sm hx:text-gray-500 hx:dark:text-gray-400 hx:mt-2 hx:block hx:text-center;
}
}
/* Definition list */
:where(dl):not(:where([class~=not-prose],[class~=not-prose] *)) {
dt {
@apply hx:mt-6 hx:font-semibold;
}
dd {
@apply hx:my-2 hx:ps-6;
}
}
/* Horizontal line */
:where(hr):not(:where([class~=not-prose],[class~=not-prose] *)) {
@apply hx:my-10 hx:first:mt-0 hx:last:mb-0 hx:border-gray-200 hx:dark:border-neutral-800;
}
.footnotes {
@apply mt-12 text-sm;
}
}
@apply hx:mt-12 hx:text-sm;
.subheading-anchor {
@apply opacity-0 transition-opacity ltr:ml-1 rtl:mr-1;
span:target + &,
:hover > &,
&:focus {
@apply opacity-100;
}
span + &,
:hover > & {
@apply !no-underline;
}
&:after {
@apply content-['#'] px-1;
@apply text-gray-300 dark:text-neutral-700;
span:target + & {
@apply text-gray-400;
@apply dark:text-neutral-500;
hr {
@apply hx:border-gray-200 hx:dark:border-neutral-800;
}
}
}
article.typesetting-article {
font-size: 17px;
font-feature-settings:
'rlig' 1,
'calt' 1;
h1 {
@apply mt-6 mb-4 text-center;
font-size: 2.5rem;
}
h2 {
@apply border-none;
}
a {
@apply no-underline hover:underline;
}
p {
@apply leading-8;
}
code {
@apply border-none dark:bg-neutral-700;
}
pre code {
@apply dark:bg-transparent;
}
.subheading-anchor + a {
@apply no-underline hover:no-underline after:hidden;
.subheading-anchor {
@apply hx:opacity-0 hx:transition-opacity hx:ltr:ml-1 hx:rtl:mr-1;
span:target + &,
:hover > &,
&:focus {
@apply hx:opacity-100;
}
span + &,
:hover > & {
@apply hx:no-underline!;
}
@apply hx:after:text-gray-300 hx:dark:after:text-neutral-700;
&:after {
@apply hx:content-['#'] hx:px-1;
span:target + & {
@apply hx:text-gray-400;
@apply hx:dark:text-neutral-500;
}
}
}
}
article details > summary {
&::-webkit-details-marker {
@apply hidden;
@apply hx:hidden;
}
&::before {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='h-5 w-5' viewBox='0 0 20 20' fill='currentColor'%3E%3Cpath fill-rule='evenodd' d='M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z' clip-rule='evenodd' /%3E%3C/svg%3E");
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='hx:h-5 hx:w-5' viewBox='0 0 20 20' fill='currentColor'%3E%3Cpath fill-rule='evenodd' d='M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z' clip-rule='evenodd' /%3E%3C/svg%3E");
height: 1.2em;
width: 1.2em;
vertical-align: -4px;
padding: 0 0.6em;
}
}
:lang(fa) ol {
list-style-type: persian;
}

30
assets/css/variables.css Normal file
View File

@@ -0,0 +1,30 @@
/* Hugo template to derive CSS variables from site and page parameters */
/* Do not remove the following comment. It is used by Hugo to render CSS variables.
{{- $pageWidth := .Params.width | default .Site.Params.page.width -}}
{{- $maxPageWidth := cond (eq $pageWidth "wide") "90rem" (cond (eq $pageWidth "full") "100%" "80rem") -}}
{{- $navbarWidth := .Site.Params.navbar.width -}}
{{- $maxNavbarWidth := cond (eq $navbarWidth "wide") "90rem" (cond (eq $navbarWidth "full") "100%" "80rem") -}}
{{- $footerWidth := .Site.Params.footer.width -}}
{{- $maxFooterWidth := cond (eq $footerWidth "wide") "90rem" (cond (eq $footerWidth "full") "100%" "80rem") -}}
*/
:root {
--hextra-max-page-width: {{ $maxPageWidth }};
--hextra-max-navbar-width: {{ $maxNavbarWidth }};
--hextra-max-footer-width: {{ $maxFooterWidth }};
}
.hextra-max-page-width {
max-width: var(--hextra-max-page-width);
}
.hextra-max-navbar-width {
max-width: var(--hextra-max-navbar-width);
}
.hextra-max-footer-width {
max-width: var(--hextra-max-footer-width);
}

View File

@@ -5,9 +5,9 @@ document.addEventListener("DOMContentLoaded", function () {
if (backToTop) {
document.addEventListener("scroll", (e) => {
if (window.scrollY > 300) {
backToTop.classList.remove("opacity-0");
backToTop.classList.remove("hx:opacity-0");
} else {
backToTop.classList.add("opacity-0");
backToTop.classList.add("hx:opacity-0");
}
});
}

View File

@@ -25,16 +25,16 @@ document.addEventListener('DOMContentLoaded', function () {
return svg;
}
document.querySelectorAll('.code-copy-btn').forEach(function (button) {
document.querySelectorAll('.hextra-code-copy-btn').forEach(function (button) {
// Add copy and success icons
button.querySelector('.copy-icon')?.appendChild(getCopyIcon());
button.querySelector('.success-icon')?.appendChild(getSuccessIcon());
button.querySelector('.hextra-copy-icon')?.appendChild(getCopyIcon());
button.querySelector('.hextra-success-icon')?.appendChild(getSuccessIcon());
// Add click event listener for copy button
button.addEventListener('click', function (e) {
e.preventDefault();
const targetId = button.getAttribute('data-clipboard-target');
const target = document.querySelector(targetId);
// Get the code target
const target = button.parentElement.previousElementSibling;
let codeElement;
if (target.tagName === 'CODE') {
codeElement = target;
@@ -44,14 +44,17 @@ document.addEventListener('DOMContentLoaded', function () {
codeElement = codeElements[codeElements.length - 1];
}
if (codeElement) {
let code = codeElement.innerText;
// Replace double newlines with single newlines in the innerText
// as each line inside <span> has trailing newline '\n'
const code = codeElement.innerText.replace(/\n\n/g, '\n');
if ("lang" in codeElement.dataset) {
code = code.replace(/\n\n/g, '\n');
}
navigator.clipboard.writeText(code).then(function () {
button.classList.add('copied');
setTimeout(function () {
button.classList.remove('copied');
}, 500);
}, 1000);
}).catch(function (err) {
console.error('Failed to copy text: ', err);
});

22
assets/js/favicon.js Normal file
View File

@@ -0,0 +1,22 @@
// {{ $faviconDarkExists := fileExists (path.Join "static" "favicon-dark.svg") }}
(function () {
const faviconEl = document.getElementById("favicon-svg");
const faviconDarkExists = "{{ $faviconDarkExists }}" === "true";
if (faviconEl && faviconDarkExists) {
const lightFavicon = '{{ "favicon.svg" | relURL }}';
const darkFavicon = '{{ "favicon-dark.svg" | relURL }}';
const darkModeQuery = window.matchMedia("(prefers-color-scheme: dark)");
function updateFavicon(e) {
faviconEl.href = e.matches ? darkFavicon : lightFavicon;
}
// Set favicon on load
updateFavicon(darkModeQuery);
// Listen for system preference changes
darkModeQuery.addEventListener("change", updateFavicon);
}
})();

View File

@@ -3,10 +3,10 @@
// Change shortcut key to cmd+k on Mac, iPad or iPhone.
document.addEventListener("DOMContentLoaded", function () {
if (/iPad|iPhone|Macintosh/.test(navigator.userAgent)) {
// select the kbd element under the .search-wrapper class
const keys = document.querySelectorAll(".search-wrapper kbd");
// select the kbd element under the .hextra-search-wrapper class
const keys = document.querySelectorAll(".hextra-search-wrapper kbd");
keys.forEach(key => {
key.innerHTML = '<span class="text-xs">⌘</span>K';
key.innerHTML = '<span class="hx:text-xs">⌘</span>K';
});
}
});
@@ -22,21 +22,35 @@ document.addEventListener("DOMContentLoaded", function () {
(function () {
const searchDataURL = '{{ $searchData.RelPermalink }}';
const inputElements = document.querySelectorAll('.search-input');
const inputElements = document.querySelectorAll('.hextra-search-input');
for (const el of inputElements) {
el.addEventListener('focus', init);
el.addEventListener('keyup', search);
el.addEventListener('keydown', handleKeyDown);
el.addEventListener('input', handleInputChange);
}
const shortcutElements = document.querySelectorAll('.hextra-search-wrapper kbd');
function setShortcutElementsOpacity(opacity) {
shortcutElements.forEach(el => {
el.style.opacity = opacity;
});
}
function handleInputChange(e) {
const opacity = e.target.value.length > 0 ? 0 : 100;
setShortcutElementsOpacity(opacity);
}
// Get the search wrapper, input, and results elements.
function getActiveSearchElement() {
const inputs = Array.from(document.querySelectorAll('.search-wrapper')).filter(el => el.clientHeight > 0);
const inputs = Array.from(document.querySelectorAll('.hextra-search-wrapper')).filter(el => el.clientHeight > 0);
if (inputs.length === 1) {
return {
wrapper: inputs[0],
inputElement: inputs[0].querySelector('.search-input'),
resultsElement: inputs[0].querySelector('.search-results')
inputElement: inputs[0].querySelector('.hextra-search-input'),
resultsElement: inputs[0].querySelector('.hextra-search-results')
};
}
return undefined;
@@ -79,6 +93,7 @@ document.addEventListener("DOMContentLoaded", function () {
e.target !== resultsElement &&
!resultsElement.contains(e.target)
) {
setShortcutElementsOpacity(100);
hideSearchResults();
}
});
@@ -88,7 +103,7 @@ document.addEventListener("DOMContentLoaded", function () {
const { resultsElement } = getActiveSearchElement();
if (!resultsElement) return { result: undefined, index: -1 };
const result = resultsElement.querySelector('.active');
const result = resultsElement.querySelector('.hextra-search-active');
if (!result) return { result: undefined, index: -1 };
const index = parseInt(result.dataset.index, 10);
@@ -101,10 +116,10 @@ document.addEventListener("DOMContentLoaded", function () {
if (!resultsElement) return;
const { result: activeResult } = getActiveResult();
activeResult && activeResult.classList.remove('active');
activeResult && activeResult.classList.remove('hextra-search-active');
const result = resultsElement.querySelector(`[data-index="${index}"]`);
if (result) {
result.classList.add('active');
result.classList.add('hextra-search-active');
result.focus();
}
}
@@ -128,7 +143,7 @@ document.addEventListener("DOMContentLoaded", function () {
function hideSearchResults() {
const { resultsElement } = getActiveSearchElement();
if (!resultsElement) return;
resultsElement.classList.add('hidden');
resultsElement.classList.add('hx:hidden');
}
// Handle keyboard events.
@@ -157,6 +172,10 @@ document.addEventListener("DOMContentLoaded", function () {
case 'Escape':
e.preventDefault();
hideSearchResults();
// Clear the input when pressing escape
inputElement.value = '';
inputElement.dispatchEvent(new Event('input'));
// Remove focus from the input
inputElement.blur();
break;
}
@@ -170,26 +189,42 @@ document.addEventListener("DOMContentLoaded", function () {
}
}
// Preload the search index.
/**
* Preloads the search index by fetching data and adding it to the FlexSearch index.
* @returns {Promise<void>} A promise that resolves when the index is preloaded.
*/
async function preloadIndex() {
const tokenize = '{{- site.Params.search.flexsearch.tokenize | default "forward" -}}';
// https://github.com/TryGhost/Ghost/pull/21148
const regex = new RegExp(
`[\u{4E00}-\u{9FFF}\u{3040}-\u{309F}\u{30A0}-\u{30FF}\u{AC00}-\u{D7A3}\u{3400}-\u{4DBF}\u{20000}-\u{2A6DF}\u{2A700}-\u{2B73F}\u{2B740}-\u{2B81F}\u{2B820}-\u{2CEAF}\u{2CEB0}-\u{2EBEF}\u{30000}-\u{3134F}\u{31350}-\u{323AF}\u{2EBF0}-\u{2EE5F}\u{F900}-\u{FAFF}\u{2F800}-\u{2FA1F}]|[0-9A-Za-zа\u00C0-\u017F\u0400-\u04FF\u0600-\u06FF\u0980-\u09FF\u1E00-\u1EFF\u0590-\u05FF]+`,
'mug'
);
const encode = (str) => { return ('' + str).toLowerCase().match(regex) ?? []; }
window.pageIndex = new FlexSearch.Document({
tokenize: 'forward',
tokenize,
encode,
cache: 100,
document: {
id: 'id',
store: ['title'],
store: ['title', 'crumb'],
index: "content"
}
});
window.sectionIndex = new FlexSearch.Document({
tokenize: 'forward',
tokenize,
encode,
cache: 100,
document: {
id: 'id',
store: ['title', 'content', 'url', 'display'],
store: ['title', 'content', 'url', 'display', 'crumb'],
index: "content",
tag: 'pageId'
tag: [{
field: "pageId"
}]
}
});
@@ -199,6 +234,30 @@ document.addEventListener("DOMContentLoaded", function () {
for (const route in data) {
let pageContent = '';
++pageId;
const urlParts = route.split('/').filter(x => x != "" && !x.startsWith('#'));
let crumb = '';
let searchUrl = '/';
for (let i = 0; i < urlParts.length; i++) {
const urlPart = urlParts[i];
searchUrl += urlPart + '/'
const crumbData = data[searchUrl];
if (!crumbData) {
console.warn('Excluded page', searchUrl, '- will not be included for search result breadcrumb for', route);
continue;
}
let title = data[searchUrl].title;
if (title == "_index") {
title = urlPart.split("-").map(x => x).join(" ");
}
crumb += title;
if (i < urlParts.length - 1) {
crumb += ' > ';
}
}
for (const heading in data[route].data) {
const [hash, text] = heading.split('#');
@@ -212,6 +271,7 @@ document.addEventListener("DOMContentLoaded", function () {
id: url,
url,
title,
crumb,
pageId: `page_${pageId}`,
content: title,
...(paragraphs[0] && { display: paragraphs[0] })
@@ -222,6 +282,7 @@ document.addEventListener("DOMContentLoaded", function () {
id: `${url}_${i}`,
url,
title,
crumb,
pageId: `page_${pageId}`,
content: paragraphs[i]
});
@@ -233,12 +294,17 @@ document.addEventListener("DOMContentLoaded", function () {
window.pageIndex.add({
id: pageId,
title: data[route].title,
crumb,
content: pageContent
});
}
}
/**
* Performs a search based on the provided query and displays the results.
* @param {Event} e - The event object.
*/
function search(e) {
const query = e.target.value;
if (!e.target.value) {
@@ -250,7 +316,7 @@ document.addEventListener("DOMContentLoaded", function () {
while (resultsElement.firstChild) {
resultsElement.removeChild(resultsElement.firstChild);
}
resultsElement.classList.remove('hidden');
resultsElement.classList.remove('hx:hidden');
const pageResults = window.pageIndex.search(query, 5, { enrich: true, suggest: true })[0]?.result || [];
@@ -262,7 +328,7 @@ document.addEventListener("DOMContentLoaded", function () {
pageTitleMatches[i] = 0;
// Show the top 5 results for each page
const sectionResults = window.sectionIndex.search(query, 5, { enrich: true, suggest: true, tag: `page_${result.id}` })[0]?.result || [];
const sectionResults = window.sectionIndex.search(query, 5, { enrich: true, suggest: true, tag: { 'pageId': `page_${result.id}` } })[0]?.result || [];
let isFirstItemOfPage = true
const occurred = {}
@@ -281,7 +347,7 @@ document.addEventListener("DOMContentLoaded", function () {
_page_rk: i,
_section_rk: j,
route: url,
prefix: isFirstItemOfPage ? result.doc.title : undefined,
prefix: isFirstItemOfPage ? result.doc.crumb : undefined,
children: { title, content }
})
isFirstItemOfPage = false
@@ -307,12 +373,18 @@ document.addEventListener("DOMContentLoaded", function () {
displayResults(sortedResults, query);
}
/**
* Displays the search results on the page.
*
* @param {Array} results - The array of search results.
* @param {string} query - The search query.
*/
function displayResults(results, query) {
const { resultsElement } = getActiveSearchElement();
if (!resultsElement) return;
if (!results.length) {
resultsElement.innerHTML = `<span class="no-result">{{ $noResultsFound | safeHTML }}</span>`;
resultsElement.innerHTML = `<span class="hextra-search-no-result">{{ $noResultsFound | safeHTML }}</span>`;
return;
}
@@ -346,14 +418,14 @@ document.addEventListener("DOMContentLoaded", function () {
const result = results[i];
if (result.prefix) {
fragment.appendChild(createElement(`
<div class="prefix">${result.prefix}</div>`));
<div class="hextra-search-prefix">${result.prefix}</div>`));
}
let li = createElement(`
let li = createElement(`
<li>
<a data-index="${i}" href="${result.route}" class=${i === 0 ? "active" : ""}>
<div class="title">`+ highlightMatches(result.children.title, query) + `</div>` +
<a data-index="${i}" href="${result.route}" class=${i === 0 ? "hextra-search-active" : ""}>
<div class="hextra-search-title">`+ highlightMatches(result.children.title, query) + `</div>` +
(result.children.content ?
`<div class="excerpt">` + highlightMatches(result.children.content, query) + `</div>` : '') + `
`<div class="hextra-search-excerpt">` + highlightMatches(result.children.content, query) + `</div>` : '') + `
</a>
</li>`);
li.addEventListener('mousemove', handleMouseMove);

View File

@@ -1,11 +1,11 @@
(function () {
const languageSwitchers = document.querySelectorAll('.language-switcher');
const languageSwitchers = document.querySelectorAll('.hextra-language-switcher');
languageSwitchers.forEach((switcher) => {
switcher.addEventListener('click', (e) => {
e.preventDefault();
switcher.dataset.state = switcher.dataset.state === 'open' ? 'closed' : 'open';
const optionsElement = switcher.nextElementSibling;
optionsElement.classList.toggle('hidden');
optionsElement.classList.toggle('hx:hidden');
// Calculate position of language options element
const switcherRect = switcher.getBoundingClientRect();
@@ -17,11 +17,11 @@
// Dismiss language switcher when clicking outside
document.addEventListener('click', (e) => {
if (e.target.closest('.language-switcher') === null) {
if (e.target.closest('.hextra-language-switcher') === null) {
languageSwitchers.forEach((switcher) => {
switcher.dataset.state = 'closed';
const optionsElement = switcher.nextElementSibling;
optionsElement.classList.add('hidden');
optionsElement.classList.add('hx:hidden');
});
}
});

View File

@@ -1,19 +1,40 @@
// Hamburger menu for mobile navigation
const menu = document.querySelector('.hamburger-menu');
document.addEventListener('DOMContentLoaded', function () {
const menu = document.querySelector('.hextra-hamburger-menu');
const sidebarContainer = document.querySelector('.hextra-sidebar-container');
menu.addEventListener('click', (e) => {
e.preventDefault();
const sidebarContainer = document.querySelector('.sidebar-container');
function toggleMenu() {
// Toggle the hamburger menu
menu.querySelector('svg').classList.toggle('open');
// Toggle the hamburger menu
menu.querySelector('svg').classList.toggle('open');
// When the menu is open, we want to show the navigation sidebar
sidebarContainer.classList.toggle('hx:max-md:[transform:translate3d(0,-100%,0)]');
sidebarContainer.classList.toggle('hx:max-md:[transform:translate3d(0,0,0)]');
// When the menu is open, we want to show the navigation sidebar
sidebarContainer.classList.toggle('max-md:[transform:translate3d(0,-100%,0)]');
sidebarContainer.classList.toggle('max-md:[transform:translate3d(0,0,0)]');
// When the menu is open, we want to prevent the body from scrolling
document.body.classList.toggle('hx:overflow-hidden');
document.body.classList.toggle('hx:md:overflow-auto');
}
// When the menu is open, we want to prevent the body from scrolling
document.body.classList.toggle('overflow-hidden');
document.body.classList.toggle('md:overflow-auto');
menu.addEventListener('click', (e) => {
e.preventDefault();
toggleMenu();
});
// Select all anchor tags in the sidebar container
const sidebarLinks = sidebarContainer.querySelectorAll('a');
// Add click event listener to each anchor tag
sidebarLinks.forEach(link => {
link.addEventListener('click', (e) => {
// Check if the href attribute contains a hash symbol (links to a heading)
if (link.getAttribute('href') && link.getAttribute('href').startsWith('#')) {
// Only dismiss overlay on mobile view
if (window.innerWidth < 768) {
toggleMenu();
}
}
});
});
});

62
assets/js/nav-menu.js Normal file
View File

@@ -0,0 +1,62 @@
(function () {
const hiddenClass = "hx:hidden";
const dropdownToggles = document.querySelectorAll(".hextra-nav-menu-toggle");
dropdownToggles.forEach((toggle) => {
toggle.addEventListener("click", (e) => {
e.preventDefault();
e.stopPropagation();
// Close all other dropdowns first
dropdownToggles.forEach((otherToggle) => {
if (otherToggle !== toggle) {
otherToggle.dataset.state = "closed";
const otherMenuItems = otherToggle.nextElementSibling;
otherMenuItems.classList.add(hiddenClass);
}
});
// Toggle current dropdown
const isOpen = toggle.dataset.state === "open";
toggle.dataset.state = isOpen ? "closed" : "open";
const menuItemsElement = toggle.nextElementSibling;
if (!isOpen) {
// Position dropdown centered with toggle
menuItemsElement.style.position = "absolute";
menuItemsElement.style.top = "100%";
menuItemsElement.style.left = "50%";
menuItemsElement.style.transform = "translateX(-50%)";
menuItemsElement.style.zIndex = "1000";
// Show dropdown
menuItemsElement.classList.remove(hiddenClass);
} else {
// Hide dropdown
menuItemsElement.classList.add(hiddenClass);
}
});
});
// Dismiss dropdown when clicking outside
document.addEventListener("click", (e) => {
if (e.target.closest(".hextra-nav-menu-toggle") === null) {
dropdownToggles.forEach((toggle) => {
toggle.dataset.state = "closed";
const menuItemsElement = toggle.nextElementSibling;
menuItemsElement.classList.add(hiddenClass);
});
}
});
// Close dropdowns on escape key
document.addEventListener("keydown", (e) => {
if (e.key === "Escape") {
dropdownToggles.forEach((toggle) => {
toggle.dataset.state = "closed";
const menuItemsElement = toggle.nextElementSibling;
menuItemsElement.classList.add(hiddenClass);
});
}
});
})();

View File

@@ -1,4 +1,9 @@
document.addEventListener("DOMContentLoaded", function () {
scrollToActiveItem();
enableCollapsibles();
});
function enableCollapsibles() {
const buttons = document.querySelectorAll(".hextra-sidebar-collapsible-button");
buttons.forEach(function (button) {
button.addEventListener("click", function (e) {
@@ -9,4 +14,23 @@ document.addEventListener("DOMContentLoaded", function () {
}
});
});
});
}
function scrollToActiveItem() {
const sidebarScrollbar = document.querySelector("aside.hextra-sidebar-container > .hextra-scrollbar");
const activeItems = document.querySelectorAll(".hextra-sidebar-active-item");
const visibleActiveItem = Array.from(activeItems).find(function (activeItem) {
return activeItem.getBoundingClientRect().height > 0;
});
if (!visibleActiveItem) {
return;
}
const yOffset = visibleActiveItem.clientHeight;
const yDistance = visibleActiveItem.getBoundingClientRect().top - sidebarScrollbar.getBoundingClientRect().top;
sidebarScrollbar.scrollTo({
behavior: "instant",
top: yDistance - yOffset
});
}

View File

@@ -1,20 +1,57 @@
document.querySelectorAll('.tabs-toggle').forEach(function (button) {
button.addEventListener('click', function (e) {
// set parent tabs to unselected
const tabs = Array.from(e.target.parentElement.querySelectorAll('.tabs-toggle'));
tabs.map(tab => tab.dataset.state = '');
// set current tab to selected
e.target.dataset.state = 'selected';
// set all panels to unselected
const panelsContainer = e.target.parentElement.nextElementSibling;
Array.from(panelsContainer.children).forEach(function (panel) {
panel.dataset.state = '';
(function () {
function updateGroup(container, index) {
const tabs = Array.from(container.querySelectorAll('.hextra-tabs-toggle'));
tabs.forEach((tab, i) => {
tab.dataset.state = i === index ? 'selected' : '';
if (i === index) {
tab.setAttribute('aria-selected', 'true');
tab.tabIndex = 0;
} else {
tab.removeAttribute('aria-selected');
tab.removeAttribute('tabindex');
}
});
const panelsContainer = container.parentElement.nextElementSibling;
if (!panelsContainer) return;
Array.from(panelsContainer.children).forEach((panel, i) => {
panel.dataset.state = i === index ? 'selected' : '';
if (i === index) {
panel.tabIndex = 0;
} else {
panel.removeAttribute('tabindex');
}
});
}
const panelId = e.target.getAttribute('aria-controls');
const panel = panelsContainer.querySelector(`#${panelId}`);
panel.dataset.state = 'selected';
const syncGroups = document.querySelectorAll('[data-tab-group]');
syncGroups.forEach((group) => {
const key = encodeURIComponent(group.dataset.tabGroup);
const saved = localStorage.getItem('hextra-tab-' + key);
if (saved !== null) {
updateGroup(group, parseInt(saved, 10));
}
});
});
document.querySelectorAll('.hextra-tabs-toggle').forEach((button) => {
button.addEventListener('click', function (e) {
const container = e.target.parentElement;
const index = Array.from(container.querySelectorAll('.hextra-tabs-toggle')).indexOf(
e.target
);
if (container.dataset.tabGroup) {
// Sync behavior: update all tab groups with the same name
const tabGroupValue = container.dataset.tabGroup;
const key = encodeURIComponent(tabGroupValue);
document
.querySelectorAll('[data-tab-group="' + tabGroupValue + '"]')
.forEach((grp) => updateGroup(grp, index));
localStorage.setItem('hextra-tab-' + key, index.toString());
} else {
// Non-sync behavior: update only this specific tab group
updateGroup(container, index);
}
});
});
})();

View File

@@ -2,7 +2,7 @@
(function () {
const defaultTheme = '{{ site.Params.theme.default | default `system`}}'
const themeToggleButtons = document.querySelectorAll(".theme-toggle");
const themeToggleButtons = document.querySelectorAll(".hextra-theme-toggle");
// Change the icons of the buttons based on previous settings or system theme
if (

68
assets/js/toc-scroll.js Normal file
View File

@@ -0,0 +1,68 @@
/**
* TOC Scroll - Highlights active TOC links based on visible headings
*
* Uses Intersection Observer to track heading visibility and applies
* 'hextra-toc-active' class to corresponding TOC links. Selects the
* topmost heading when multiple are visible.
*
* Requires: .hextra-toc element, matching heading IDs, toc.css styles
*/
document.addEventListener("DOMContentLoaded", function () {
const toc = document.querySelector(".hextra-toc");
if (!toc) return;
const tocLinks = toc.querySelectorAll('a[href^="#"]');
if (tocLinks.length === 0) return;
const headingIds = Array.from(tocLinks).map((link) => link.getAttribute("href").substring(1));
const headings = headingIds.map((id) => document.getElementById(id)).filter(Boolean);
if (headings.length === 0) return;
let currentActiveLink = null;
// Create intersection observer
const observer = new IntersectionObserver(
(entries) => {
const visibleHeadings = entries.filter((entry) => entry.isIntersecting).map((entry) => entry.target);
if (visibleHeadings.length === 0) return;
// Find the heading closest to the top of the viewport
const topMostHeading = visibleHeadings.reduce((closest, heading) => {
const headingTop = heading.getBoundingClientRect().top;
const closestTop = closest.getBoundingClientRect().top;
return Math.abs(headingTop) < Math.abs(closestTop) ? heading : closest;
});
const targetId = topMostHeading.id;
const targetLink = toc.querySelector(`a[href="#${targetId}"]`);
if (targetLink && targetLink !== currentActiveLink) {
// Remove active class from previous link
if (currentActiveLink) {
currentActiveLink.classList.remove("hextra-toc-active");
}
// Add active class to current link
targetLink.classList.add("hextra-toc-active");
currentActiveLink = targetLink;
}
},
{
rootMargin: "-20px 0px -80% 0px", // Adjust sensitivity
threshold: [0, 0.1, 0.5, 1],
}
);
// Observe all headings
headings.forEach((heading) => observer.observe(heading));
// Handle edge case: if no headings are visible on initial load
setTimeout(() => {
if (!currentActiveLink && tocLinks.length > 0) {
tocLinks[0].classList.add("hextra-toc-active");
currentActiveLink = tocLinks[0];
}
}, 100);
});

View File

@@ -1,39 +0,0 @@
/**
* Skipped minification because the original files appears to be already minified.
* Original file: /npm/flexsearch@0.7.31/dist/flexsearch.bundle.js
*
* Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
*/
/**!
* FlexSearch.js v0.7.31 (Bundle)
* Copyright 2018-2022 Nextapps GmbH
* Author: Thomas Wilkerling
* Licence: Apache-2.0
* https://github.com/nextapps-de/flexsearch
*/
(function _f(self){'use strict';try{if(module)self=module}catch(e){}self._factory=_f;var t;function u(a){return"undefined"!==typeof a?a:!0}function aa(a){const b=Array(a);for(let c=0;c<a;c++)b[c]=v();return b}function v(){return Object.create(null)}function ba(a,b){return b.length-a.length}function x(a){return"string"===typeof a}function C(a){return"object"===typeof a}function D(a){return"function"===typeof a};function ca(a,b){var c=da;if(a&&(b&&(a=E(a,b)),this.H&&(a=E(a,this.H)),this.J&&1<a.length&&(a=E(a,this.J)),c||""===c)){a=a.split(c);if(this.filter){b=this.filter;c=a.length;const d=[];for(let e=0,f=0;e<c;e++){const g=a[e];g&&!b[g]&&(d[f++]=g)}a=d}return a}return a}const da=/[\p{Z}\p{S}\p{P}\p{C}]+/u,ea=/[\u0300-\u036f]/g;
function fa(a,b){const c=Object.keys(a),d=c.length,e=[];let f="",g=0;for(let h=0,k,m;h<d;h++)k=c[h],(m=a[k])?(e[g++]=F(b?"(?!\\b)"+k+"(\\b|_)":k),e[g++]=m):f+=(f?"|":"")+k;f&&(e[g++]=F(b?"(?!\\b)("+f+")(\\b|_)":"("+f+")"),e[g]="");return e}function E(a,b){for(let c=0,d=b.length;c<d&&(a=a.replace(b[c],b[c+1]),a);c+=2);return a}function F(a){return new RegExp(a,"g")}function ha(a){let b="",c="";for(let d=0,e=a.length,f;d<e;d++)(f=a[d])!==c&&(b+=c=f);return b};var ja={encode:ia,F:!1,G:""};function ia(a){return ca.call(this,(""+a).toLowerCase(),!1)};const ka={},G={};function la(a){I(a,"add");I(a,"append");I(a,"search");I(a,"update");I(a,"remove")}function I(a,b){a[b+"Async"]=function(){const c=this,d=arguments;var e=d[d.length-1];let f;D(e)&&(f=e,delete d[d.length-1]);e=new Promise(function(g){setTimeout(function(){c.async=!0;const h=c[b].apply(c,d);c.async=!1;g(h)})});return f?(e.then(f),this):e}};function ma(a,b,c,d){const e=a.length;let f=[],g,h,k=0;d&&(d=[]);for(let m=e-1;0<=m;m--){const n=a[m],w=n.length,q=v();let r=!g;for(let l=0;l<w;l++){const p=n[l],z=p.length;if(z)for(let B=0,A,y;B<z;B++)if(y=p[B],g){if(g[y]){if(!m)if(c)c--;else if(f[k++]=y,k===b)return f;if(m||d)q[y]=1;r=!0}if(d&&(A=(h[y]||0)+1,h[y]=A,A<e)){const H=d[A-2]||(d[A-2]=[]);H[H.length]=y}}else q[y]=1}if(d)g||(h=q);else if(!r)return[];g=q}if(d)for(let m=d.length-1,n,w;0<=m;m--){n=d[m];w=n.length;for(let q=0,r;q<w;q++)if(r=
n[q],!g[r]){if(c)c--;else if(f[k++]=r,k===b)return f;g[r]=1}}return f}function na(a,b){const c=v(),d=v(),e=[];for(let f=0;f<a.length;f++)c[a[f]]=1;for(let f=0,g;f<b.length;f++){g=b[f];for(let h=0,k;h<g.length;h++)k=g[h],c[k]&&!d[k]&&(d[k]=1,e[e.length]=k)}return e};function J(a){this.l=!0!==a&&a;this.cache=v();this.h=[]}function oa(a,b,c){C(a)&&(a=a.query);let d=this.cache.get(a);d||(d=this.search(a,b,c),this.cache.set(a,d));return d}J.prototype.set=function(a,b){if(!this.cache[a]){var c=this.h.length;c===this.l?delete this.cache[this.h[c-1]]:c++;for(--c;0<c;c--)this.h[c]=this.h[c-1];this.h[0]=a}this.cache[a]=b};J.prototype.get=function(a){const b=this.cache[a];if(this.l&&b&&(a=this.h.indexOf(a))){const c=this.h[a-1];this.h[a-1]=this.h[a];this.h[a]=c}return b};const qa={memory:{charset:"latin:extra",D:3,B:4,m:!1},performance:{D:3,B:3,s:!1,context:{depth:2,D:1}},match:{charset:"latin:extra",G:"reverse"},score:{charset:"latin:advanced",D:20,B:3,context:{depth:3,D:9}},"default":{}};function ra(a,b,c,d,e,f,g){setTimeout(function(){const h=a(c?c+"."+d:d,JSON.stringify(g));h&&h.then?h.then(function(){b.export(a,b,c,e,f+1)}):b.export(a,b,c,e,f+1)})};function K(a,b){if(!(this instanceof K))return new K(a);var c;if(a){x(a)?a=qa[a]:(c=a.preset)&&(a=Object.assign({},c[c],a));c=a.charset;var d=a.lang;x(c)&&(-1===c.indexOf(":")&&(c+=":default"),c=G[c]);x(d)&&(d=ka[d])}else a={};let e,f,g=a.context||{};this.encode=a.encode||c&&c.encode||ia;this.register=b||v();this.D=e=a.resolution||9;this.G=b=c&&c.G||a.tokenize||"strict";this.depth="strict"===b&&g.depth;this.l=u(g.bidirectional);this.s=f=u(a.optimize);this.m=u(a.fastupdate);this.B=a.minlength||1;this.C=
a.boost;this.map=f?aa(e):v();this.A=e=g.resolution||1;this.h=f?aa(e):v();this.F=c&&c.F||a.rtl;this.H=(b=a.matcher||d&&d.H)&&fa(b,!1);this.J=(b=a.stemmer||d&&d.J)&&fa(b,!0);if(c=b=a.filter||d&&d.filter){c=b;d=v();for(let h=0,k=c.length;h<k;h++)d[c[h]]=1;c=d}this.filter=c;this.cache=(b=a.cache)&&new J(b)}t=K.prototype;t.append=function(a,b){return this.add(a,b,!0)};
t.add=function(a,b,c,d){if(b&&(a||0===a)){if(!d&&!c&&this.register[a])return this.update(a,b);b=this.encode(b);if(d=b.length){const m=v(),n=v(),w=this.depth,q=this.D;for(let r=0;r<d;r++){let l=b[this.F?d-1-r:r];var e=l.length;if(l&&e>=this.B&&(w||!n[l])){var f=L(q,d,r),g="";switch(this.G){case "full":if(2<e){for(f=0;f<e;f++)for(var h=e;h>f;h--)if(h-f>=this.B){var k=L(q,d,r,e,f);g=l.substring(f,h);M(this,n,g,k,a,c)}break}case "reverse":if(1<e){for(h=e-1;0<h;h--)g=l[h]+g,g.length>=this.B&&M(this,n,
g,L(q,d,r,e,h),a,c);g=""}case "forward":if(1<e){for(h=0;h<e;h++)g+=l[h],g.length>=this.B&&M(this,n,g,f,a,c);break}default:if(this.C&&(f=Math.min(f/this.C(b,l,r)|0,q-1)),M(this,n,l,f,a,c),w&&1<d&&r<d-1)for(e=v(),g=this.A,f=l,h=Math.min(w+1,d-r),e[f]=1,k=1;k<h;k++)if((l=b[this.F?d-1-r-k:r+k])&&l.length>=this.B&&!e[l]){e[l]=1;const p=this.l&&l>f;M(this,m,p?f:l,L(g+(d/2>g?0:1),d,r,h-1,k-1),a,c,p?l:f)}}}}this.m||(this.register[a]=1)}}return this};
function L(a,b,c,d,e){return c&&1<a?b+(d||0)<=a?c+(e||0):(a-1)/(b+(d||0))*(c+(e||0))+1|0:0}function M(a,b,c,d,e,f,g){let h=g?a.h:a.map;if(!b[c]||g&&!b[c][g])a.s&&(h=h[d]),g?(b=b[c]||(b[c]=v()),b[g]=1,h=h[g]||(h[g]=v())):b[c]=1,h=h[c]||(h[c]=[]),a.s||(h=h[d]||(h[d]=[])),f&&h.includes(e)||(h[h.length]=e,a.m&&(a=a.register[e]||(a.register[e]=[]),a[a.length]=h))}
t.search=function(a,b,c){c||(!b&&C(a)?(c=a,a=c.query):C(b)&&(c=b));let d=[],e;let f,g=0;if(c){a=c.query||a;b=c.limit;g=c.offset||0;var h=c.context;f=c.suggest}if(a&&(a=this.encode(""+a),e=a.length,1<e)){c=v();var k=[];for(let n=0,w=0,q;n<e;n++)if((q=a[n])&&q.length>=this.B&&!c[q])if(this.s||f||this.map[q])k[w++]=q,c[q]=1;else return d;a=k;e=a.length}if(!e)return d;b||(b=100);h=this.depth&&1<e&&!1!==h;c=0;let m;h?(m=a[0],c=1):1<e&&a.sort(ba);for(let n,w;c<e;c++){w=a[c];h?(n=sa(this,d,f,b,g,2===e,w,
m),f&&!1===n&&d.length||(m=w)):n=sa(this,d,f,b,g,1===e,w);if(n)return n;if(f&&c===e-1){k=d.length;if(!k){if(h){h=0;c=-1;continue}return d}if(1===k)return ta(d[0],b,g)}}return ma(d,b,g,f)};
function sa(a,b,c,d,e,f,g,h){let k=[],m=h?a.h:a.map;a.s||(m=ua(m,g,h,a.l));if(m){let n=0;const w=Math.min(m.length,h?a.A:a.D);for(let q=0,r=0,l,p;q<w;q++)if(l=m[q])if(a.s&&(l=ua(l,g,h,a.l)),e&&l&&f&&(p=l.length,p<=e?(e-=p,l=null):(l=l.slice(e),e=0)),l&&(k[n++]=l,f&&(r+=l.length,r>=d)))break;if(n){if(f)return ta(k,d,0);b[b.length]=k;return}}return!c&&k}function ta(a,b,c){a=1===a.length?a[0]:[].concat.apply([],a);return c||a.length>b?a.slice(c,c+b):a}
function ua(a,b,c,d){c?(d=d&&b>c,a=(a=a[d?b:c])&&a[d?c:b]):a=a[b];return a}t.contain=function(a){return!!this.register[a]};t.update=function(a,b){return this.remove(a).add(a,b)};
t.remove=function(a,b){const c=this.register[a];if(c){if(this.m)for(let d=0,e;d<c.length;d++)e=c[d],e.splice(e.indexOf(a),1);else N(this.map,a,this.D,this.s),this.depth&&N(this.h,a,this.A,this.s);b||delete this.register[a];if(this.cache){b=this.cache;for(let d=0,e,f;d<b.h.length;d++)f=b.h[d],e=b.cache[f],e.includes(a)&&(b.h.splice(d--,1),delete b.cache[f])}}return this};
function N(a,b,c,d,e){let f=0;if(a.constructor===Array)if(e)b=a.indexOf(b),-1!==b?1<a.length&&(a.splice(b,1),f++):f++;else{e=Math.min(a.length,c);for(let g=0,h;g<e;g++)if(h=a[g])f=N(h,b,c,d,e),d||f||delete a[g]}else for(let g in a)(f=N(a[g],b,c,d,e))||delete a[g];return f}t.searchCache=oa;
t.export=function(a,b,c,d,e){let f,g;switch(e||(e=0)){case 0:f="reg";if(this.m){g=v();for(let h in this.register)g[h]=1}else g=this.register;break;case 1:f="cfg";g={doc:0,opt:this.s?1:0};break;case 2:f="map";g=this.map;break;case 3:f="ctx";g=this.h;break;default:return}ra(a,b||this,c,f,d,e,g);return!0};t.import=function(a,b){if(b)switch(x(b)&&(b=JSON.parse(b)),a){case "cfg":this.s=!!b.opt;break;case "reg":this.m=!1;this.register=b;break;case "map":this.map=b;break;case "ctx":this.h=b}};la(K.prototype);function va(a){a=a.data;var b=self._index;const c=a.args;var d=a.task;switch(d){case "init":d=a.options||{};a=a.factory;b=d.encode;d.cache=!1;b&&0===b.indexOf("function")&&(d.encode=Function("return "+b)());a?(Function("return "+a)()(self),self._index=new self.FlexSearch.Index(d),delete self.FlexSearch):self._index=new K(d);break;default:a=a.id,b=b[d].apply(b,c),postMessage("search"===d?{id:a,msg:b}:{id:a})}};let wa=0;function O(a){if(!(this instanceof O))return new O(a);var b;a?D(b=a.encode)&&(a.encode=b.toString()):a={};(b=(self||window)._factory)&&(b=b.toString());const c="undefined"===typeof window&&self.exports,d=this;this.o=xa(b,c,a.worker);this.h=v();if(this.o){if(c)this.o.on("message",function(e){d.h[e.id](e.msg);delete d.h[e.id]});else this.o.onmessage=function(e){e=e.data;d.h[e.id](e.msg);delete d.h[e.id]};this.o.postMessage({task:"init",factory:b,options:a})}}P("add");P("append");P("search");
P("update");P("remove");function P(a){O.prototype[a]=O.prototype[a+"Async"]=function(){const b=this,c=[].slice.call(arguments);var d=c[c.length-1];let e;D(d)&&(e=d,c.splice(c.length-1,1));d=new Promise(function(f){setTimeout(function(){b.h[++wa]=f;b.o.postMessage({task:a,id:wa,args:c})})});return e?(d.then(e),this):d}}
function xa(a,b,c){let d;try{d=b?eval('new (require("worker_threads")["Worker"])("../dist/node/node.js")'):a?new Worker(URL.createObjectURL(new Blob(["onmessage="+va.toString()],{type:"text/javascript"}))):new Worker(x(c)?c:"worker/worker.js",{type:"module"})}catch(e){}return d};function Q(a){if(!(this instanceof Q))return new Q(a);var b=a.document||a.doc||a,c;this.K=[];this.h=[];this.A=[];this.register=v();this.key=(c=b.key||b.id)&&S(c,this.A)||"id";this.m=u(a.fastupdate);this.C=(c=b.store)&&!0!==c&&[];this.store=c&&v();this.I=(c=b.tag)&&S(c,this.A);this.l=c&&v();this.cache=(c=a.cache)&&new J(c);a.cache=!1;this.o=a.worker;this.async=!1;c=v();let d=b.index||b.field||b;x(d)&&(d=[d]);for(let e=0,f,g;e<d.length;e++)f=d[e],x(f)||(g=f,f=f.field),g=C(g)?Object.assign({},a,g):a,
this.o&&(c[f]=new O(g),c[f].o||(this.o=!1)),this.o||(c[f]=new K(g,this.register)),this.K[e]=S(f,this.A),this.h[e]=f;if(this.C)for(a=b.store,x(a)&&(a=[a]),b=0;b<a.length;b++)this.C[b]=S(a[b],this.A);this.index=c}function S(a,b){const c=a.split(":");let d=0;for(let e=0;e<c.length;e++)a=c[e],0<=a.indexOf("[]")&&(a=a.substring(0,a.length-2))&&(b[d]=!0),a&&(c[d++]=a);d<c.length&&(c.length=d);return 1<d?c:c[0]}function T(a,b){if(x(b))a=a[b];else for(let c=0;a&&c<b.length;c++)a=a[b[c]];return a}
function U(a,b,c,d,e){a=a[e];if(d===c.length-1)b[e]=a;else if(a)if(a.constructor===Array)for(b=b[e]=Array(a.length),e=0;e<a.length;e++)U(a,b,c,d,e);else b=b[e]||(b[e]=v()),e=c[++d],U(a,b,c,d,e)}function V(a,b,c,d,e,f,g,h){if(a=a[g])if(d===b.length-1){if(a.constructor===Array){if(c[d]){for(b=0;b<a.length;b++)e.add(f,a[b],!0,!0);return}a=a.join(" ")}e.add(f,a,h,!0)}else if(a.constructor===Array)for(g=0;g<a.length;g++)V(a,b,c,d,e,f,g,h);else g=b[++d],V(a,b,c,d,e,f,g,h)}t=Q.prototype;
t.add=function(a,b,c){C(a)&&(b=a,a=T(b,this.key));if(b&&(a||0===a)){if(!c&&this.register[a])return this.update(a,b);for(let d=0,e,f;d<this.h.length;d++)f=this.h[d],e=this.K[d],x(e)&&(e=[e]),V(b,e,this.A,0,this.index[f],a,e[0],c);if(this.I){let d=T(b,this.I),e=v();x(d)&&(d=[d]);for(let f=0,g,h;f<d.length;f++)if(g=d[f],!e[g]&&(e[g]=1,h=this.l[g]||(this.l[g]=[]),!c||!h.includes(a)))if(h[h.length]=a,this.m){const k=this.register[a]||(this.register[a]=[]);k[k.length]=h}}if(this.store&&(!c||!this.store[a])){let d;
if(this.C){d=v();for(let e=0,f;e<this.C.length;e++)f=this.C[e],x(f)?d[f]=b[f]:U(b,d,f,0,f[0])}this.store[a]=d||b}}return this};t.append=function(a,b){return this.add(a,b,!0)};t.update=function(a,b){return this.remove(a).add(a,b)};
t.remove=function(a){C(a)&&(a=T(a,this.key));if(this.register[a]){for(var b=0;b<this.h.length&&(this.index[this.h[b]].remove(a,!this.o),!this.m);b++);if(this.I&&!this.m)for(let c in this.l){b=this.l[c];const d=b.indexOf(a);-1!==d&&(1<b.length?b.splice(d,1):delete this.l[c])}this.store&&delete this.store[a];delete this.register[a]}return this};
t.search=function(a,b,c,d){c||(!b&&C(a)?(c=a,a=""):C(b)&&(c=b,b=0));let e=[],f=[],g,h,k,m,n,w,q=0;if(c)if(c.constructor===Array)k=c,c=null;else{a=c.query||a;k=(g=c.pluck)||c.index||c.field;m=c.tag;h=this.store&&c.enrich;n="and"===c.bool;b=c.limit||b||100;w=c.offset||0;if(m&&(x(m)&&(m=[m]),!a)){for(let l=0,p;l<m.length;l++)if(p=ya.call(this,m[l],b,w,h))e[e.length]=p,q++;return q?e:[]}x(k)&&(k=[k])}k||(k=this.h);n=n&&(1<k.length||m&&1<m.length);const r=!d&&(this.o||this.async)&&[];for(let l=0,p,z,B;l<
k.length;l++){let A;z=k[l];x(z)||(A=z,z=A.field,a=A.query||a,b=A.limit||b);if(r)r[l]=this.index[z].searchAsync(a,b,A||c);else{d?p=d[l]:p=this.index[z].search(a,b,A||c);B=p&&p.length;if(m&&B){const y=[];let H=0;n&&(y[0]=[p]);for(let X=0,pa,R;X<m.length;X++)if(pa=m[X],B=(R=this.l[pa])&&R.length)H++,y[y.length]=n?[R]:R;H&&(p=n?ma(y,b||100,w||0):na(p,y),B=p.length)}if(B)f[q]=z,e[q++]=p;else if(n)return[]}}if(r){const l=this;return new Promise(function(p){Promise.all(r).then(function(z){p(l.search(a,b,
c,z))})})}if(!q)return[];if(g&&(!h||!this.store))return e[0];for(let l=0,p;l<f.length;l++){p=e[l];p.length&&h&&(p=za.call(this,p));if(g)return p;e[l]={field:f[l],result:p}}return e};function ya(a,b,c,d){let e=this.l[a],f=e&&e.length-c;if(f&&0<f){if(f>b||c)e=e.slice(c,c+b);d&&(e=za.call(this,e));return{tag:a,result:e}}}function za(a){const b=Array(a.length);for(let c=0,d;c<a.length;c++)d=a[c],b[c]={id:d,doc:this.store[d]};return b}t.contain=function(a){return!!this.register[a]};t.get=function(a){return this.store[a]};
t.set=function(a,b){this.store[a]=b;return this};t.searchCache=oa;t.export=function(a,b,c,d,e){e||(e=0);d||(d=0);if(d<this.h.length){const f=this.h[d],g=this.index[f];b=this;setTimeout(function(){g.export(a,b,e?f:"",d,e++)||(d++,e=1,b.export(a,b,f,d,e))})}else{let f,g;switch(e){case 1:f="tag";g=this.l;break;case 2:f="store";g=this.store;break;default:return}ra(a,this,c,f,d,e,g)}};
t.import=function(a,b){if(b)switch(x(b)&&(b=JSON.parse(b)),a){case "tag":this.l=b;break;case "reg":this.m=!1;this.register=b;for(let d=0,e;d<this.h.length;d++)e=this.index[this.h[d]],e.register=b,e.m=!1;break;case "store":this.store=b;break;default:a=a.split(".");const c=a[0];a=a[1];c&&a&&this.index[c].import(a,b)}};la(Q.prototype);var Ba={encode:Aa,F:!1,G:""};const Ca=[F("[\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5]"),"a",F("[\u00e8\u00e9\u00ea\u00eb]"),"e",F("[\u00ec\u00ed\u00ee\u00ef]"),"i",F("[\u00f2\u00f3\u00f4\u00f5\u00f6\u0151]"),"o",F("[\u00f9\u00fa\u00fb\u00fc\u0171]"),"u",F("[\u00fd\u0177\u00ff]"),"y",F("\u00f1"),"n",F("[\u00e7c]"),"k",F("\u00df"),"s",F(" & ")," and "];function Aa(a){var b=a=""+a;b.normalize&&(b=b.normalize("NFD").replace(ea,""));return ca.call(this,b.toLowerCase(),!a.normalize&&Ca)};var Ea={encode:Da,F:!1,G:"strict"};const Fa=/[^a-z0-9]+/,Ga={b:"p",v:"f",w:"f",z:"s",x:"s","\u00df":"s",d:"t",n:"m",c:"k",g:"k",j:"k",q:"k",i:"e",y:"e",u:"o"};function Da(a){a=Aa.call(this,a).join(" ");const b=[];if(a){const c=a.split(Fa),d=c.length;for(let e=0,f,g=0;e<d;e++)if((a=c[e])&&(!this.filter||!this.filter[a])){f=a[0];let h=Ga[f]||f,k=h;for(let m=1;m<a.length;m++){f=a[m];const n=Ga[f]||f;n&&n!==k&&(h+=n,k=n)}b[g++]=h}}return b};var Ia={encode:Ha,F:!1,G:""};const Ja=[F("ae"),"a",F("oe"),"o",F("sh"),"s",F("th"),"t",F("ph"),"f",F("pf"),"f",F("(?![aeo])h(?![aeo])"),"",F("(?!^[aeo])h(?!^[aeo])"),""];function Ha(a,b){a&&(a=Da.call(this,a).join(" "),2<a.length&&(a=E(a,Ja)),b||(1<a.length&&(a=ha(a)),a&&(a=a.split(" "))));return a||[]};var La={encode:Ka,F:!1,G:""};const Ma=F("(?!\\b)[aeo]");function Ka(a){a&&(a=Ha.call(this,a,!0),1<a.length&&(a=a.replace(Ma,"")),1<a.length&&(a=ha(a)),a&&(a=a.split(" ")));return a||[]};G["latin:default"]=ja;G["latin:simple"]=Ba;G["latin:balance"]=Ea;G["latin:advanced"]=Ia;G["latin:extra"]=La;const W=self;let Y;const Z={Index:K,Document:Q,Worker:O,registerCharset:function(a,b){G[a]=b},registerLanguage:function(a,b){ka[a]=b}};(Y=W.define)&&Y.amd?Y([],function(){return Z}):W.exports?W.exports=Z:W.FlexSearch=Z;}(this));

View File

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

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