├── assets ├── css │ ├── custom.css │ ├── safelist.txt │ ├── components │ │ ├── badge.css │ │ ├── toc.css │ │ ├── hextra │ │ │ └── feature-grid.css │ │ ├── code-copy.css │ │ ├── banner.css │ │ ├── jupyter.css │ │ ├── sidebar.css │ │ ├── scrollbar.css │ │ ├── steps.css │ │ ├── cards.css │ │ ├── navbar.css │ │ └── search.css │ ├── variables.css │ └── highlight.css ├── js │ ├── head │ │ ├── banner.js │ │ └── theme.js │ └── core │ │ ├── back-to-top.js │ │ ├── banner.js │ │ ├── filetree.js │ │ ├── favicon.js │ │ ├── lang.js │ │ ├── sidebar.js │ │ ├── menu.js │ │ ├── switcher-menu.js │ │ ├── theme.js │ │ ├── tabs.js │ │ └── nav-menu.js └── json │ └── search-data.json ├── layouts ├── _partials │ ├── custom │ │ ├── banner.html │ │ ├── footer.html │ │ ├── head-end.html │ │ └── navbar-title.html │ ├── google-analytics.html │ ├── utils │ │ ├── format-date.html │ │ ├── page-width-override.html │ │ ├── page-description.html │ │ ├── icon.html │ │ ├── lang-link.html │ │ ├── title.html │ │ ├── file-path.html │ │ ├── sort-pages.html │ │ └── extract-headings.html │ ├── shortcodes │ │ ├── cards.html │ │ └── callout.html │ ├── components │ │ ├── comments.html │ │ ├── analytics │ │ │ ├── google-analytics.html │ │ │ ├── analytics.html │ │ │ ├── goat-counter.html │ │ │ ├── matomo.html │ │ │ └── umami.html │ │ ├── last-updated.html │ │ ├── codeblock.html │ │ ├── codeblock-copy-button.html │ │ ├── blog-pager.html │ │ └── github-style-alert.html │ ├── tags.html │ ├── scripts.html │ ├── scripts │ │ ├── core.html │ │ ├── mathjax.html │ │ └── search.html │ ├── favicons.html │ ├── banner.html │ ├── breadcrumb.html │ ├── navbar-title.html │ └── search.html ├── _markup │ ├── render-blockquote-regular.html │ ├── render-codeblock-mermaid.html │ ├── render-heading.html │ ├── render-blockquote-alert.html │ ├── render-codeblock.html │ ├── render-passthrough.html │ ├── render-link.html │ └── render-image.html ├── _shortcodes │ ├── cards.html │ ├── steps.html │ ├── filetree │ │ ├── container.html │ │ ├── file.html │ │ └── folder.html │ ├── pdf.html │ ├── hextra │ │ ├── hero-subtitle.html │ │ ├── hero-headline.html │ │ ├── feature-grid.html │ │ ├── hero-section.html │ │ ├── hero-button.html │ │ ├── hero-badge.html │ │ └── feature-card.html │ ├── tab.html │ ├── icon.html │ ├── include.html │ ├── details.html │ ├── tabs.html │ ├── badge.html │ └── callout.html ├── baseof.html ├── hextra-home.html ├── wide.html ├── home.html ├── list.html ├── docs │ ├── list.html │ └── single.html ├── single.html ├── llms.txt ├── 404.html ├── taxonomy.html ├── term.html ├── list.rss.xml └── blog │ └── list.html ├── docs ├── hugo.work ├── assets │ └── images │ │ └── space.jpg ├── go.mod ├── static │ ├── images │ │ ├── hextra-doc.webp │ │ ├── hextra-search.webp │ │ ├── hextra-markdown.webp │ │ └── card-image-unprocessed.jpg │ └── favicon-dark.svg ├── i18n │ ├── zh-cn.yaml │ ├── ja.yaml │ └── fa.yaml ├── layouts │ ├── _partials │ │ └── custom │ │ │ └── head-end.html │ └── _shortcodes │ │ └── new-feature.html └── content │ ├── blog │ ├── _index.ja.md │ ├── _index.zh-cn.md │ ├── _index.fa.md │ ├── _index.md │ └── markdown.zh-cn.md │ ├── docs │ ├── advanced │ │ ├── _index.zh-cn.md │ │ ├── _index.ja.md │ │ ├── _index.fa.md │ │ ├── _index.md │ │ ├── comments.zh-cn.md │ │ ├── comments.ja.md │ │ ├── comments.fa.md │ │ ├── comments.md │ │ ├── multi-language.zh-cn.md │ │ └── multi-language.ja.md │ ├── guide │ │ ├── shortcodes │ │ │ ├── steps.zh-cn.md │ │ │ ├── details.zh-cn.md │ │ │ ├── details.ja.md │ │ │ ├── steps.ja.md │ │ │ ├── details.fa.md │ │ │ ├── details.md │ │ │ ├── steps.fa.md │ │ │ ├── _index.zh-cn.md │ │ │ ├── icon.zh-cn.md │ │ │ ├── _index.ja.md │ │ │ ├── steps.md │ │ │ ├── icon.ja.md │ │ │ ├── _index.fa.md │ │ │ ├── _index.md │ │ │ ├── icon.md │ │ │ ├── icon.fa.md │ │ │ ├── filetree.zh-cn.md │ │ │ ├── filetree.ja.md │ │ │ ├── filetree.fa.md │ │ │ ├── filetree.md │ │ │ └── jupyter.zh-cn.md │ │ ├── _index.zh-cn.md │ │ ├── _index.ja.md │ │ ├── _index.fa.md │ │ ├── _index.md │ │ ├── diagrams.zh-cn.md │ │ ├── diagrams.ja.md │ │ ├── diagrams.md │ │ ├── diagrams.fa.md │ │ └── syntax-highlighting.zh-cn.md │ ├── _index.zh-cn.md │ ├── _index.ja.md │ ├── _index.fa.md │ └── _index.md │ ├── about │ ├── index.zh-cn.md │ ├── index.ja.md │ ├── index.md │ └── index.fa.md │ └── showcase │ └── index.fa.md ├── go.mod ├── images ├── tn.jpg └── screenshot.jpg ├── .gitignore ├── static ├── favicon.ico ├── favicon-16x16.png ├── favicon-32x32.png ├── apple-touch-icon.png ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── site.webmanifest ├── casts │ └── demo.cast ├── images │ ├── logo-dark.svg │ └── logo.svg └── favicon.svg ├── postcss.config.mjs ├── .vscode ├── settings.json └── tailwind.json ├── hugo.toml ├── i18n ├── zh-tw.yaml ├── ko.yaml ├── ja.yaml ├── zh-cn.yaml ├── nb.yaml ├── nn.yaml ├── he.yaml ├── vi.yaml ├── pt.yaml ├── sw.yaml ├── cs.yaml ├── ru.yaml ├── uk.yaml ├── fa.yaml ├── nl.yaml ├── de.yaml ├── ro.yaml ├── en.yaml ├── es.yaml └── fr.yaml ├── examples └── README.md ├── netlify.toml ├── .prettierrc ├── taskfile.yaml ├── .devcontainer └── devcontainer.json ├── .github ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── FUNDING.yml └── workflows │ └── pages.yml ├── package.json ├── theme.toml ├── dev.toml ├── LICENSE └── README.zh-cn.md /assets/css/custom.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /layouts/_partials/custom/banner.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /layouts/_partials/custom/footer.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /layouts/_partials/custom/head-end.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/css/safelist.txt: -------------------------------------------------------------------------------- 1 | hx:max-w-full 2 | -------------------------------------------------------------------------------- /docs/hugo.work: -------------------------------------------------------------------------------- 1 | go 1.20 2 | 3 | use ../ 4 | -------------------------------------------------------------------------------- /layouts/_partials/custom/navbar-title.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/imfing/hextra 2 | 3 | go 1.20 4 | -------------------------------------------------------------------------------- /images/tn.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imfing/hextra/HEAD/images/tn.jpg -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | public/ 3 | resources/ 4 | 5 | .hugo_build.lock 6 | -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imfing/hextra/HEAD/static/favicon.ico -------------------------------------------------------------------------------- /images/screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imfing/hextra/HEAD/images/screenshot.jpg -------------------------------------------------------------------------------- /assets/css/components/badge.css: -------------------------------------------------------------------------------- 1 | .hextra-badge { 2 | @apply hx:inline-flex hx:items-center; 3 | } -------------------------------------------------------------------------------- /static/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imfing/hextra/HEAD/static/favicon-16x16.png -------------------------------------------------------------------------------- /static/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imfing/hextra/HEAD/static/favicon-32x32.png -------------------------------------------------------------------------------- /layouts/_markup/render-blockquote-regular.html: -------------------------------------------------------------------------------- 1 |
2 | {{ .Text }} 3 |
4 | -------------------------------------------------------------------------------- /static/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imfing/hextra/HEAD/static/apple-touch-icon.png -------------------------------------------------------------------------------- /docs/assets/images/space.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imfing/hextra/HEAD/docs/assets/images/space.jpg -------------------------------------------------------------------------------- /postcss.config.mjs: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | "@tailwindcss/postcss": {}, 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /docs/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/imfing/hextra/docs 2 | 3 | go 1.20 4 | 5 | replace github.com/imfing/hextra => ../ 6 | -------------------------------------------------------------------------------- /docs/static/images/hextra-doc.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imfing/hextra/HEAD/docs/static/images/hextra-doc.webp -------------------------------------------------------------------------------- /static/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imfing/hextra/HEAD/static/android-chrome-192x192.png -------------------------------------------------------------------------------- /static/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imfing/hextra/HEAD/static/android-chrome-512x512.png -------------------------------------------------------------------------------- /docs/static/images/hextra-search.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imfing/hextra/HEAD/docs/static/images/hextra-search.webp -------------------------------------------------------------------------------- /docs/static/images/hextra-markdown.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imfing/hextra/HEAD/docs/static/images/hextra-markdown.webp -------------------------------------------------------------------------------- /docs/static/images/card-image-unprocessed.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imfing/hextra/HEAD/docs/static/images/card-image-unprocessed.jpg -------------------------------------------------------------------------------- /layouts/_partials/google-analytics.html: -------------------------------------------------------------------------------- 1 | {{- /* Only for compatibility. */ -}} 2 | {{- partial "components/analytics/google-analytics.html" . -}} 3 | -------------------------------------------------------------------------------- /layouts/_partials/utils/format-date.html: -------------------------------------------------------------------------------- 1 | {{- with . -}} 2 | {{- . | time.Format (site.Params.dateFormat | default ":date_long") -}} 3 | {{- end -}} 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.tabSize": 2, 3 | "css.customData": [".vscode/tailwind.json"], 4 | "markdown.extension.toc.levels": "2..6" 5 | } 6 | -------------------------------------------------------------------------------- /docs/i18n/zh-cn.yaml: -------------------------------------------------------------------------------- 1 | documentation: "文档" 2 | showcase: "项目展示" 3 | blog: "博客" 4 | about: "关于" 5 | more: "更多" 6 | hugoDocs: "Hugo 文档 ↗" 7 | versions: "版本" 8 | development: "最新开发版本" 9 | -------------------------------------------------------------------------------- /layouts/_markup/render-codeblock-mermaid.html: -------------------------------------------------------------------------------- 1 |
2 |   {{ .Inner | htmlEscape | safeHTML }}
3 | 
4 | {{- .Page.Store.Set "hasMermaid" true -}} 5 | -------------------------------------------------------------------------------- /docs/i18n/ja.yaml: -------------------------------------------------------------------------------- 1 | documentation: "ドキュメント" 2 | showcase: "展示" 3 | blog: "ブログ" 4 | about: "概要" 5 | more: "もっと見る" 6 | hugoDocs: "Hugo ドキュメント ↗" 7 | versions: "バージョン" 8 | development: "最新の開発版" 9 | -------------------------------------------------------------------------------- /assets/css/components/toc.css: -------------------------------------------------------------------------------- 1 | /* Table of Contents Scroll Spy Styles */ 2 | .hextra-toc a.hextra-toc-active { 3 | @apply hx:text-gray-900! hx:dark:text-gray-50! hx:transition-all hx:duration-200; 4 | } 5 | -------------------------------------------------------------------------------- /assets/css/components/hextra/feature-grid.css: -------------------------------------------------------------------------------- 1 | .hextra-feature-grid { 2 | @media (min-width: 1024px) { 3 | grid-template-columns: repeat(var(--hextra-feature-grid-cols), minmax(0, 1fr)); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /docs/i18n/fa.yaml: -------------------------------------------------------------------------------- 1 | documentation: "مستندات" 2 | showcase: "ویترین" 3 | blog: "وبلاگ" 4 | about: "درباره ما" 5 | more: "بیشتر" 6 | hugoDocs: "مستندات هیوگو ↖" 7 | versions: "نسخه‌ها" 8 | development: "آخرین نسخه توسعه‌ای" 9 | -------------------------------------------------------------------------------- /hugo.toml: -------------------------------------------------------------------------------- 1 | [module] 2 | [module.hugoVersion] 3 | min = '0.146.0' 4 | 5 | [outputFormats] 6 | [outputFormats.llms] 7 | name= 'llms' 8 | baseName = 'llms' 9 | mediaType = 'text/plain' 10 | isPlainText = true 11 | -------------------------------------------------------------------------------- /layouts/_partials/utils/page-width-override.html: -------------------------------------------------------------------------------- 1 | {{- with .Params.width -}} 2 | 7 | {{- end -}} 8 | -------------------------------------------------------------------------------- /assets/css/components/code-copy.css: -------------------------------------------------------------------------------- 1 | @supports ( 2 | (-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px)) 3 | ) { 4 | .hextra-code-copy-btn { 5 | @apply hx:backdrop-blur-md hx:opacity-85 hx:dark:opacity-80; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /docs/layouts/_partials/custom/head-end.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | -------------------------------------------------------------------------------- /layouts/_partials/shortcodes/cards.html: -------------------------------------------------------------------------------- 1 | {{- $cols := .cols | default 3 -}} 2 | {{- $content := .content -}} 3 | 4 |
5 | {{- $content -}} 6 |
7 | -------------------------------------------------------------------------------- /docs/content/blog/_index.ja.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "ブログ" 3 | --- 4 | 5 |
6 | {{< hextra/hero-badge link="index.xml" >}} 7 | RSS フィード 8 | {{< icon name="rss" attributes="height=14" >}} 9 | {{< /hextra/hero-badge >}} 10 |
-------------------------------------------------------------------------------- /docs/content/blog/_index.zh-cn.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "博客" 3 | --- 4 | 5 |
6 | {{< hextra/hero-badge link="index.xml" >}} 7 | RSS 订阅 8 | {{< icon name="rss" attributes="height=14" >}} 9 | {{< /hextra/hero-badge >}} 10 |
-------------------------------------------------------------------------------- /docs/content/blog/_index.fa.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "وبلاگ" 3 | --- 4 | 5 |
6 | {{< hextra/hero-badge link="index.xml" >}} 7 | فید RSS 8 | {{< icon name="rss" attributes="height=14" >}} 9 | {{< /hextra/hero-badge >}} 10 |
-------------------------------------------------------------------------------- /docs/content/blog/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Blog" 3 | --- 4 | 5 |
6 | {{< hextra/hero-badge link="index.xml" >}} 7 | RSS Feed 8 | {{< icon name="rss" attributes="height=14" >}} 9 | {{< /hextra/hero-badge >}} 10 |
11 | -------------------------------------------------------------------------------- /layouts/_shortcodes/cards.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | A shortcode for creating cards. 3 | 4 | @param {string} cols The number of columns. 5 | 6 | @example {{< cards cols="3" >}}{{< /cards >}} 7 | */ -}} 8 | 9 | {{- $cols := .Get "cols" | default 3 -}} 10 | 11 | {{- partial "shortcodes/cards" (dict "cols" $cols "content" .Inner) -}} 12 | -------------------------------------------------------------------------------- /layouts/_shortcodes/steps.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | A shortcode for creating a step list. 3 | 4 | @example {{% steps %}}{{% /steps %}} 5 | */ -}} 6 | 7 |
8 | {{- .Inner -}} 9 |
10 | -------------------------------------------------------------------------------- /assets/js/head/banner.js: -------------------------------------------------------------------------------- 1 | // The section must not be in the banner.js (body) file because it can create a quick flash. 2 | 3 | if (localStorage.getItem('{{ site.Params.banner.key | default `banner-closed` }}')) { 4 | document.documentElement.style.setProperty("--hextra-banner-height", "0px"); 5 | document.documentElement.classList.add("hextra-banner-hidden"); 6 | } 7 | -------------------------------------------------------------------------------- /i18n/zh-tw.yaml: -------------------------------------------------------------------------------- 1 | backToTop: "返回頂部" 2 | changeLanguage: "切換語言" 3 | changeTheme: "切換主題" 4 | copyright: "© 2025 Hextra Project." 5 | dark: "深色" 6 | editThisPage: "在 GitHub 上編輯此頁 →" 7 | lastUpdated: "最後更新於" 8 | light: "淺色" 9 | noResultsFound: "無結果" 10 | onThisPage: "此頁上" 11 | tags: "標籤" 12 | poweredBy: "由 Hextra 驅動" 13 | readMore: "更多 →" 14 | searchPlaceholder: "搜尋文檔..." 15 | -------------------------------------------------------------------------------- /layouts/_partials/utils/page-description.html: -------------------------------------------------------------------------------- 1 | {{ with .Description | plainify | htmlUnescape -}} 2 | {{ . -}} 3 | {{ else -}} 4 | {{ if .IsHome -}} 5 | {{ with .Site.Params.description | plainify | htmlUnescape -}} 6 | {{ . -}} 7 | {{ end -}} 8 | {{ else -}} 9 | {{ .Summary | plainify | htmlUnescape | chomp -}} 10 | {{ end -}} 11 | {{ end -}} 12 | -------------------------------------------------------------------------------- /i18n/ko.yaml: -------------------------------------------------------------------------------- 1 | backToTop: "맨위로 스크롤" 2 | changeLanguage: "언어 변경" 3 | changeTheme: "테마 변경" 4 | copyright: "© 2025 Hextra Project." 5 | dark: "어두운 테마" 6 | editThisPage: "GitHub에서 편집하기 →" 7 | lastUpdated: "마지막 수정 일자" 8 | light: "밝은 테마" 9 | noResultsFound: "결과 없음" 10 | onThisPage: "페이지 목차" 11 | tags: "태그" 12 | poweredBy: "Hextra로 제작됨" 13 | readMore: "더보기 →" 14 | searchPlaceholder: "검색..." 15 | -------------------------------------------------------------------------------- /assets/css/components/banner.css: -------------------------------------------------------------------------------- 1 | .hextra-banner-hidden .hextra-banner { 2 | display: none; 3 | } 4 | 5 | .hextra-banner { 6 | :where(a):not(:where([class~=not-prose],[class~=not-prose] *)) { 7 | @apply hx:underline hx:decoration-from-font; 8 | } 9 | :where(p):not(:where([class~=not-prose],[class~=not-prose] *)) { 10 | @apply hx:leading-7 hx:first:mt-0; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /layouts/_partials/components/comments.html: -------------------------------------------------------------------------------- 1 | {{- $enableComments := site.Params.comments.enable | default false -}} 2 | 3 | {{ if not (eq .Params.comments nil) }} 4 | {{ $enableComments = .Params.comments }} 5 | {{ end }} 6 | 7 | {{- if $enableComments -}} 8 | {{- if eq site.Params.comments.type "giscus" -}} 9 | {{ partial "components/giscus.html" . }} 10 | {{- end -}} 11 | {{- end -}} 12 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | This folder will host boilerplate example sites demonstrating Hextra for different use-cases. 4 | 5 | Planned examples: 6 | - docs/ (minimal docs boilerplate) 7 | - blog/ (blog-centric setup) 8 | - portfolio/ (personal site/portfolio) 9 | 10 | Each example will include: 11 | - A ready-to-run Hugo site 12 | - Recommended config and params 13 | - Customizations and best practices 14 | -------------------------------------------------------------------------------- /i18n/ja.yaml: -------------------------------------------------------------------------------- 1 | backToTop: "トップにスクロール" 2 | changeLanguage: "言語を変更" 3 | changeTheme: "テーマを変更" 4 | copyright: "© 2025 Hextra プロジェクト。" 5 | dark: "ダーク" 6 | editThisPage: "このページをGitHubで編集 →" 7 | lastUpdated: "最終更新日" 8 | light: "ライト" 9 | noResultsFound: "結果が見つかりませんでした。" 10 | onThisPage: "このページの内容" 11 | tags: "タグ" 12 | poweredBy: "提供元 Hextra" 13 | readMore: "もっと読む →" 14 | searchPlaceholder: "検索..." 15 | previous: "前へ" 16 | next: "次へ" 17 | -------------------------------------------------------------------------------- /layouts/_markup/render-heading.html: -------------------------------------------------------------------------------- 1 | 2 | {{- .Text | safeHTML -}} 3 | {{- if gt .Level 1 -}} 4 | 5 | 6 | {{- end -}} 7 | 8 | {{- /* Drop trailing newlines */ -}} 9 | -------------------------------------------------------------------------------- /layouts/_partials/utils/icon.html: -------------------------------------------------------------------------------- 1 | {{/* Render raw svg icon from .Site.Data */}} 2 | {{- $icon := index site.Data.icons .name -}} 3 | 4 | {{- if not $icon -}} 5 | {{ errorf "icon %q not found" .name }} 6 | {{- end -}} 7 | 8 | {{- $icon = $icon | safeHTML -}} 9 | 10 | {{- if .attributes -}} 11 | {{- $icon = replaceRE " 11 | 12 | {{< cards >}} 13 | {{< card link="multi-language" title="多语言支持" icon="translate" >}} 14 | {{< card link="customization" title="自定义配置" icon="pencil" >}} 15 | {{< card link="comments" title="评论系统" icon="chat-alt" >}} 16 | {{< /cards >}} -------------------------------------------------------------------------------- /i18n/nb.yaml: -------------------------------------------------------------------------------- 1 | backToTop: "Gå til toppen" 2 | changeLanguage: "Endre språk" 3 | changeTheme: "Endre tema" 4 | copyright: "© 2025 Hextra-prosjektet." 5 | dark: "Mørk" 6 | editThisPage: "Rediger denne siden på GitHub →" 7 | lastUpdated: "Sist oppdatert" 8 | light: "Lys" 9 | noResultsFound: "Fant ingen treff." 10 | onThisPage: "På denne siden" 11 | tags: "Stikkord" 12 | poweredBy: "Powered by Hextra" 13 | readMore: "Les mer →" 14 | searchPlaceholder: "Søk..." 15 | -------------------------------------------------------------------------------- /i18n/nn.yaml: -------------------------------------------------------------------------------- 1 | backToTop: "Gå til toppen" 2 | changeLanguage: "Endre språk" 3 | changeTheme: "Endre tema" 4 | copyright: "© 2025 Hextra-prosjektet." 5 | dark: "Mørk" 6 | editThisPage: "Rediger denne sida på GitHub →" 7 | lastUpdated: "Sist oppdatert" 8 | light: "Ljos" 9 | noResultsFound: "Fann ingen treff." 10 | onThisPage: "På denne sida" 11 | tags: "Stikkord" 12 | poweredBy: "Powered by Hextra" 13 | readMore: "Les meir →" 14 | searchPlaceholder: "Søk..." 15 | -------------------------------------------------------------------------------- /layouts/_markup/render-blockquote-alert.html: -------------------------------------------------------------------------------- 1 | {{- if not (in (slice "note" "tip" "important" "warning" "caution") .AlertType) -}} 2 | {{- warnf "Alert type %s is not supported" .AlertType -}} 3 | {{- end -}} 4 | 5 | {{- $content := .Text -}} 6 | {{- $alertType := .AlertType -}} 7 | {{- $alertTitle := .AlertTitle -}} 8 | 9 | {{- partial "components/github-style-alert.html" (dict "content" $content "alertType" $alertType "alertTitle" $alertTitle) -}} 10 | -------------------------------------------------------------------------------- /i18n/he.yaml: -------------------------------------------------------------------------------- 1 | backToTop: "גלול למעלה" 2 | changeLanguage: "שנה שפה" 3 | changeTheme: "שנה ערכת צבעים" 4 | copyCode: "העתק קוד" 5 | copyright: "© 2025 פרוייקט Hextra" 6 | dark: "כהה" 7 | editThisPage: "← ערוך עמוד זה בגיטהאב" 8 | lastUpdated: "עודכן לאחרונה ב" 9 | light: "בהיר" 10 | noResultsFound: "לא נמצאו תוצאות." 11 | onThisPage: "בעמוד זה" 12 | tags: "תגיות" 13 | poweredBy: "Hextra מופעל על-ידי" 14 | readMore: "← קרא עוד" 15 | searchPlaceholder: "חיפוש..." 16 | -------------------------------------------------------------------------------- /layouts/_partials/tags.html: -------------------------------------------------------------------------------- 1 | {{- $context := .context -}} 2 | 3 | {{- range $tag := $context.Params.tags -}} 4 | {{- with $context.Site.GetPage (printf "/tags/%s" $tag) -}} 5 | #{{ $tag }} 6 | {{- end -}} 7 | {{- end -}} 8 | -------------------------------------------------------------------------------- /layouts/_shortcodes/filetree/container.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | A file tree container. 3 | 4 | @example {{< filetree/container >}}{{< /filetree/container >}} 5 | */ -}} 6 | 7 |
8 |
9 | {{- .InnerDeindent -}} 10 |
11 |
12 | -------------------------------------------------------------------------------- /i18n/vi.yaml: -------------------------------------------------------------------------------- 1 | backToTop: "Lướt lên đầu trang" 2 | changeLanguage: "Đổi ngôn ngữ" 3 | changeTheme: "Đổi chủ đề" 4 | copyright: "© 2025 Hextra Project." 5 | dark: "Tối" 6 | editThisPage: "Sửa trang này trên GitHub →" 7 | lastUpdated: "Lần cuối cập nhật lúc" 8 | light: "Sáng" 9 | noResultsFound: "Không tìm thấy kết quả." 10 | onThisPage: "Ở trang này" 11 | tags: "Thẻ" 12 | poweredBy: "Chạy bởi Hextra" 13 | readMore: "Đọc thêm →" 14 | searchPlaceholder: "Tìm kiếm..." 15 | -------------------------------------------------------------------------------- /layouts/_partials/scripts.html: -------------------------------------------------------------------------------- 1 | {{/* Core scripts (theme, menu, tabs, etc.) */}} 2 | {{- partial "scripts/core.html" . -}} 3 | 4 | {{/* Search */}} 5 | {{- partial "scripts/search.html" . -}} 6 | 7 | {{/* Mermaid */}} 8 | {{- if (.Store.Get "hasMermaid") -}} 9 | {{- partial "scripts/mermaid.html" . -}} 10 | {{- end -}} 11 | 12 | {{/* Asciinema */}} 13 | {{- if (.Store.Get "hasAsciinema") -}} 14 | {{- partial "scripts/asciinema.html" . -}} 15 | {{- end -}} 16 | -------------------------------------------------------------------------------- /layouts/_shortcodes/pdf.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | Shortcode to include a PDF file in a page. 3 | 4 | @param {string} 0 The path to the PDF file. 5 | 6 | @example {{< pdf "path/to/file.pdf" >}} 7 | */ -}} 8 | 9 | {{- $path := .Get 0 -}} 10 | {{- $url := partial "utils/file-path" (dict "page" .Page "path" $path) -}} 11 | 12 | 13 |
14 | 15 |
16 | -------------------------------------------------------------------------------- /docs/content/docs/advanced/_index.ja.md: -------------------------------------------------------------------------------- 1 | --- 2 | linkTitle: 高度な設定 3 | title: 高度なトピック 4 | prev: /docs/guide/shortcodes/tabs 5 | next: /docs/advanced/multi-language 6 | --- 7 | 8 | このセクションでは、テーマの高度なトピックについて説明します。 9 | 10 | 11 | 12 | {{< cards >}} 13 | {{< card link="multi-language" title="多言語対応" icon="translate" >}} 14 | {{< card link="customization" title="カスタマイズ" icon="pencil" >}} 15 | {{< card link="comments" title="コメントシステム" icon="chat-alt" >}} 16 | {{< /cards >}} -------------------------------------------------------------------------------- /layouts/_partials/components/analytics/google-analytics.html: -------------------------------------------------------------------------------- 1 | {{- with site.Config.Services.GoogleAnalytics.ID }} 2 | 3 | 4 | 13 | {{ end -}} 14 | -------------------------------------------------------------------------------- /taskfile.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | tasks: 4 | build: 5 | desc: Build Hextra documentation site under `docs` 6 | cmds: 7 | - hugo --gc --minify --themesDir=../.. --source=docs 8 | 9 | css: 10 | depends: [build] 11 | desc: Compile production CSS using PostCSS to `assets/css/compiled/main.css` 12 | cmds: 13 | - npm run build:css 14 | 15 | dev: 16 | desc: Start development server for Hextra theme 17 | cmds: 18 | - npm run dev:theme 19 | -------------------------------------------------------------------------------- /i18n/pt.yaml: -------------------------------------------------------------------------------- 1 | backToTop: "Voltar ao topo" 2 | changeLanguage: "Mudar a língua" 3 | changeTheme: "Mudar tema" 4 | copyright: "© 2025 Projecto Hextra." 5 | dark: "Escuro" 6 | editThisPage: "Edita esta página no GitHub →" 7 | lastUpdated: "Última modificação" 8 | light: "Claro" 9 | noResultsFound: "Nenhum resultado encontrado" 10 | onThisPage: "Nesta página" 11 | tags: "Etiquetas" 12 | poweredBy: "Com a tecnologia de Hextra" 13 | readMore: "Ler mais →" 14 | searchPlaceholder: "Procurar..." 15 | -------------------------------------------------------------------------------- /layouts/_shortcodes/hextra/hero-subtitle.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | A shortcode for displaying a hero subtitle. 3 | 4 | @param {string} style The style of the subtitle. 5 | 6 | @example {{< hextra/hero-subtitle >}}{{< /hextra/hero-subtitle >}} 7 | */ -}} 8 | 9 | {{- $style := .Get "style" -}} 10 | 11 |

15 | {{ .Inner | markdownify }} 16 |

17 | -------------------------------------------------------------------------------- /i18n/sw.yaml: -------------------------------------------------------------------------------- 1 | backToTop: "Tembeza hadi juu" 2 | changeLanguage: "Badilisha lugha" 3 | changeTheme: "Badilisha mandhari" 4 | copyright: "© 2025 Hextra Project." 5 | dark: "Meusi" 6 | editThisPage: "Hariri ukurasa huu kwenye GitHub →" 7 | lastUpdated: "Ilisasishwa mwisho" 8 | light: "Meupe" 9 | noResultsFound: "Hakuna matokeo yalipopatikana." 10 | onThisPage: "Kwenye ukurasa huu" 11 | tags: "Lebo" 12 | poweredBy: "Inaendeshwa na Hextra" 13 | readMore: "Soma zaidi →" 14 | searchPlaceholder: "Tafuta..." 15 | -------------------------------------------------------------------------------- /layouts/_partials/scripts/core.html: -------------------------------------------------------------------------------- 1 | {{- $scriptsBody := slice }} 2 | {{- range resources.Match "js/core/*.js" -}} 3 | {{ $scriptsBody = $scriptsBody | append (resources.ExecuteAsTemplate .Name $ .) }} 4 | {{- end -}} 5 | 6 | {{- $scripts := $scriptsBody | resources.Concat "js/main.js" -}} 7 | {{- if hugo.IsProduction -}} 8 | {{- $scripts = $scripts | minify | fingerprint -}} 9 | {{- end -}} 10 | 11 | -------------------------------------------------------------------------------- /i18n/cs.yaml: -------------------------------------------------------------------------------- 1 | backToTop: "Zpět nahoru" 2 | changeLanguage: "Změnit jazyk" 3 | changeTheme: "Změnit vzhled" 4 | copyCode: "Zkopírovat kód" 5 | copyright: "© 2025 Hextra Project." 6 | dark: "Tmavý" 7 | editThisPage: "Upravit tuto stránku na GitHubu →" 8 | lastUpdated: "Naposledy změněno" 9 | light: "Světlý" 10 | noResultsFound: "Nebylo nic nalezeno." 11 | onThisPage: "Na této stránce" 12 | tags: "Tagy" 13 | poweredBy: "Powered by Hextra" 14 | readMore: "Přečíst víc →" 15 | searchPlaceholder: "Hledat..." 16 | -------------------------------------------------------------------------------- /static/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Hextra", 3 | "short_name": "Hextra", 4 | "start_url": "index.html", 5 | "icons": [ 6 | { 7 | "src": "android-chrome-192x192.png", 8 | "sizes": "192x192", 9 | "type": "image/png" 10 | }, 11 | { 12 | "src": "android-chrome-512x512.png", 13 | "sizes": "512x512", 14 | "type": "image/png" 15 | } 16 | ], 17 | "theme_color": "#000000", 18 | "background_color": "#000000", 19 | "display": "standalone" 20 | } 21 | -------------------------------------------------------------------------------- /i18n/ru.yaml: -------------------------------------------------------------------------------- 1 | backToTop: 'Прокрутить к началу' 2 | changeLanguage: 'Изменить язык' 3 | changeTheme: 'Изменить тему' 4 | copyCode: 'Скопировать код' 5 | copyright: '2025 Проект Hextra.' 6 | dark: 'Темная' 7 | editThisPage: 'Отредактировать страницу на GitHub →' 8 | lastUpdated: 'Последнее обновление' 9 | light: 'Светлая' 10 | noResultsFound: 'Ничего не найдено.' 11 | onThisPage: 'На этой странице' 12 | tags: 'Теги' 13 | poweredBy: 'При поддержке Hextra' 14 | readMore: 'Читать далее →' 15 | searchPlaceholder: 'Поиск...' 16 | -------------------------------------------------------------------------------- /i18n/uk.yaml: -------------------------------------------------------------------------------- 1 | backToTop: "Прокрутити до початку" 2 | changeLanguage: "Змінити мову" 3 | changeTheme: "Змінити тему" 4 | copyCode: "Скопіювати код" 5 | copyright: "2025 Проєкт Hextra." 6 | dark: "Темна" 7 | editThisPage: "Редагувати цю сторінку на GitHub →" 8 | lastUpdated: "Востаннє оновлено" 9 | light: "Світла" 10 | noResultsFound: "Не знайдено результатів" 11 | onThisPage: "На цій сторінці" 12 | tags: "Теги" 13 | poweredBy: "Працює завдяки Hextra" 14 | readMore: "Читати більше →" 15 | searchPlaceholder: "Пошук..." 16 | -------------------------------------------------------------------------------- /layouts/baseof.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{- partial "head.html" . -}} 4 | 5 | {{- partial "banner.html" . -}} 6 | {{- partial "navbar.html" . -}} 7 | {{- block "main" . }}{{ end -}} 8 | {{- if or (eq .Site.Params.footer.enable nil) (.Site.Params.footer.enable) }} 9 | {{ partial "footer.html" . }} 10 | {{ end }} 11 | {{ partial "scripts.html" . }} 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/content/docs/advanced/_index.fa.md: -------------------------------------------------------------------------------- 1 | --- 2 | linkTitle: پیشرفته 3 | title: مباحث پیشرفته 4 | prev: /docs/guide/shortcodes/tabs 5 | next: /docs/advanced/multi-language 6 | --- 7 | 8 | این بخش برخی از مباحث پیشرفته این پوسته را پوشش می‌دهد. 9 | 10 | 11 | 12 | {{< cards >}} 13 | {{< card link="multi-language" title="چندزبانه" icon="translate" >}} 14 | {{< card link="customization" title="سفارشی‌سازی" icon="pencil" >}} 15 | {{< card link="comments" title="سیستم نظرات" icon="chat-alt" >}} 16 | {{< /cards >}} -------------------------------------------------------------------------------- /i18n/fa.yaml: -------------------------------------------------------------------------------- 1 | backToTop: "به بالا بروید" 2 | changeLanguage: "تغییر زبان" 3 | changeTheme: "تغییر تم" 4 | copyCode: "کپی کد" 5 | copyright: "© ۲۰۲۴ پروژه هگزترا." 6 | dark: "تیره" 7 | editThisPage: "ویرایش این صفحه در گیت‌هاب ←" 8 | lastUpdated: "آخرین به‌روزرسانی در" 9 | light: "روشن" 10 | noResultsFound: "هیچ نتیجه‌ای پیدا نشد." 11 | onThisPage: "در این صفحه" 12 | tags: "برچسب‌ها" 13 | poweredBy: "طراحی شده توسط هگزترا" 14 | readMore: "ادامه مطلب ←" 15 | searchPlaceholder: "جستجو..." 16 | previous: "قبلی" 17 | next: "بعدی" 18 | -------------------------------------------------------------------------------- /i18n/nl.yaml: -------------------------------------------------------------------------------- 1 | backToTop: "Terug naar boven" 2 | changeLanguage: "Taal veranderen" 3 | changeTheme: "Thema aanpassen" 4 | copyCode: "Kopieer code" 5 | copyright: "© 2025 Hextra Project." 6 | dark: "Donker" 7 | editThisPage: "Bewerk deze pagina op GitHub →" 8 | lastUpdated: "Laatst bijgewerkt op" 9 | light: "Licht" 10 | noResultsFound: "Geen resultaten gevonden." 11 | onThisPage: "Op deze pagina" 12 | tags: "Labels" 13 | poweredBy: "Mogelijk gemaakt door Hextra" 14 | readMore: "Lees meer →" 15 | searchPlaceholder: "Zoeken..." 16 | -------------------------------------------------------------------------------- /i18n/de.yaml: -------------------------------------------------------------------------------- 1 | backToTop: "Nach oben" 2 | changeLanguage: "Sprache ändern" 3 | changeTheme: "Darstellung ändern" 4 | copyCode: "Code kopieren" 5 | copyright: "© 2025 Hextra Project." 6 | dark: "Dunkel" 7 | editThisPage: "Diese Seite auf GitHub bearbeiten →" 8 | lastUpdated: "Zuletzt aktualisiert am" 9 | light: "Hell" 10 | noResultsFound: "Keine Ergebnisse gefunden." 11 | onThisPage: "Auf dieser Seite" 12 | tags: "Schlagwörter" 13 | poweredBy: "Unterstützt durch Hextra" 14 | readMore: "Mehr lesen →" 15 | searchPlaceholder: "Suchen..." 16 | -------------------------------------------------------------------------------- /docs/content/docs/advanced/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | linkTitle: Advanced 3 | title: Advanced Topics 4 | prev: /docs/guide/shortcodes/tabs 5 | next: /docs/advanced/multi-language 6 | --- 7 | 8 | This section covers some advanced topics of the theme. 9 | 10 | 11 | 12 | {{< cards >}} 13 | {{< card link="multi-language" title="Multi-language" icon="translate" >}} 14 | {{< card link="customization" title="Customization" icon="pencil" >}} 15 | {{< card link="comments" title="Comments System" icon="chat-alt" >}} 16 | {{< /cards >}} 17 | -------------------------------------------------------------------------------- /i18n/ro.yaml: -------------------------------------------------------------------------------- 1 | backToTop: "Înapoi sus" 2 | changeLanguage: "Schimbă limba" 3 | changeTheme: "Schimbă tema" 4 | copyCode: "Copiază codul" 5 | copyright: "© 2025 Hextra Project." 6 | dark: "Întuneric" 7 | editThisPage: "Editați această pagină pe GitHub ←" 8 | lastUpdated: "Ultima actualizare la" 9 | light: "Lumină" 10 | noResultsFound: "Nici un rezultat găsit." 11 | onThisPage: "Pe această pagină" 12 | tags: "Etichete" 13 | poweredBy: "Susținut de Hextra" 14 | readMore: "Citește mai mult ←" 15 | searchPlaceholder: "Caută..." 16 | -------------------------------------------------------------------------------- /i18n/en.yaml: -------------------------------------------------------------------------------- 1 | backToTop: "Scroll to top" 2 | changeLanguage: "Change language" 3 | changeTheme: "Change theme" 4 | copyCode: "Copy code" 5 | copyright: "© 2025 Hextra Project." 6 | dark: "Dark" 7 | editThisPage: "Edit this page on GitHub →" 8 | lastUpdated: "Last updated on" 9 | light: "Light" 10 | next: "Next" 11 | noResultsFound: "No results found." 12 | onThisPage: "On this page" 13 | poweredBy: "Powered by Hextra" 14 | previous: "Prev" 15 | readMore: "Read more →" 16 | searchPlaceholder: "Search..." 17 | system: "System" 18 | tags: "Tags" 19 | -------------------------------------------------------------------------------- /layouts/_shortcodes/filetree/file.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | A file in a file tree. 3 | 4 | @param {string} name The name of the file. 5 | 6 | @example {{< filetree/file name="_index.md" >}} 7 | */ -}} 8 | 9 | {{- $name := .Get "name" -}} 10 | 11 |
  • 12 | 13 | {{- partial "utils/icon" (dict "name" "document-text" "attributes" "width=1em") -}} 14 | {{ $name | markdownify }} 15 | 16 |
  • 17 | -------------------------------------------------------------------------------- /layouts/hextra-home.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
    3 | {{ partial "sidebar.html" (dict "context" . "disableSidebar" true) }} 4 |
    5 |
    6 | {{ .Content }} 7 |
    8 |
    9 |
    10 | {{ end }} 11 | -------------------------------------------------------------------------------- /layouts/_partials/favicons.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /layouts/_partials/scripts/mathjax.html: -------------------------------------------------------------------------------- 1 | {{/* MathJax */}} 2 | {{ $mathjaxJsUrl := "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js" -}} 3 | 4 | 21 | -------------------------------------------------------------------------------- /i18n/es.yaml: -------------------------------------------------------------------------------- 1 | backToTop: "Subir al inicio" 2 | changeLanguage: "Cambiar idioma" 3 | changeTheme: "Cambiar tema" 4 | copyCode: "Copiar código" 5 | copyright: "© 2025 Proyecto Hextra." 6 | dark: "Oscuro" 7 | editThisPage: "Edita esta página en GitHub →" 8 | lastUpdated: "Última actualización" 9 | light: "Claro" 10 | next: "Siguiente" 11 | noResultsFound: "No hubo resultados." 12 | onThisPage: "En esta página" 13 | poweredBy: "Con tecnología de Hextra" 14 | previous: "Anterior" 15 | readMore: "Leer más →" 16 | searchPlaceholder: "Buscar..." 17 | system: "Sistema" 18 | tags: "Etiquetas" 19 | -------------------------------------------------------------------------------- /i18n/fr.yaml: -------------------------------------------------------------------------------- 1 | backToTop: "Revenir en haut" 2 | changeLanguage: "Changer la langue" 3 | changeTheme: "Thème d'affichage" 4 | copyCode: "Copier le code" 5 | copyright: "© 2025 Hextra Project." 6 | dark: "Sombre" 7 | editThisPage: "Modifier cette page sur GitHub →" 8 | lastUpdated: "Dernière modification" 9 | light: "Clair" 10 | next: "Suivant" 11 | noResultsFound: "Pas de résultats trouvés" 12 | onThisPage: "Sur cette page" 13 | poweredBy: "Propulsé par Hextra" 14 | previous: "Précdent" 15 | readMore: "Lire plus →" 16 | searchPlaceholder: "Rechercher..." 17 | system: "Système" 18 | tags: "Étiquettes" 19 | -------------------------------------------------------------------------------- /assets/js/core/back-to-top.js: -------------------------------------------------------------------------------- 1 | // Back to top button 2 | 3 | document.addEventListener("DOMContentLoaded", function () { 4 | const backToTop = document.querySelector("#backToTop"); 5 | if (backToTop) { 6 | document.addEventListener("scroll", (e) => { 7 | if (window.scrollY > 300) { 8 | backToTop.classList.remove("hx:opacity-0"); 9 | } else { 10 | backToTop.classList.add("hx:opacity-0"); 11 | } 12 | }); 13 | } 14 | }); 15 | 16 | function scrollUp() { 17 | window.scroll({ 18 | top: 0, 19 | left: 0, 20 | behavior: "smooth", 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /docs/content/about/index.zh-cn.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 关于 3 | toc: false 4 | --- 5 | 6 | Hextra 是一款专为构建现代化静态网站而设计的简洁、快速且灵活的主题。它尤其适合搭建文档类网站,同时也能轻松驾驭博客、作品集等多种站点类型。 7 | 8 | 与 Jekyll 类似,Hugo 同样是一款静态网站生成器。其独特之处在于采用单一二进制文件,可在多平台轻松安装运行。Hugo 以极致的速度与稳定性著称,能在毫秒间渲染包含数千页面的网站。 9 | 10 | Hextra 秉持极简理念开发。您无需安装 Node.js 等额外依赖,仅需一个 YAML 配置文件搭配 Markdown 内容即可快速开始。这让我们能专注于创作优质内容,而非配置工具链。 11 | 12 | ## 致谢 13 | 14 | Hextra 的诞生离不开以下工具与灵感的启发: 15 | 16 | - [Hugo](https://gohugo.io/) 17 | - [Tailwind CSS](https://tailwindcss.com/) 18 | - [Heroicons](https://heroicons.com/) 19 | - [Nextra](https://nextra.vercel.app/) 20 | - [Next.js](https://nextjs.org/) -------------------------------------------------------------------------------- /docs/content/docs/guide/shortcodes/steps.zh-cn.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 步骤 3 | --- 4 | 5 | 一个内置组件,用于显示一系列步骤。 6 | 7 | ## 示例 8 | 9 | {{% steps %}} 10 | 11 | ### 第一步 12 | 13 | 这是第一步。 14 | 15 | ### 第二步 16 | 17 | 这是第二步。 18 | 19 | ### 第三步 20 | 21 | 这是第三步。 22 | 23 | {{% /steps %}} 24 | 25 | 26 | ## 使用方法 27 | 28 | {{< callout type="warning" >}} 29 | 请注意,此短代码**仅适用于Markdown内容**。 30 | 如果在步骤内容中放入HTML或其他短代码,可能无法按预期渲染。 31 | {{< /callout >}} 32 | 33 | 在`steps`短代码内放置Markdown的三级标题。 34 | 35 | ``` 36 | {{%/* steps */%}} 37 | 38 | ### 第一步 39 | 40 | 这是第一步。 41 | 42 | ### 第二步 43 | 44 | 这是第二步。 45 | 46 | {{%/* /steps */%}} 47 | ``` -------------------------------------------------------------------------------- /layouts/_partials/components/last-updated.html: -------------------------------------------------------------------------------- 1 | {{- $lastUpdated := (T "lastUpdated") | default "Last updated on" -}} 2 | 3 | {{- if site.Params.displayUpdatedDate -}} 4 | {{- with .Lastmod -}} 5 | {{ $datetime := (time.Format "2006-01-02T15:04:05.000Z" .) }} 6 |
    {{ $lastUpdated }}
    7 | {{- else -}} 8 |
    9 | {{- end -}} 10 | {{- else -}} 11 |
    12 | {{- end -}} 13 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "image": "mcr.microsoft.com/devcontainers/go:1", 3 | "features": { 4 | "ghcr.io/devcontainers/features/hugo:1": { 5 | "extended": true, 6 | "version": "0.147.7" 7 | }, 8 | "ghcr.io/devcontainers/features/node:1": {} 9 | }, 10 | "customizations": { 11 | "vscode": { 12 | "extensions": [ 13 | "mhutchie.git-graph", 14 | "esbenp.prettier-vscode", 15 | "tamasfe.even-better-toml", 16 | "budparr.language-hugo-vscode" 17 | ] 18 | } 19 | }, 20 | "postCreateCommand": "npm install", 21 | "forwardPorts": [ 22 | 1313 23 | ] 24 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Feature Description** 11 | 12 | 13 | 14 | **Problem/Solution** 15 | 16 | 17 | 18 | **Alternatives Considered** 19 | 20 | 21 | 22 | **Additional Context** 23 | 24 | 25 | -------------------------------------------------------------------------------- /layouts/_shortcodes/hextra/hero-headline.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | A shortcode for displaying a hero headline. 3 | 4 | @param {string} style The style of the headline. 5 | 6 | @example {{< hextra/hero-headline >}}{{< /hextra/hero-headline >}} 7 | */ -}} 8 | 9 | {{- $style := .Get "style" -}} 10 | 11 |

    15 | {{ .Inner | markdownify }} 16 |

    17 | -------------------------------------------------------------------------------- /assets/js/core/banner.js: -------------------------------------------------------------------------------- 1 | // {{- if site.Params.banner }} 2 | (function () { 3 | const banner = document.querySelector(".hextra-banner") 4 | document.documentElement.style.setProperty("--hextra-banner-height", banner.clientHeight+"px"); 5 | 6 | const closeBtn = banner.querySelector(".hextra-banner-close-button"); 7 | 8 | closeBtn.addEventListener("click", () => { 9 | document.documentElement.classList.add("hextra-banner-hidden"); 10 | document.documentElement.style.setProperty("--hextra-banner-height", "0px"); 11 | 12 | localStorage.setItem('{{ site.Params.banner.key | default `banner-closed` }}', "0"); 13 | }); 14 | })(); 15 | // {{- end -}} 16 | -------------------------------------------------------------------------------- /assets/js/head/theme.js: -------------------------------------------------------------------------------- 1 | // The section must not be in the theme.js (body) file because it can create a quick flash (switch between light and dark). 2 | 3 | function setTheme(theme) { 4 | document.documentElement.classList.remove("light", "dark"); 5 | 6 | if (theme !== "light" && theme !== "dark") { 7 | theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; 8 | } 9 | 10 | document.documentElement.classList.add(theme); 11 | document.documentElement.style.colorScheme = theme; 12 | } 13 | 14 | setTheme("color-theme" in localStorage ? localStorage.getItem("color-theme") : '{{ site.Params.theme.default | default `system`}}') 15 | -------------------------------------------------------------------------------- /docs/content/docs/guide/shortcodes/details.zh-cn.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 详情 3 | --- 4 | 5 | 一个内置组件,用于显示可折叠的内容。 6 | 7 | 8 | 9 | ## 示例 10 | 11 | {{< details title="详情" >}} 12 | 13 | 这是详情的内容。 14 | 15 | 支持 **Markdown** 格式。 16 | 17 | {{< /details >}} 18 | 19 | {{< details title="点击我展开" closed="true" >}} 20 | 21 | 默认情况下,这部分内容会被隐藏。 22 | 23 | {{< /details >}} 24 | 25 | ## 使用方法 26 | 27 | ````markdown 28 | {{}} 29 | 30 | 这是详情的内容。 31 | 32 | 支持 **Markdown** 格式。 33 | 34 | {{}} 35 | ```` 36 | 37 | ````markdown 38 | {{}} 39 | 40 | 默认情况下,这部分内容会被隐藏。 41 | 42 | {{}} 43 | ```` -------------------------------------------------------------------------------- /layouts/_partials/utils/lang-link.html: -------------------------------------------------------------------------------- 1 | {{/* Get relative link of a page for given language */}} 2 | {{/* If not found, return the homepage of the language page */}} 3 | 4 | {{ $page := .context }} 5 | {{ $lang := .lang }} 6 | 7 | {{ $link := false }} 8 | 9 | {{ range $page.AllTranslations }} 10 | {{ if eq .Language.Lang $lang }} 11 | {{ $link = .RelPermalink }} 12 | {{ end }} 13 | {{ end }} 14 | 15 | {{ if not $link }} 16 | {{ range where $page.Sites ".Language.Lang" $lang }} 17 | {{ $link = .Home.RelPermalink }} 18 | {{ end }} 19 | {{ end }} 20 | 21 | {{ if not $link }} 22 | {{ $link = site.Home.RelPermalink }} 23 | {{ end }} 24 | 25 | {{ return $link }} 26 | -------------------------------------------------------------------------------- /layouts/_partials/utils/title.html: -------------------------------------------------------------------------------- 1 | {{/* 2 | This utility is used to retrieve the title of a page or section. 3 | If no title is set, it falls back to using the directory or file name. 4 | 5 | Based on https://github.com/thegeeklab/hugo-geekdoc/blob/v0.44.0/layouts/partials/utils/title.html 6 | */}} 7 | {{- $title := "" }} 8 | 9 | {{ if .LinkTitle }} 10 | {{ $title = .LinkTitle }} 11 | {{ else if .Title }} 12 | {{ $title = .Title }} 13 | {{ else if and .IsSection .File }} 14 | {{ $title = path.Base .File.Dir | humanize | title }} 15 | {{ else if and .IsPage .File }} 16 | {{ $title = .File.BaseFileName | humanize | title }} 17 | {{ end }} 18 | 19 | {{ return $title -}} 20 | -------------------------------------------------------------------------------- /assets/css/components/sidebar.css: -------------------------------------------------------------------------------- 1 | @media (max-width: 48rem) { 2 | .hextra-sidebar-container { 3 | @apply hx:fixed hx:pt-[calc(var(--navbar-height)+var(--hextra-banner-height))] hx:top-0 hx:w-full hx:bottom-0 hx:z-[15] hx:overscroll-contain hx:bg-white hx:dark:bg-dark; 4 | transition: transform 0.4s cubic-bezier(0.52, 0.16, 0.04, 1); 5 | will-change: transform, opacity; 6 | contain: layout style; 7 | backface-visibility: hidden; 8 | } 9 | } 10 | 11 | .hextra-sidebar-container { 12 | li > div { 13 | @apply hx:h-0; 14 | } 15 | li.open > div { 16 | @apply hx:h-auto hx:pt-1; 17 | } 18 | li.open > a > span > svg > path { 19 | @apply hx:rotate-90; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /docs/layouts/_shortcodes/new-feature.html: -------------------------------------------------------------------------------- 1 | {{- $version := .Get "version" | default "" -}} 2 | {{- $icon := .Get "icon" | default "" -}} 3 | {{- $defaultLink := cond (eq $version "") "https://github.com/imfing/hextra/tree/main" (printf "https://github.com/imfing/hextra/releases/tag/%s" $version) -}} 4 | {{- $link := .Get "link" | default $defaultLink -}} 5 | {{- $content := cond (eq $version "") "New in main branch" (printf "New in %s" $version) -}} 6 | 7 |
    8 | 9 | {{- partial "shortcodes/badge" (dict "content" $content "border" true "icon" $icon) -}} 10 | 11 |
    12 | -------------------------------------------------------------------------------- /assets/css/components/scrollbar.css: -------------------------------------------------------------------------------- 1 | .hextra-scrollbar, .hextra-scrollbar * { 2 | scrollbar-width: thin; /* Firefox */ 3 | scrollbar-color: oklch(55.55% 0 0 / 40%) transparent; /* Firefox */ 4 | 5 | scrollbar-gutter: stable; 6 | &::-webkit-scrollbar { 7 | @apply hx:w-3 hx:h-3; 8 | } 9 | &::-webkit-scrollbar-track { 10 | @apply hx:bg-transparent; 11 | } 12 | &::-webkit-scrollbar-thumb { 13 | @apply hx:rounded-[10px]; 14 | } 15 | &:hover::-webkit-scrollbar-thumb { 16 | border: 3px solid transparent; 17 | background-color: var(--tw-shadow-color); 18 | background-clip: content-box; 19 | @apply hx:shadow-neutral-500/20 hx:hover:shadow-neutral-500/40; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /layouts/_shortcodes/hextra/feature-grid.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | A shortcode for displaying a feature grid. 3 | 4 | @param {string} cols The number of columns. 5 | @param {string} style The style of the grid. 6 | 7 | @example {{< hextra/feature-grid cols="3" >}}{{< /hextra/feature-grid >}} 8 | */ -}} 9 | 10 | {{- $cols := .Get "cols" | default 3 -}} 11 | {{- $style := .Get "style" | default "" -}} 12 | 13 | {{- $css := printf "--hextra-feature-grid-cols: %v; %s" $cols $style -}} 14 | 15 | 16 |
    20 | {{ .Inner }} 21 |
    22 | -------------------------------------------------------------------------------- /docs/content/docs/guide/shortcodes/details.ja.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 詳細 3 | --- 4 | 5 | 折りたたみ可能なコンテンツを表示するための組み込みコンポーネントです。 6 | 7 | 8 | 9 | ## 例 10 | 11 | {{< details title="詳細" >}} 12 | 13 | これは詳細のコンテンツです。 14 | 15 | Markdown は **サポートされています**。 16 | 17 | {{< /details >}} 18 | 19 | {{< details title="クリックして表示" closed="true" >}} 20 | 21 | これはデフォルトで非表示になります。 22 | 23 | {{< /details >}} 24 | 25 | ## 使用方法 26 | 27 | ````markdown 28 | {{}} 29 | 30 | これは詳細のコンテンツです。 31 | 32 | Markdown は **サポートされています**。 33 | 34 | {{}} 35 | ```` 36 | 37 | ````markdown 38 | {{}} 39 | 40 | これはデフォルトで非表示になります。 41 | 42 | {{}} 43 | ```` -------------------------------------------------------------------------------- /assets/js/core/filetree.js: -------------------------------------------------------------------------------- 1 | // Script for filetree shortcode collapsing/expanding folders used in the theme 2 | // ====================================================================== 3 | document.addEventListener("DOMContentLoaded", function () { 4 | const folders = document.querySelectorAll(".hextra-filetree-folder"); 5 | folders.forEach(function (folder) { 6 | folder.addEventListener("click", function () { 7 | Array.from(folder.children).forEach(function (el) { 8 | el.dataset.state = el.dataset.state === "open" ? "closed" : "open"; 9 | }); 10 | folder.nextElementSibling.dataset.state = folder.nextElementSibling.dataset.state === "open" ? "closed" : "open"; 11 | }); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /layouts/_markup/render-codeblock.html: -------------------------------------------------------------------------------- 1 | {{- $class := .Attributes.class | default "" -}} 2 | {{- $filename := .Attributes.filename | default "" -}} 3 | {{- $base_url := .Attributes.base_url | default "" -}} 4 | {{- $lang := .Attributes.lang | default .Type -}} 5 | 6 | 7 |
    8 | {{- partial "components/codeblock" (dict "filename" $filename "lang" $lang "base_url" $base_url "content" .Inner "options" .Options) -}} 9 | 10 | {{- if or (eq site.Params.highlight.copy.enable nil) (site.Params.highlight.copy.enable) -}} 11 | {{- partialCached "components/codeblock-copy-button" (dict "filename" $filename) $filename -}} 12 | {{- end -}} 13 |
    14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "dev:theme": "hugo server --logLevel=debug --config=hugo.yaml,../dev.toml --environment=theme --source=docs --themesDir=../.. -D -F --port 1313", 4 | "dev": "hugo server --source=docs --themesDir=../.. --disableFastRender -D --port 1313", 5 | "build:css": "npx postcss --config postcss.config.mjs --env production assets/css/styles.css -o assets/css/compiled/main.css", 6 | "build": "hugo --gc --minify --themesDir=../.. --source=docs" 7 | }, 8 | "devDependencies": { 9 | "@tailwindcss/postcss": "^4.1.11", 10 | "postcss-cli": "^11.0.1", 11 | "prettier": "^3.5.3", 12 | "prettier-plugin-go-template": "^0.0.15", 13 | "tailwindcss": "^4.1.11" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /layouts/wide.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
    3 | {{ partial "sidebar.html" (dict "context" . "disableSidebar" true "displayPlaceholder" false) }} 4 |
    5 |
    6 | {{ if .Title }}

    {{ .Title }}

    {{ end }} 7 |
    8 | {{ .Content }} 9 |
    10 |
    11 |
    12 | {{ end }} -------------------------------------------------------------------------------- /docs/content/docs/guide/shortcodes/steps.ja.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ステップ 3 | --- 4 | 5 | 一連のステップを表示するための組み込みコンポーネントです。 6 | 7 | ## 例 8 | 9 | {{% steps %}} 10 | 11 | ### ステップ 1 12 | 13 | これは最初のステップです。 14 | 15 | ### ステップ 2 16 | 17 | これは2番目のステップです。 18 | 19 | ### ステップ 3 20 | 21 | これは3番目のステップです。 22 | 23 | {{% /steps %}} 24 | 25 | 26 | ## 使い方 27 | 28 | {{< callout type="warning" >}} 29 | このショートコードは **Markdown コンテンツ専用** であることに注意してください。 30 | HTML コンテンツや他のショートコードをステップの内容として含めると、期待通りにレンダリングされない場合があります。 31 | {{< /callout >}} 32 | 33 | `steps` ショートコード内に Markdown の h3 ヘッダーを配置します。 34 | 35 | ``` 36 | {{%/* steps */%}} 37 | 38 | ### ステップ 1 39 | 40 | これは最初のステップです。 41 | 42 | ### ステップ 2 43 | 44 | これは2番目のステップです。 45 | 46 | {{%/* /steps */%}} 47 | ``` -------------------------------------------------------------------------------- /layouts/_shortcodes/tab.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | Create a tab. 3 | 4 | @param {string} name The name of the tab. 5 | @param {string} selected Whether the tab is selected. 6 | 7 | @example {{< tab name="Foo" selected=true >}}content{{< /tab >}} 8 | */ -}} 9 | 10 | {{- $name := .Get "name" | default (printf "Tab %d" .Ordinal) -}} 11 | 12 | {{- $selected := .Get "selected" -}} 13 | {{- if .Parent.Get "defaultIndex" -}} 14 | {{- $selected = eq .Ordinal (int (.Parent.Get "defaultIndex")) -}} 15 | {{- end -}} 16 | 17 | {{- $tabs := .Parent.Store.Get "tabs" | default slice -}} 18 | {{ .Parent.Store.Set "tabs" ($tabs | append (dict 19 | "id" .Ordinal 20 | "name" $name 21 | "content" .InnerDeindent 22 | "selected" $selected 23 | )) 24 | -}} 25 | -------------------------------------------------------------------------------- /docs/content/about/index.ja.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: このサイトについて 3 | toc: false 4 | --- 5 | 6 | Hextra は、モダンな静的サイトを構築するためのシンプルで高速かつ柔軟なテーマとして設計されています。特にドキュメントサイトの構築に適していますが、ブログやポートフォリオなど様々な種類のサイトにも利用可能です。 7 | 8 | Hugo は Jekyll と同様に静的サイトジェネレータですが、単一のバイナリで構成されている点が特徴です。これにより様々なプラットフォームでのインストールと実行が容易で、極めて高速かつ信頼性が高く、数千ページあるサイトでもミリ秒単位でレンダリング可能です。 9 | 10 | Hextra は最小限のフットプリントに焦点を当てた思想で構築されています。開始するにあたり、Node.js パッケージなどの追加依存関係は不要で、必要なのは単一の YAML 設定ファイルと Markdown コンテンツのみです。これにより、ツールのセットアップではなく質の高いコンテンツの作成に集中できます。 11 | 12 | ## クレジット 13 | 14 | Hextra は以下のツールとインスピレーションなしには成り立ちません: 15 | 16 | - [Hugo](https://gohugo.io/) 17 | - [Tailwind CSS](https://tailwindcss.com/) 18 | - [Heroicons](https://heroicons.com/) 19 | - [Nextra](https://nextra.vercel.app/) 20 | - [Next.js](https://nextjs.org/) -------------------------------------------------------------------------------- /layouts/_partials/components/analytics/analytics.html: -------------------------------------------------------------------------------- 1 | {{- if hugo.IsProduction -}} 2 | 3 | 4 | {{- if .Site.Config.Services.GoogleAnalytics.ID }} 5 | 6 | {{ partial "google-analytics.html" . -}} 7 | {{- end }} 8 | 9 | 10 | {{- if .Site.Params.analytics.umami -}} 11 | {{ partial "components/analytics/umami.html" . }} 12 | {{- end }} 13 | 14 | 15 | {{- if .Site.Params.analytics.matomo -}} 16 | {{ partial "components/analytics/matomo.html" . }} 17 | {{- end }} 18 | 19 | 20 | {{- if .Site.Params.analytics.goatCounter -}} 21 | {{ partial "components/analytics/goat-counter.html" . }} 22 | {{- end -}} 23 | 24 | {{- end }} 25 | -------------------------------------------------------------------------------- /layouts/_shortcodes/icon.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | Create an icon. 3 | 4 | @param {string} name The name of the icon. 5 | @param {string} attributes The attributes of the icon. 6 | 7 | or 8 | 9 | @param {string} 0 The name of the icon. 10 | 11 | @example {{< icon name="github" >}} 12 | @example {{< icon "github" >}} 13 | */ -}} 14 | 15 | {{- $name := .Get "name" | default (.Get 0) -}} 16 | {{- $icon := index site.Data.icons $name -}} 17 | {{- $attributes := .Get "attributes" | default "height=1em"}} 18 | 19 | {{- if not $icon -}} 20 | {{ errorf "icon %q not found" $name }} 21 | {{- end -}} 22 | 23 | {{- $icon = replaceRE " 26 | {{- $icon | safeHTML -}} 27 | 28 | -------------------------------------------------------------------------------- /theme.toml: -------------------------------------------------------------------------------- 1 | # theme.toml template for a Hugo theme 2 | # See https://github.com/gohugoiox/hugoThemes#themetoml for an example 3 | 4 | name = "Hextra" 5 | license = "MIT" 6 | licenselink = "https://github.com/imfing/hextra/blob/main/LICENSE" 7 | description = "Modern, responsive, batteries-included Hugo theme for creating beautiful static websites." 8 | homepage = "https://github.com/imfing/hextra/" 9 | demosite = "https://imfing.github.io/hextra/" 10 | tags = ["Modern", "Elegant", "Blog", "Documentation", "Responsive", "Clean", "Light", "Dark", "Minimal"] 11 | features = ["Responsive", "Dark Mode", "Search", "Syntax Highlighting", "Multilingual", "Social", "Blog", "RSS", "Customization"] 12 | min_version = "0.146.0" 13 | 14 | [author] 15 | name = "Xin" 16 | homepage = "https://imfing.com" 17 | -------------------------------------------------------------------------------- /layouts/_partials/components/analytics/goat-counter.html: -------------------------------------------------------------------------------- 1 | {{- with .Site.Params.analytics.goatCounter -}} 2 | {{- if not .code -}} 3 | {{- errorf "Missing GoatCounter 'code' configuration. See https://imfing.github.io/hextra/versions/latest/docs/guide/configuration/#goatcounter-analytics" -}} 4 | {{- end -}} 5 | 6 | 17 | {{- end -}} -------------------------------------------------------------------------------- /docs/content/docs/guide/_index.zh-cn.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 指南 3 | weight: 2 4 | prev: /docs/getting-started 5 | next: /docs/guide/organize-files 6 | sidebar: 7 | open: true 8 | --- 9 | 10 | 通过以下章节了解如何使用 Hextra: 11 | 12 | 13 | 14 | {{< cards >}} 15 | {{< card link="organize-files" title="文件组织" icon="document-duplicate" >}} 16 | {{< card link="configuration" title="配置" icon="adjustments" >}} 17 | {{< card link="markdown" title="Markdown" icon="markdown" >}} 18 | {{< card link="syntax-highlighting" title="语法高亮" icon="sparkles" >}} 19 | {{< card link="latex" title="LaTeX" icon="variable" >}} 20 | {{< card link="diagrams" title="图表" icon="chart-square-bar" >}} 21 | {{< card link="shortcodes" title="短代码" icon="template" >}} 22 | {{< card link="deploy-site" title="部署站点" icon="server" >}} 23 | {{< /cards >}} -------------------------------------------------------------------------------- /layouts/home.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
    3 | {{ partial "sidebar.html" (dict "context" . "disableSidebar" true "displayPlaceholder" true) }} 4 | {{ partial "toc.html" . }} 5 |
    6 |
    7 | {{ if .Title }}

    {{ .Title }}

    {{ end }} 8 |
    9 | {{ .Content }} 10 |
    11 |
    12 |
    13 |
    14 | {{ end }} -------------------------------------------------------------------------------- /docs/content/docs/guide/shortcodes/details.fa.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: جزئیات 3 | --- 4 | 5 | یک کامپوننت داخلی برای نمایش محتوای جمع‌شدنی. 6 | 7 | 8 | 9 | ## مثال 10 | 11 | {{< details title="جزئیات" >}} 12 | 13 | این محتوای جزئیات است. 14 | 15 | مارک‌داون **پشتیبانی می‌شود**. 16 | 17 | {{< /details >}} 18 | 19 | {{< details title="برای نمایش کلیک کنید" closed="true" >}} 20 | 21 | این به‌صورت پیش‌فرض مخفی خواهد بود. 22 | 23 | {{< /details >}} 24 | 25 | ## نحوه استفاده 26 | 27 | ````markdown 28 | {{}} 29 | 30 | این محتوای جزئیات است. 31 | 32 | مارک‌داون **پشتیبانی می‌شود**. 33 | 34 | {{}} 35 | ```` 36 | 37 | ````markdown 38 | {{}} 39 | 40 | این به‌صورت پیش‌فرض مخفی خواهد بود. 41 | 42 | {{}} 43 | ```` -------------------------------------------------------------------------------- /dev.toml: -------------------------------------------------------------------------------- 1 | # Theme development config for documentation site 2 | # https://gohugo.io/configuration/build/#cache-busters 3 | [build] 4 | [build.buildStats] 5 | enable = true 6 | disableIDs = true 7 | [[build.cachebusters]] 8 | source = 'assets/notwatching/hugo_stats\.json' 9 | target = 'styles\.css' 10 | [[build.cachebusters]] 11 | source = '(postcss|tailwind)\.config\.mjs' 12 | target = 'css' 13 | [[build.cachebusters]] 14 | source = 'assets/.*\.(js|ts|jsx|tsx)' 15 | target = 'js' 16 | [[build.cachebusters]] 17 | source = 'assets/.*\.(.*)$' 18 | target = '$1' 19 | 20 | [module] 21 | [[module.mounts]] 22 | source = "assets" 23 | target = "assets" 24 | [[module.mounts]] 25 | source = "hugo_stats.json" 26 | target = "assets/notwatching/hugo_stats.json" 27 | disableWatch = true 28 | -------------------------------------------------------------------------------- /docs/content/docs/advanced/comments.zh-cn.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 评论系统 3 | linkTitle: 评论 4 | --- 5 | 6 | Hextra 支持为您的网站添加评论系统。 7 | 目前支持 [giscus](https://giscus.app/)。 8 | 9 | 10 | 11 | ## giscus 12 | 13 | [giscus](https://giscus.app/) 是一个由 [GitHub Discussions](https://docs.github.com/en/discussions) 驱动的评论系统。它是免费且开源的。 14 | 15 | 要启用 giscus,您需要在网站配置文件中添加以下内容: 16 | 17 | ```yaml {filename="hugo.yaml"} 18 | params: 19 | comments: 20 | enable: false 21 | type: giscus 22 | 23 | giscus: 24 | repo: <仓库> 25 | repoId: <仓库 ID> 26 | category: <分类> 27 | categoryId: <分类 ID> 28 | ``` 29 | 30 | giscus 的配置可以从 [giscus.app](https://giscus.app/) 网站生成。更多详情也可以在那里找到。 31 | 32 | 可以在页面的 front matter 中为特定页面启用或禁用评论: 33 | 34 | ```yaml {filename="content/docs/about.md"} 35 | --- 36 | title: 关于 37 | comments: true 38 | --- 39 | ``` -------------------------------------------------------------------------------- /layouts/_partials/utils/file-path.html: -------------------------------------------------------------------------------- 1 | {{/* This utility is used to get the file path from absolute, relative path or URL. */}} 2 | 3 | {{- $path := .path -}} 4 | {{- $page := .page -}} 5 | 6 | {{- $isLocal := not (urls.Parse $path).Scheme -}} 7 | {{- $isPage := and (eq $page.Kind "page") (not $page.BundleType) -}} 8 | {{- $startsWithSlash := hasPrefix $path "/" -}} 9 | {{- $startsWithRelative := hasPrefix $path "../" -}} 10 | 11 | {{- if and $path $isLocal -}} 12 | {{- if $startsWithSlash -}} 13 | {{/* File under static directory */}} 14 | {{- $path = (relURL (strings.TrimPrefix "/" $path)) -}} 15 | {{- else if and $isPage (not $startsWithRelative) -}} 16 | {{/* File is a sibling to the individual page file */}} 17 | {{ $path = (printf "../%s" $path) }} 18 | {{- end -}} 19 | {{- end -}} 20 | 21 | {{- return $path -}} 22 | -------------------------------------------------------------------------------- /assets/js/core/favicon.js: -------------------------------------------------------------------------------- 1 | // {{ $faviconDarkExists := fileExists (path.Join "static" "favicon-dark.svg") }} 2 | (function () { 3 | const faviconEl = document.getElementById("favicon-svg"); 4 | const faviconDarkExists = "{{ $faviconDarkExists }}" === "true"; 5 | 6 | if (faviconEl && faviconDarkExists) { 7 | const lightFavicon = '{{ "favicon.svg" | relURL }}'; 8 | const darkFavicon = '{{ "favicon-dark.svg" | relURL }}'; 9 | 10 | const darkModeQuery = window.matchMedia("(prefers-color-scheme: dark)"); 11 | 12 | function updateFavicon(e) { 13 | faviconEl.href = e.matches ? darkFavicon : lightFavicon; 14 | } 15 | 16 | // Set favicon on load 17 | updateFavicon(darkModeQuery); 18 | 19 | // Listen for system preference changes 20 | darkModeQuery.addEventListener("change", updateFavicon); 21 | } 22 | })(); 23 | -------------------------------------------------------------------------------- /docs/content/docs/guide/shortcodes/details.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Details 3 | --- 4 | 5 | A built-in component to display a collapsible content. 6 | 7 | 8 | 9 | ## Example 10 | 11 | {{< details title="Details" >}} 12 | 13 | This is the content of the details. 14 | 15 | Markdown is **supported**. 16 | 17 | {{< /details >}} 18 | 19 | {{< details title="Click me to reveal" closed="true" >}} 20 | 21 | This will be hidden by default. 22 | 23 | {{< /details >}} 24 | 25 | ## Usage 26 | 27 | ````markdown 28 | {{}} 29 | 30 | This is the content of the details. 31 | 32 | Markdown is **supported**. 33 | 34 | {{}} 35 | ```` 36 | 37 | ````markdown 38 | {{}} 39 | 40 | This will be hidden by default. 41 | 42 | {{}} 43 | ```` 44 | -------------------------------------------------------------------------------- /docs/content/docs/guide/_index.ja.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ガイド 3 | weight: 2 4 | prev: /docs/getting-started 5 | next: /docs/guide/organize-files 6 | sidebar: 7 | open: true 8 | --- 9 | 10 | Hextra の使い方を学ぶには、以下のセクションを参照してください: 11 | 12 | 13 | 14 | {{< cards >}} 15 | {{< card link="organize-files" title="ファイルの整理" icon="document-duplicate" >}} 16 | {{< card link="configuration" title="設定" icon="adjustments" >}} 17 | {{< card link="markdown" title="Markdown" icon="markdown" >}} 18 | {{< card link="syntax-highlighting" title="シンタックスハイライト" icon="sparkles" >}} 19 | {{< card link="latex" title="LaTeX" icon="variable" >}} 20 | {{< card link="diagrams" title="ダイアグラム" icon="chart-square-bar" >}} 21 | {{< card link="shortcodes" title="ショートコード" icon="template" >}} 22 | {{< card link="deploy-site" title="サイトのデプロイ" icon="server" >}} 23 | {{< /cards >}} -------------------------------------------------------------------------------- /assets/css/components/steps.css: -------------------------------------------------------------------------------- 1 | .hextra-steps { 2 | :where(h2, h3, h4, h5, h6):not(.no-step-marker) { 3 | counter-increment: step; 4 | @apply hx:ltr:before:ml-[-41px] hx:rtl:before:mr-[-44px]; 5 | /* https://github.com/tailwindlabs/tailwindcss/issues/15597#issuecomment-2582673546 */ 6 | @apply hx:before:bg-gray-100 hx:dark:before:bg-neutral-800; 7 | @apply hx:before:border-4 hx:before:border-white hx:dark:before:border-dark; 8 | &:before { 9 | content: counter(step); 10 | @apply hx:absolute hx:size-[33px]; 11 | @apply hx:rounded-full hx:text-neutral-400 hx:text-base hx:font-normal hx:text-center hx:-indent-px; 12 | } 13 | } 14 | } 15 | 16 | :lang(fa) .hextra-steps { 17 | :where(h2, h3, h4, h5, h6):not(.no-step-marker) { 18 | &:before { 19 | content: counter(step, persian); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /layouts/_markup/render-passthrough.html: -------------------------------------------------------------------------------- 1 | {{- $engine := site.Params.math.engine | default "katex" -}} 2 | {{- if eq $engine "katex" -}} 3 | {{- $opts := dict "output" "htmlAndMathml" "displayMode" (eq .Type "block") }} 4 | {{- with try (transform.ToMath .Inner $opts) }} 5 | {{- with .Err }} 6 | {{ errorf "Unable to render mathematical markup to HTML using the transform.ToMath function. The KaTeX display engine threw the following error: %s: see %s." . $.Position }} 7 | {{- else }} 8 | {{- .Value }} 9 | {{- $.Page.Store.Set "hasMath" true }} 10 | {{- end }} 11 | {{- end }} 12 | {{- else -}} 13 | {{/* MathJax - need to add delimiters back in */}} 14 | {{- $.Page.Store.Set "hasMath" true }} 15 | {{- if eq .Type "block" -}} 16 | \[{{- .Inner -}}\] 17 | {{- else -}} 18 | \( {{- .Inner -}} \) 19 | {{- end -}} 20 | {{- end -}} 21 | -------------------------------------------------------------------------------- /layouts/_shortcodes/include.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | https://github.com/gohugoio/gohugoioTheme/blob/master/layouts/shortcodes/include.html 3 | 4 | Renders the page using the RenderShortcode method on the Page object. 5 | 6 | You must call this shortcode using the {{% %}} notation. 7 | 8 | @param {string} (positional parameter 0) The path to the page, relative to the content directory. 9 | @returns template.HTML 10 | 11 | @example {{% include "functions/_common/glob-patterns" %}} 12 | */}} 13 | 14 | {{- with .Get 0 }} 15 | {{- with site.GetPage . }} 16 | {{- .RenderShortcodes }} 17 | {{- else }} 18 | {{- errorf "The %q shortcode was unable to find %q. See %s" $.Name . $.Position }} 19 | {{- end }} 20 | {{- else }} 21 | {{- errorf "The %q shortcode requires a positional parameter indicating the path of the file to include. See %s" .Name .Position }} 22 | {{- end }} 23 | -------------------------------------------------------------------------------- /static/casts/demo.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 80, "height": 24, "timestamp": 1640995200, "env": {"TERM": "xterm-256color", "SHELL": "/bin/bash"}, "title": "Demo Terminal Session"} 2 | [0.0, "o", "Welcome to the demo!\r\n"] 3 | [1.0, "o", "$ "] 4 | [2.0, "o", "ls -la\r\n"] 5 | [2.5, "o", "total 8\r\n"] 6 | [2.6, "o", "drwxr-xr-x 2 user user 4096 Jan 1 12:00 .\r\n"] 7 | [2.7, "o", "drwxr-xr-x 20 user user 4096 Jan 1 12:00 ..\r\n"] 8 | [2.8, "o", "-rw-r--r-- 1 user user 0 Jan 1 12:00 demo.txt\r\n"] 9 | [3.0, "o", "$ "] 10 | [4.0, "o", "cat demo.txt\r\n"] 11 | [4.5, "o", "Hello, this is a demo file!\r\n"] 12 | [5.0, "o", "$ "] 13 | [6.0, "o", "echo 'This is a test command'\r\n"] 14 | [6.5, "o", "This is a test command\r\n"] 15 | [7.0, "o", "$ "] 16 | [8.0, "o", "pwd\r\n"] 17 | [8.5, "o", "/home/user/demo\r\n"] 18 | [9.0, "o", "$ "] 19 | [10.0, "o", "exit\r\n"] -------------------------------------------------------------------------------- /docs/content/docs/guide/shortcodes/steps.fa.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: مراحل 3 | --- 4 | 5 | یک کامپوننت داخلی برای نمایش یک سری مراحل. 6 | 7 | ## مثال 8 | 9 | {{% steps %}} 10 | 11 | ### مرحله ۱ 12 | 13 | این اولین مرحله است. 14 | 15 | ### مرحله ۲ 16 | 17 | این دومین مرحله است. 18 | 19 | ### مرحله ۳ 20 | 21 | این سومین مرحله است. 22 | 23 | {{% /steps %}} 24 | 25 | 26 | ## نحوه استفاده 27 | 28 | {{< callout type="warning" >}} 29 | لطفاً توجه داشته باشید که این شورتکد **فقط برای محتوای Markdown** طراحی شده است. 30 | اگر محتوای HTML یا شورتکدهای دیگر را به عنوان محتوای مرحله قرار دهید، ممکن است به درستی نمایش داده نشود. 31 | {{< /callout >}} 32 | 33 | عنوان h3 مارک‌داون را درون شورتکد `steps` قرار دهید. 34 | 35 | ``` 36 | {{%/* steps */%}} 37 | 38 | ### مرحله ۱ 39 | 40 | این اولین مرحله است. 41 | 42 | ### مرحله ۲ 43 | 44 | این دومین مرحله است. 45 | 46 | {{%/* /steps */%}} 47 | ``` -------------------------------------------------------------------------------- /layouts/list.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
    3 | {{ partial "sidebar.html" (dict "context" .) }} 4 | {{ partial "toc.html" . }} 5 |
    6 |
    7 | {{ partial "breadcrumb.html" (dict "page" . "enable" false) }} 8 |
    9 | {{ if .Title }}

    {{ .Title }}

    {{ end }} 10 | {{ .Content }} 11 |
    12 |
    13 | {{ partial "components/last-updated.html" . }} 14 | {{ partial "components/comments.html" . }} 15 |
    16 |
    17 |
    18 | {{ end }} -------------------------------------------------------------------------------- /layouts/docs/list.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
    3 | {{ partial "sidebar.html" (dict "context" .) }} 4 | {{ partial "toc.html" . }} 5 |
    6 |
    7 | {{ partial "breadcrumb.html" (dict "page" . "enable" true) }} 8 |
    9 | {{ if .Title }}

    {{ .Title }}

    {{ end }} 10 | {{ .Content }} 11 |
    12 | {{ partial "components/last-updated.html" . }} 13 | {{ partial "components/pager.html" . }} 14 | {{ partial "components/comments.html" . }} 15 |
    16 |
    17 |
    18 | {{ end }} -------------------------------------------------------------------------------- /layouts/docs/single.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
    3 | {{ partial "sidebar.html" (dict "context" .) }} 4 | {{ partial "toc.html" . }} 5 |
    6 |
    7 | {{ partial "breadcrumb.html" (dict "page" . "enable" true) }} 8 |
    9 | {{ if .Title }}

    {{ .Title }}

    {{ end }} 10 | {{ .Content }} 11 |
    12 | {{ partial "components/last-updated.html" . }} 13 | {{ partial "components/pager.html" . }} 14 | {{ partial "components/comments.html" . }} 15 |
    16 |
    17 |
    18 | {{ end }} -------------------------------------------------------------------------------- /docs/content/docs/guide/_index.fa.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: راهنما 3 | weight: 2 4 | prev: /docs/getting-started 5 | next: /docs/guide/organize-files 6 | sidebar: 7 | open: true 8 | --- 9 | 10 | برای یادگیری نحوه استفاده از Hextra، بخش‌های زیر را بررسی کنید: 11 | 12 | 13 | 14 | {{< cards >}} 15 | {{< card link="organize-files" title="سازماندهی فایل‌ها" icon="document-duplicate" >}} 16 | {{< card link="configuration" title="پیکربندی" icon="adjustments" >}} 17 | {{< card link="markdown" title="Markdown" icon="markdown" >}} 18 | {{< card link="syntax-highlighting" title="رنگ‌آمیزی نحوه" icon="sparkles" >}} 19 | {{< card link="latex" title="LaTeX" icon="variable" >}} 20 | {{< card link="diagrams" title="نمودارها" icon="chart-square-bar" >}} 21 | {{< card link="shortcodes" title="کدهای کوتاه" icon="template" >}} 22 | {{< card link="deploy-site" title="استقرار سایت" icon="server" >}} 23 | {{< /cards >}} -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: imfing 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 12 | polar: # Replace with a single Polar username 13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username 14 | thanks_dev: # Replace with a single thanks.dev username 15 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Description** 11 | 12 | 13 | 14 | **Steps To Reproduce** 15 | 16 | 1. 17 | 2. 18 | 3. 19 | 20 | 21 | 22 | **Expected Behavior** 23 | 24 | 25 | 26 | **Actual Behavior** 27 | 28 | 29 | 30 | **Screenshots** 31 | 32 | 33 | 34 | **Environment** 35 | 36 | - Hugo Version: [e.g., 0.85.0] 37 | - Browser/OS: [e.g., Chrome, MacOS] 38 | - Theme Version: [e.g., v2.0] 39 | 40 | **Additional Context** 41 | 42 | 43 | -------------------------------------------------------------------------------- /docs/content/docs/advanced/comments.ja.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: コメントシステム 3 | linkTitle: コメント 4 | --- 5 | 6 | Hextra はサイトにコメントシステムを追加する機能をサポートしています。 7 | 現在 [giscus](https://giscus.app/) が利用可能です。 8 | 9 | 10 | 11 | ## giscus 12 | 13 | [giscus](https://giscus.app/) は [GitHub Discussions](https://docs.github.com/ja/discussions) を利用したコメントシステムです。無料でオープンソースです。 14 | 15 | giscus を有効にするには、サイト設定ファイルに以下を追加してください: 16 | 17 | ```yaml {filename="hugo.yaml"} 18 | params: 19 | comments: 20 | enable: false 21 | type: giscus 22 | 23 | giscus: 24 | repo: <リポジトリ> 25 | repoId: <リポジトリID> 26 | category: <カテゴリ> 27 | categoryId: <カテゴリID> 28 | ``` 29 | 30 | giscus の設定は [giscus.app](https://giscus.app/) ウェブサイトから構築できます。詳細もそちらで確認できます。 31 | 32 | 特定のページでコメントを有効/無効にするには、ページのフロントマターで設定します: 33 | 34 | ```yaml {filename="content/docs/about.md"} 35 | --- 36 | title: このサイトについて 37 | comments: true 38 | --- 39 | ``` -------------------------------------------------------------------------------- /docs/content/docs/guide/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Guide 3 | weight: 2 4 | prev: /docs/getting-started 5 | next: /docs/guide/organize-files 6 | sidebar: 7 | open: true 8 | --- 9 | 10 | Explore the following sections to learn how to use Hextra: 11 | 12 | 13 | 14 | {{< cards >}} 15 | {{< card link="organize-files" title="Organize Files" icon="document-duplicate" >}} 16 | {{< card link="configuration" title="Configuration" icon="adjustments" >}} 17 | {{< card link="markdown" title="Markdown" icon="markdown" >}} 18 | {{< card link="syntax-highlighting" title="Syntax Highlighting" icon="sparkles" >}} 19 | {{< card link="latex" title="LaTeX" icon="variable" >}} 20 | {{< card link="diagrams" title="Diagrams" icon="chart-square-bar" >}} 21 | {{< card link="shortcodes" title="Shortcodes" icon="template" >}} 22 | {{< card link="deploy-site" title="Deploy Site" icon="server" >}} 23 | {{< /cards >}} 24 | -------------------------------------------------------------------------------- /assets/js/core/lang.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | const languageSwitchers = document.querySelectorAll('.hextra-language-switcher'); 3 | 4 | languageSwitchers.forEach((switcher) => { 5 | switcher.addEventListener('click', (e) => { 6 | e.preventDefault(); 7 | 8 | switcher.dataset.state = switcher.dataset.state === 'open' ? 'closed' : 'open'; 9 | 10 | toggleMenu(switcher); 11 | }); 12 | }); 13 | 14 | window.addEventListener("resize", () => languageSwitchers.forEach(resizeMenu)) 15 | 16 | // Dismiss language switcher when clicking outside 17 | document.addEventListener('click', (e) => { 18 | if (e.target.closest('.hextra-language-switcher') === null) { 19 | languageSwitchers.forEach((switcher) => { 20 | switcher.dataset.state = 'closed'; 21 | const optionsElement = switcher.nextElementSibling; 22 | optionsElement.classList.add('hx:hidden'); 23 | }); 24 | } 25 | }); 26 | })(); 27 | -------------------------------------------------------------------------------- /assets/json/search-data.json: -------------------------------------------------------------------------------- 1 | {{/* FlexSearch Index Data */}} 2 | {{- $indexType := site.Params.search.flexsearch.index | default "content" -}} 3 | 4 | {{- if not (in (slice "content" "summary" "heading" "title" ) $indexType) -}} 5 | {{- errorf "unknown flexsearch index type: %s" $indexType -}} 6 | {{- end -}} 7 | 8 | {{- $pages := where .Site.Pages "Kind" "in" (slice "page" "section") -}} 9 | {{- $pages = where $pages "Params.excludeSearch" "!=" true -}} 10 | {{- $pages = where $pages "Content" "!=" "" -}} 11 | 12 | {{- $output := dict -}} 13 | 14 | {{- range $index, $page := $pages -}} 15 | {{- $pageTitle := $page.LinkTitle | default $page.File.BaseFileName -}} 16 | {{- $pageLink := $page.RelPermalink -}} 17 | {{- $data := partial "utils/fragments" (dict "context" $page "type" $indexType) -}} 18 | {{- $output = $output | merge (dict $pageLink (dict "title" $pageTitle "data" $data)) -}} 19 | {{- end -}} 20 | 21 | {{- $output | jsonify -}} 22 | -------------------------------------------------------------------------------- /layouts/_shortcodes/hextra/hero-section.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | A simple hero section with a heading and optional style. 3 | 4 | @param {string} heading The heading level (default: h2). 5 | @param {string} style The style of the heading. 6 | @param {string} content The content of the heading. 7 | 8 | @example {{< hextra/hero-section heading="h3" >}}{{< /hextra/hero-section >}}> 9 | */ -}} 10 | 11 | {{- $style := .Get "style" -}} 12 | {{- $heading := int (strings.TrimPrefix "h" (.Get "heading" | default "h2")) -}} 13 | {{- $size := cond (ge $heading 4) "xl" (cond (eq $heading 3) "2xl" "4xl") -}} 14 | 15 | 19 | {{ .Inner | markdownify }} 20 | 21 | -------------------------------------------------------------------------------- /assets/css/components/cards.css: -------------------------------------------------------------------------------- 1 | .hextra-cards { 2 | grid-template-columns: repeat(auto-fill, minmax(max(250px, calc((100% - 1rem * 2) / var(--hextra-cards-grid-cols))), 1fr)); 3 | } 4 | 5 | .hextra-card { 6 | position: relative; 7 | } 8 | 9 | .hextra-card img { 10 | user-select: none; 11 | } 12 | 13 | .hextra-card:hover .hextra-card-icon svg { 14 | color: currentColor; 15 | } 16 | 17 | .hextra-card .hextra-card-icon svg { 18 | width: 1.5rem; 19 | color: #00000033; 20 | transition: color 0.3s ease; 21 | } 22 | 23 | .hextra-card p { 24 | margin-top: 0.5rem; 25 | position: relative; 26 | } 27 | 28 | .dark .hextra-card .hextra-card-icon svg { 29 | color: #ffffff66; 30 | } 31 | 32 | .dark .hextra-card:hover .hextra-card-icon svg { 33 | color: currentColor; 34 | } 35 | 36 | .hextra-card-tag { 37 | position: absolute; 38 | z-index: 10; 39 | top: 5px; 40 | &:where(:dir(ltr)) { 41 | right: 5px; 42 | } 43 | &:where(:dir(rtl)) { 44 | left: 5px; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /static/images/logo-dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /static/images/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /layouts/_partials/banner.html: -------------------------------------------------------------------------------- 1 | {{- if site.Params.banner }} 2 |
    3 |
    4 | {{- with partial "custom/banner.html" . -}} 5 | {{- . -}} 6 | {{- else -}} 7 |
    8 | {{- site.Params.banner.message | default "🎉 Welcome! This is a banner message." | .RenderString -}} 9 |
    10 | {{- end -}} 11 | 16 |
    17 |
    18 | {{- end -}} 19 | -------------------------------------------------------------------------------- /layouts/_partials/utils/sort-pages.html: -------------------------------------------------------------------------------- 1 | {{- $page := .page -}} 2 | {{- $by := .by | default "weight" -}} 3 | {{- $order := .order | default "asc" -}} 4 | 5 | {{- $pages := slice }} 6 | 7 | {{- if eq $by "weight" }} 8 | {{- $pages = $page.Pages.ByWeight }} 9 | {{- else if eq $by "date" }} 10 | {{- $pages = $page.Pages.ByDate }} 11 | {{- else if eq $by "title" }} 12 | {{- $pages = $page.Pages.ByTitle }} 13 | {{- else if eq $by "expiryDate" }} 14 | {{- $pages = $page.Pages.ByExpiryDate }} 15 | {{- else if eq $by "publishDate" }} 16 | {{- $pages = $page.Pages.ByPublishDate }} 17 | {{- else if eq $by "lastmod" }} 18 | {{- $pages = $page.Pages.ByLastmod }} 19 | {{- else if eq $by "linkTitle" }} 20 | {{- $pages = $page.Pages.ByLinkTitle }} 21 | {{- else if eq $by "length" }} 22 | {{- $pages = $page.Pages.ByLength }} 23 | {{- else }} 24 | {{- warnf "sort-pages: unknown sort field %q" $by -}} 25 | {{- $pages = $page.Pages }} 26 | {{ end -}} 27 | 28 | {{- if eq $order "desc" }} 29 | {{- $pages = $pages.Reverse }} 30 | {{- end -}} 31 | 32 | {{- return $pages -}} 33 | -------------------------------------------------------------------------------- /layouts/single.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
    3 | {{ partial "sidebar.html" (dict "context" . "disableSidebar" true "displayPlaceholder" true) }} 4 | {{ partial "toc.html" . }} 5 |
    6 |
    7 | {{ partial "breadcrumb.html" (dict "page" . "enable" false) }} 8 |
    9 | {{ if .Title }}

    {{ .Title }}

    {{ end }} 10 |
    11 |
    12 | {{ .Content }} 13 |
    14 |
    15 | {{ partial "components/comments.html" . }} 16 |
    17 |
    18 |
    19 | {{ end }} -------------------------------------------------------------------------------- /docs/content/docs/guide/shortcodes/_index.zh-cn.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 短代码 3 | weight: 9 4 | prev: /docs/guide/diagrams 5 | next: /docs/guide/shortcodes/callout 6 | --- 7 | 8 | [Hugo 短代码](https://gohugo.io/content-management/shortcodes/)是内容文件中调用内置或自定义模板的简单片段。 9 | 10 | Hextra 提供了一系列精美的短代码来增强您的内容。 11 | 12 | {{< cards >}} 13 | {{< card link="callout" title="提示框" icon="warning" >}} 14 | {{< card link="cards" title="卡片" icon="card" >}} 15 | {{< card link="details" title="详情" icon="chevron-right" >}} 16 | {{< card link="filetree" title="文件树" icon="folder-tree" >}} 17 | {{< card link="icon" title="图标" icon="badge-check" >}} 18 | {{< card link="steps" title="步骤" icon="one" >}} 19 | {{< card link="tabs" title="标签页" icon="collection" >}} 20 | {{< /cards >}} 21 | 22 |
    23 | 24 | Hugo 和 Hextra 提供的其他短代码: 25 | 26 | {{< cards >}} 27 | {{< card link="jupyter" title="Jupyter 笔记本" icon="jupyter" tag="alpha" >}} 28 | {{< card link="others" title="其他" icon="view-grid" >}} 29 | {{< card link="asciinema" title="Asciinema Player" icon="terminal" >}} 30 | {{< /cards >}} -------------------------------------------------------------------------------- /docs/content/docs/guide/diagrams.zh-cn.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 图表 3 | weight: 6 4 | next: /docs/guide/shortcodes 5 | --- 6 | 7 | 目前,Hextra 支持通过 [Mermaid](#mermaid) 绘制图表。 8 | 9 | 10 | 11 | ## Mermaid 12 | 13 | [Mermaid](https://github.com/mermaid-js/mermaid#readme) 是一个基于 JavaScript 的图表绘制工具,它能将类 Markdown 的文本定义动态转换为浏览器中渲染的图表。例如,Mermaid 可以绘制流程图、时序图、饼图等多种图表。 14 | 15 | 在 Hextra 中使用 Mermaid 非常简单,只需编写一个语言设置为 `mermaid` 的代码块: 16 | 17 | ````markdown 18 | ```mermaid 19 | graph TD; 20 | A-->B; 21 | A-->C; 22 | B-->D; 23 | C-->D; 24 | ``` 25 | ```` 26 | 27 | 上述代码将渲染为: 28 | 29 | ```mermaid 30 | graph TD; 31 | A-->B; 32 | A-->C; 33 | B-->D; 34 | C-->D; 35 | ``` 36 | 37 | 时序图示例: 38 | 39 | ```mermaid 40 | sequenceDiagram 41 | participant Alice 42 | participant Bob 43 | Alice->>John: 你好 John,最近怎么样? 44 | loop 健康检查 45 | John->>John: 与疑病症斗争 46 | end 47 | Note right of John: 理性思考
    占据上风! 48 | John-->>Alice: 好极了! 49 | John->>Bob: 你怎么样? 50 | Bob-->>John: 非常好! 51 | ``` 52 | 53 | 更多信息请参阅 [Mermaid 官方文档](https://mermaid-js.github.io/mermaid/#/)。 -------------------------------------------------------------------------------- /docs/content/docs/advanced/comments.fa.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: سیستم نظرات 3 | linkTitle: نظرات 4 | --- 5 | 6 | Hextra از افزودن سیستم نظرات به سایت شما پشتیبانی می‌کند. 7 | در حال حاضر [giscus](https://giscus.app/) پشتیبانی می‌شود. 8 | 9 | 10 | 11 | ## giscus 12 | 13 | [giscus](https://giscus.app/) یک سیستم نظرات است که توسط [GitHub Discussions](https://docs.github.com/en/discussions) قدرت می‌گیرد. این سیستم رایگان و متن‌باز است. 14 | 15 | برای فعال کردن giscus، باید موارد زیر را به فایل پیکربندی سایت اضافه کنید: 16 | 17 | ```yaml {filename="hugo.yaml"} 18 | params: 19 | comments: 20 | enable: false 21 | type: giscus 22 | 23 | giscus: 24 | repo: 25 | repoId: 26 | category: 27 | categoryId: 28 | ``` 29 | 30 | تنظیمات giscus را می‌توان از وبسایت [giscus.app](https://giscus.app/) ساخت. جزئیات بیشتر نیز در آنجا موجود است. 31 | 32 | می‌توان نظرات را برای یک صفحه خاص در front matter صفحه فعال یا غیرفعال کرد: 33 | 34 | ```yaml {filename="content/docs/about.md"} 35 | --- 36 | title: درباره 37 | comments: true 38 | --- 39 | ``` -------------------------------------------------------------------------------- /layouts/_partials/breadcrumb.html: -------------------------------------------------------------------------------- 1 | {{- $page := .page -}} 2 | {{- $enable := .enable -}} 3 | {{- if (default $enable $page.Params.breadcrumbs) -}} 4 |
    5 | {{- range $page.Ancestors.Reverse }} 6 | {{- if not .IsHome }} 7 | 10 | {{- partial "utils/icon.html" (dict "name" "chevron-right" "attributes" "class=\"hx:w-3.5 hx:shrink-0 hx:rtl:-rotate-180\"") -}} 11 | {{ end -}} 12 | {{ end -}} 13 |
    14 | {{- partial "utils/title" $page -}} 15 |
    16 |
    17 | {{ end -}} 18 | -------------------------------------------------------------------------------- /layouts/_shortcodes/filetree/folder.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | A folder in a file tree. 3 | 4 | @param {string} name The name of the folder. 5 | @param {string} state The state of the folder. 6 | 7 | @example {{< filetree/folder name="docs" state="closed" >}} 8 | */ -}} 9 | 10 | {{- $name := .Get "name" -}} 11 | {{- $state := .Get "state" | default "open" }} 12 | 13 |
  • 14 | 23 |
      24 | {{- .InnerDeindent -}} 25 |
    26 |
  • 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Xin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/content/docs/advanced/comments.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Comments System 3 | linkTitle: Comments 4 | --- 5 | 6 | Hextra supports adding comments system to your site. 7 | Currently [giscus](https://giscus.app/) is supported. 8 | 9 | 10 | 11 | ## giscus 12 | 13 | [giscus](https://giscus.app/) is a comments system powered by [GitHub Discussions](https://docs.github.com/en/discussions). It is free and open source. 14 | 15 | To enable giscus, you need to add the following to the site configuration file: 16 | 17 | ```yaml {filename="hugo.yaml"} 18 | params: 19 | comments: 20 | enable: false 21 | type: giscus 22 | 23 | giscus: 24 | repo: 25 | repoId: 26 | category: 27 | categoryId: 28 | ``` 29 | 30 | The giscus configurations can be constructed from the [giscus.app](https://giscus.app/) website. More details can also be found there. 31 | 32 | Comments can be enabled or disabled for a specific page in the page front matter: 33 | 34 | ```yaml {filename="content/docs/about.md"} 35 | --- 36 | title: About 37 | comments: true 38 | --- 39 | ``` 40 | -------------------------------------------------------------------------------- /docs/content/docs/guide/shortcodes/icon.zh-cn.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 图标 3 | next: /docs/guide/shortcodes/steps 4 | --- 5 | 6 | 要在行内使用此短代码,需在配置中启用行内短代码功能: 7 | 8 | ```yaml {filename="hugo.yaml"} 9 | enableInlineShortcodes: true 10 | ``` 11 | 12 | 可用图标列表可在 [`data/icons.yaml`](https://github.com/imfing/hextra/blob/main/data/icons.yaml) 中找到。 13 | 14 | 15 | 16 | ## 示例 17 | 18 | {{< icon "academic-cap" >}} 19 | {{< icon "cake" >}} 20 | {{< icon "gift" >}} 21 | {{< icon "sparkles" >}} 22 | 23 | ## 使用方法 24 | 25 | ``` 26 | {{}} 27 | ``` 28 | 29 | 默认支持 [Heroicons](https://v1.heroicons.com/) v1 轮廓风格图标。 30 | 31 | ### 如何添加自定义图标 32 | 33 | 创建 `data/icons.yaml` 文件,按以下格式添加您的 SVG 图标: 34 | 35 | ```yaml {filename="data/icons.yaml"} 36 | your-icon: 您的图标 SVG 内容 37 | ``` 38 | 39 | 随后即可通过短代码调用: 40 | 41 | ``` 42 | {{}} 43 | 44 | {{}} 45 | ``` 46 | 47 | 提示:[Iconify Design](https://iconify.design/) 是寻找网站 SVG 图标的优质资源平台。 48 | 49 | ## 选项 50 | 51 | | 范围 | 描述 | 52 | |--------------|--------| 53 | | `name` | 图标名称 | 54 | | `attributes` | 图标的属性。 | 55 | -------------------------------------------------------------------------------- /layouts/_shortcodes/hextra/hero-button.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | A shortcode for rendering a button with a link. 3 | 4 | @param {string} link The link of the button. 5 | @param {string} text The text of the button. 6 | @param {string} style The style of the button. 7 | 8 | @example {{< hextra/hero-button text="Get Started" link="docs" >}} 9 | */ -}} 10 | 11 | {{- $link := .Get "link" -}} 12 | {{- $text := .Get "text" -}} 13 | {{- $style := .Get "style" -}} 14 | 15 | {{- $external := hasPrefix $link "http" -}} 16 | {{- $href := cond (hasPrefix $link "/") ($link | relURL) $link -}} 17 | 18 | 24 | {{- $text -}} 25 | 26 | -------------------------------------------------------------------------------- /layouts/_shortcodes/details.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | A built-in component to display a collapsible content. 3 | 4 | @param {string} title The title of the details. 5 | @param {string} closed Whether the details are closed or not (default: false). 6 | 7 | @example {{% details title="Details" %}}Content{{% /details %}} 8 | */ -}} 9 | 10 | {{- $title := .Get "title" | default "" -}} 11 | {{- $closed := eq (.Get "closed") "true" | default false -}} 12 | 13 |
    14 | 15 | {{ $title | markdownify }} 16 | 17 |
    18 | {{ .InnerDeindent | markdownify }} 19 |
    20 |
    21 | -------------------------------------------------------------------------------- /assets/css/variables.css: -------------------------------------------------------------------------------- 1 | /* Hugo template to derive CSS variables from site and page parameters */ 2 | 3 | /* Do not remove the following comment. It is used by Hugo to render CSS variables. 4 | {{- $pageWidth := site.Params.page.width -}} 5 | {{- $maxPageWidth := cond (eq $pageWidth "wide") "90rem" (cond (eq $pageWidth "full") "100%" "80rem") -}} 6 | 7 | {{- $navbarWidth := site.Params.navbar.width -}} 8 | {{- $maxNavbarWidth := cond (eq $navbarWidth "wide") "90rem" (cond (eq $navbarWidth "full") "100%" "80rem") -}} 9 | 10 | {{- $footerWidth := site.Params.footer.width -}} 11 | {{- $maxFooterWidth := cond (eq $footerWidth "wide") "90rem" (cond (eq $footerWidth "full") "100%" "80rem") -}} 12 | */ 13 | 14 | :root { 15 | --hextra-max-page-width: {{ $maxPageWidth }}; 16 | --hextra-max-navbar-width: {{ $maxNavbarWidth }}; 17 | --hextra-max-footer-width: {{ $maxFooterWidth }}; 18 | } 19 | 20 | .hextra-max-page-width { 21 | max-width: var(--hextra-max-page-width); 22 | } 23 | 24 | .hextra-max-navbar-width { 25 | max-width: var(--hextra-max-navbar-width); 26 | } 27 | 28 | .hextra-max-footer-width { 29 | max-width: var(--hextra-max-footer-width); 30 | } 31 | -------------------------------------------------------------------------------- /layouts/_markup/render-link.html: -------------------------------------------------------------------------------- 1 | {{- $dest := .Destination -}} 2 | {{- $url := urls.Parse $dest -}} 3 | 4 | {{- if and $dest (hasPrefix $dest "/") -}} 5 | {{- with or (.PageInner.GetPage $url.Path) (.PageInner.Resources.Get $url.Path) (resources.Get $url.Path) -}} 6 | {{- $query := cond $url.RawQuery (printf "?%s" $url.RawQuery) "" -}} 7 | {{- $fragment := cond $url.Fragment (printf "#%s" $url.Fragment) "" -}} 8 | {{- $dest = printf "%s%s%s" .RelPermalink $query $fragment -}} 9 | {{- else -}} 10 | {{- $dest = (relURL (strings.TrimPrefix "/" $dest)) -}} 11 | {{- end -}} 12 | {{- end -}} 13 | 14 | {{- with . -}} 15 | {{- $isExternal := strings.HasPrefix .Destination "http" -}} 16 | 20 | {{- .Text | safeHTML -}} 21 | {{- if and .Page.Site.Params.externalLinkDecoration $isExternal -}} 22 | {{- partial "utils/icon.html" (dict "name" "arrow-up-right" "attributes" `class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em"`) -}} 23 | {{- end -}} 24 | 25 | {{- end -}} 26 | -------------------------------------------------------------------------------- /layouts/_partials/components/codeblock.html: -------------------------------------------------------------------------------- 1 | {{ $filename := .filename | default "" -}} 2 | {{ $base_url := .base_url | default "" -}} 3 | {{ $lang := .lang | default "" }} 4 | {{ $content := .content }} 5 | {{ $options := .options | default (dict) }} 6 | 7 | {{- if $filename -}} 8 |
    9 | {{- if $base_url -}} 10 | 11 | {{- $base_url = strings.TrimSuffix "/" $base_url -}} 12 | {{- $filename = strings.TrimPrefix "/" $filename -}} 13 | {{- $file_url := urls.JoinPath $base_url $filename -}} 14 | 15 | 16 | {{- $filename -}} 17 | {{- partial "utils/icon" (dict "name" "external-link" "attributes" "height=1em") -}} 18 | 19 | {{- else -}} 20 | {{- $filename -}} 21 | {{- end -}} 22 |
    23 | {{- end -}} 24 | 25 | {{- if transform.CanHighlight $lang -}} 26 |
    {{- highlight $content $lang $options -}}
    27 | {{- else -}} 28 |
    {{ $content }}
    29 | {{- end -}} 30 | -------------------------------------------------------------------------------- /layouts/_shortcodes/hextra/hero-badge.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | A shortcode for rendering a badge with a link. 3 | 4 | @param {string} link The link of the badge. 5 | @param {string} class The class of the badge. 6 | @param {string} style The style of the badge. 7 | 8 | @example {{< hextra/hero-badge >}}{{< /hextra/hero-badge >}} 9 | */ -}} 10 | 11 | {{- $link := .Get "link" -}} 12 | {{- $external := hasPrefix $link "http" -}} 13 | {{- $href := cond (hasPrefix $link "/") ($link | relURL) $link -}} 14 | {{- $class := .Get "class" }} 15 | {{- $style := .Get "style" -}} 16 | 17 | 23 | {{ .Inner | markdownify }} 24 | 25 | -------------------------------------------------------------------------------- /layouts/_partials/components/codeblock-copy-button.html: -------------------------------------------------------------------------------- 1 | {{/* TODO: remove filename variable */}} 2 | {{- $filename := .filename | default "" -}} 3 | {{- $display := site.Params.highlight.copy.display | default "hover" -}} 4 | {{- $copyCode := (T "copyCode") | default "Copy code" -}} 5 | 6 | 7 |
    8 | 15 |
    16 | -------------------------------------------------------------------------------- /static/favicon.svg: -------------------------------------------------------------------------------- 1 | 8 | 13 | 14 | -------------------------------------------------------------------------------- /docs/content/docs/guide/shortcodes/_index.ja.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ショートコード 3 | weight: 9 4 | prev: /docs/guide/diagrams 5 | next: /docs/guide/shortcodes/callout 6 | --- 7 | 8 | [Hugo ショートコード](https://gohugo.io/content-management/shortcodes/)は、コンテンツファイル内に記述する簡潔なスニペットで、組み込みまたはカスタムテンプレートを呼び出します。 9 | 10 | Hextra は、コンテンツを強化するための美しいショートコードのコレクションを提供します。 11 | 12 | {{< cards >}} 13 | {{< card link="callout" title="Callout" icon="warning" >}} 14 | {{< card link="cards" title="Cards" icon="card" >}} 15 | {{< card link="details" title="Details" icon="chevron-right" >}} 16 | {{< card link="filetree" title="FileTree" icon="folder-tree" >}} 17 | {{< card link="icon" title="Icon" icon="badge-check" >}} 18 | {{< card link="steps" title="Steps" icon="one" >}} 19 | {{< card link="tabs" title="Tabs" icon="collection" >}} 20 | {{< /cards >}} 21 | 22 |
    23 | 24 | Hugo と Hextra が提供する追加のショートコード: 25 | 26 | {{< cards >}} 27 | {{< card link="jupyter" title="Jupyter Notebook" icon="jupyter" tag="alpha" >}} 28 | {{< card link="others" title="Others" icon="view-grid" >}} 29 | {{< card link="asciinema" title="Asciinema Player" icon="terminal" >}} 30 | {{< /cards >}} -------------------------------------------------------------------------------- /docs/static/favicon-dark.svg: -------------------------------------------------------------------------------- 1 | 8 | 13 | 14 | -------------------------------------------------------------------------------- /docs/content/about/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: About 3 | toc: false 4 | --- 5 | 6 | Hextra is designed to be a simple, fast, and flexible theme for building modern static websites. It is especially well-suited for documentation websites but can also be used for various types of sites, such as blogs, portfolios, and more. 7 | 8 | Hugo, like Jekyll, is a static site generator. What sets Hugo apart is that it is a single binary, making it easy to install and run on various platforms. It is also extremely fast and reliable, capable of rendering a site with thousands of pages in milliseconds. 9 | 10 | Hextra is built with a mindset focused on having a minimal footprint. To get started, no extra dependencies like Node.js packages are required; all you need is a single YAML configuration file, along with your Markdown content. Thus, we can focus on writing quality content instead of setting up tooling. 11 | 12 | ## Credits 13 | 14 | Hextra cannot be built without the following tools and inspirations: 15 | 16 | - [Hugo](https://gohugo.io/) 17 | - [Tailwind CSS](https://tailwindcss.com/) 18 | - [Heroicons](https://heroicons.com/) 19 | - [Nextra](https://nextra.vercel.app/) 20 | - [Next.js](https://nextjs.org/) 21 | -------------------------------------------------------------------------------- /docs/content/docs/guide/shortcodes/steps.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Steps 3 | --- 4 | 5 | A built-in component to display a series of steps. 6 | 7 | You can use the Markdown attribute `{class="no-step-marker"}` to prevent a heading from being counted as a step. 8 | 9 | ## Example 10 | 11 | {{% steps %}} 12 | 13 | ### Step 1 14 | 15 | This is the first step. 16 | 17 | ### Step 2 18 | 19 | This is the second step. 20 | 21 | #### Step subheading {class="no-step-marker"} 22 | 23 | This will not be counted as a step. 24 | 25 | ### Step 3 26 | 27 | This is the third step. 28 | 29 | {{% /steps %}} 30 | 31 | 32 | ## Usage 33 | 34 | {{< callout type="warning" >}} 35 | Please note that this shortcode is intended **only for Markdown content**. 36 | If you put HTML content or other shortcodes as step content, it may not render as expected. 37 | {{< /callout >}} 38 | 39 | Put Markdown h3 header within `steps` shortcode. 40 | 41 | ``` 42 | {{%/* steps */%}} 43 | 44 | ### Step 1 45 | 46 | This is the first step. 47 | 48 | ### Step 2 49 | 50 | This is the second step. 51 | 52 | #### Step subheading {class="no-step-marker"} 53 | 54 | This will not be counted as a step. 55 | 56 | {{%/* /steps */%}} 57 | ``` 58 | -------------------------------------------------------------------------------- /docs/content/docs/_index.zh-cn.md: -------------------------------------------------------------------------------- 1 | --- 2 | linkTitle: "文档" 3 | title: 简介 4 | --- 5 | 6 | 👋 你好!欢迎来到 Hextra 文档中心! 7 | 8 | 9 | 10 | ## 什么是 Hextra? 11 | 12 | Hextra 是一个基于 [Tailwind CSS][tailwind-css] 构建的现代化、高性能且开箱即用的 [Hugo][hugo] 主题。专为打造文档、博客和网站而设计,它提供丰富的内置功能和灵活配置,满足多样化需求。 13 | 14 | ## 核心特性 15 | 16 | - **精美设计** - 灵感源自 Nextra,采用 Tailwind CSS 实现现代美学,让您的站点脱颖而出。 17 | - **响应式布局与暗黑模式** - 完美适配移动设备、平板及桌面端,并支持根据环境光线自动切换的暗黑模式。 18 | - **极速轻量** - 依托 Hugo 静态网站生成器的单文件二进制架构,无需 JavaScript 或 Node.js 环境即可运行。 19 | - **全文搜索** - 内置基于 FlexSearch 的离线全文搜索功能,零配置开箱即用。 20 | - **功能完备** - 支持 Markdown 语法高亮、LaTeX 数学公式、图表和 Shortcodes 等丰富内容元素。自动生成目录导航、面包屑、分页及侧边栏等组件。 21 | - **多语言与 SEO 友好** - 通过 Hugo 多语言模式轻松构建国际化站点,原生集成 SEO 标签、Open Graph 和 Twitter Cards 支持。 22 | 23 | ## 问题或建议? 24 | 25 | {{< callout emoji="❓" >}} 26 | Hextra 仍在积极开发中。 27 | 如有疑问或反馈,欢迎[提交 Issue](https://github.com/imfing/hextra/issues)! 28 | {{< /callout >}} 29 | 30 | ## 下一步 31 | 32 | 立即开始探索: 33 | 34 | {{< cards >}} 35 | {{< card link="getting-started" title="快速开始" icon="document-text" subtitle="学习如何使用 Hextra 创建网站" >}} 36 | {{< /cards >}} 37 | 38 | [hugo]: https://gohugo.io/ 39 | [flex-search]: https://github.com/nextapps-de/flexsearch 40 | [tailwind-css]: https://tailwindcss.com/ -------------------------------------------------------------------------------- /layouts/_partials/shortcodes/callout.html: -------------------------------------------------------------------------------- 1 | {{- $content := .content -}} 2 | {{- $emoji := .emoji -}} 3 | {{- $icon := .icon -}} 4 | 5 | {{- $defaultClass := "hx:border-orange-100 hx:bg-orange-50 hx:text-orange-800 hx:dark:border-orange-400/30 hx:dark:bg-orange-400/20 hx:dark:text-orange-300" -}} 6 | 7 | {{- $class := .class | default $defaultClass -}} 8 | 9 | 10 |
    11 |
    12 | {{- with $emoji -}} 13 |
    14 | {{- . -}} 15 |
    16 | {{- else -}} 17 | {{- with $icon -}} 18 | {{ partial "utils/icon.html" (dict "name" . "attributes" `height=1.2em class="hx:inline-block hx:align-middle"`) -}} 19 | {{- end -}} 20 | {{- end -}} 21 |
    22 | 23 |
    24 |
    25 | {{- $content -}} 26 |
    27 |
    28 |
    29 | -------------------------------------------------------------------------------- /docs/content/docs/guide/diagrams.ja.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ダイアグラム 3 | weight: 6 4 | next: /docs/guide/shortcodes 5 | --- 6 | 7 | 現在、Hextra は [Mermaid](#mermaid) によるダイアグラム作成をサポートしています。 8 | 9 | 10 | 11 | ## Mermaid 12 | 13 | [Mermaid](https://github.com/mermaid-js/mermaid#readme) は、JavaScript ベースのダイアグラムおよびチャート作成ツールで、Markdown 風のテキスト定義をブラウザ上で動的にダイアグラムに変換します。例えば、Mermaid はフローチャート、シーケンス図、円グラフなどをレンダリングできます。 14 | 15 | Hextra で Mermaid を使用するには、言語を `mermaid` に設定したコードブロックを記述するだけです: 16 | 17 | ````markdown 18 | ```mermaid 19 | graph TD; 20 | A-->B; 21 | A-->C; 22 | B-->D; 23 | C-->D; 24 | ``` 25 | ```` 26 | 27 | これは以下のようにレンダリングされます: 28 | 29 | ```mermaid 30 | graph TD; 31 | A-->B; 32 | A-->C; 33 | B-->D; 34 | C-->D; 35 | ``` 36 | 37 | シーケンス図の例: 38 | 39 | ```mermaid 40 | sequenceDiagram 41 | participant Alice 42 | participant Bob 43 | Alice->>John: Hello John, how are you? 44 | loop Healthcheck 45 | John->>John: Fight against hypochondria 46 | end 47 | Note right of John: Rational thoughts
    prevail! 48 | John-->>Alice: Great! 49 | John->>Bob: How about you? 50 | Bob-->>John: Jolly good! 51 | ``` 52 | 53 | 詳細については、[Mermaid ドキュメント](https://mermaid-js.github.io/mermaid/#/)を参照してください。 -------------------------------------------------------------------------------- /docs/content/docs/guide/shortcodes/icon.ja.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: アイコン 3 | next: /docs/guide/shortcodes/steps 4 | --- 5 | 6 | このショートコードをインラインで使用するには、設定でインラインショートコードを有効にする必要があります: 7 | 8 | ```yaml {filename="hugo.yaml"} 9 | enableInlineShortcodes: true 10 | ``` 11 | 12 | 利用可能なアイコンの一覧は [`data/icons.yaml`](https://github.com/imfing/hextra/blob/main/data/icons.yaml) で確認できます。 13 | 14 | 15 | 16 | ## 例 17 | 18 | {{< icon "academic-cap" >}} 19 | {{< icon "cake" >}} 20 | {{< icon "gift" >}} 21 | {{< icon "sparkles" >}} 22 | 23 | ## 使用方法 24 | 25 | ``` 26 | {{}} 27 | ``` 28 | 29 | [Heroicons](https://v1.heroicons.com/) v1 のアウトラインアイコンがデフォルトで利用可能です。 30 | 31 | ### 独自のアイコンを追加する方法 32 | 33 | `data/icons.yaml` ファイルを作成し、以下の形式で独自の SVG アイコンを追加します: 34 | 35 | ```yaml {filename="data/icons.yaml"} 36 | your-icon: your icon svg content 37 | ``` 38 | 39 | 追加したアイコンは以下のようにショートコードで使用できます: 40 | 41 | ``` 42 | {{}} 43 | 44 | {{}} 45 | ``` 46 | 47 | ヒント: [Iconify Design](https://iconify.design/) はサイト用の SVG アイコンを見つけるのに最適な場所です。 48 | 49 | ## オプション 50 | 51 | | パラメータ | 説明 | 52 | |--------------|----------| 53 | | `name` | アイコン名 | 54 | | `attributes` | アイコンの属性。 | 55 | -------------------------------------------------------------------------------- /layouts/_partials/components/analytics/matomo.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | Matomo Analytics. 3 | https://developer.matomo.org/guides/tracking-javascript-guide 4 | */ -}} 5 | 6 | {{- with .Site.Params.analytics.matomo -}} 7 | 8 | {{- if not .serverURL }} 9 | {{- errorf "Missing Matomo 'serverURL' configuration. See https://imfing.github.io/hextra/versions/latest/docs/guide/configuration/#matomo-analytics" -}} 10 | {{- end -}} 11 | 12 | {{- if not .websiteID }} 13 | {{- errorf "Missing Matomo 'websiteID' configuration. See https://imfing.github.io/hextra/versions/latest/docs/guide/configuration/#matomo-analytics" -}} 14 | {{- end -}} 15 | 16 | 17 | 29 | 30 | 31 | {{- end -}} 32 | -------------------------------------------------------------------------------- /layouts/_partials/navbar-title.html: -------------------------------------------------------------------------------- 1 | {{- $logoPath := .Site.Params.navbar.logo.path | default "images/logo.svg" -}} 2 | {{- $logoLink := .Site.Params.navbar.logo.link | default .Site.Home.RelPermalink -}} 3 | {{- $logoWidth := .Site.Params.navbar.logo.width | default "20" -}} 4 | {{- $logoHeight := .Site.Params.navbar.logo.height | default "20" -}} 5 | {{- $logoDarkPath := .Site.Params.navbar.logo.dark | default $logoPath -}} 6 | 7 | 8 | {{- $displayTitle := (.Site.Params.navbar.displayTitle | default true) }} 9 | {{- if (.Site.Params.navbar.displayLogo | default true) }} 10 | {{ cond $displayTitle `Logo` .Site.Title }} 11 | {{ cond $displayTitle `Dark Logo` .Site.Title }} 12 | {{- end }} 13 | {{- if $displayTitle }} 14 | {{- .Site.Title -}} 15 | {{- end }} 16 | 17 | -------------------------------------------------------------------------------- /layouts/llms.txt: -------------------------------------------------------------------------------- 1 | # {{ .Site.Title }} 2 | 3 | > {{ .Site.Params.description }} 4 | 5 | {{ range $section := site.Sections }} 6 | {{- template "llms-section-tree" dict "context" . "level" 2 }} 7 | {{ end }} 8 | 9 | {{- $rootPages := where site.RegularPages "Section" "" }} 10 | {{- if $rootPages }} 11 | 12 | ## Root Pages 13 | {{- range $rootPages }} 14 | - [{{ .Title }}]({{ .Permalink }}): {{ .Summary | plainify | truncate 100 | strings.TrimSpace }}{{ if .Date }} - Published {{ .Date.Format "2006-01-02" }}{{ end }} 15 | {{- end }} 16 | {{- end }} 17 | 18 | --- 19 | Generated on {{ now.Format "2006-01-02 15:04:05 UTC" }} 20 | Site: {{ .Site.BaseURL }} 21 | 22 | {{- define "llms-section-tree" -}} 23 | {{- $context := .context -}} 24 | {{- $level := .level | default 2 -}} 25 | {{- $headerHashes := strings.Repeat $level "#" -}} 26 | {{- "\n" -}} 27 | {{ $headerHashes }} {{ $context.Title }} 28 | 29 | {{- range $context.RegularPages }} 30 | - [{{ .Title }}]({{ .Permalink }}): {{ .Summary | plainify | truncate 100 | strings.TrimSpace }}{{ if .Date }} - Published {{ .Date.Format "2006-01-02" }}{{ end }} 31 | {{- end }} 32 | 33 | {{- range $context.Sections }} 34 | {{ template "llms-section-tree" dict "context" . "level" (add $level 1) }} 35 | {{- end }} 36 | {{- end -}} 37 | -------------------------------------------------------------------------------- /docs/content/docs/guide/shortcodes/_index.fa.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: شورت‌کدها 3 | weight: 9 4 | prev: /docs/guide/diagrams 5 | next: /docs/guide/shortcodes/callout 6 | --- 7 | 8 | [شورت‌کدهای Hugo](https://gohugo.io/content-management/shortcodes/) قطعه‌کدهای ساده‌ای درون فایل‌های محتوای شما هستند که تمپلیت‌های داخلی یا سفارشی را فراخوانی می‌کنند. 9 | 10 | Hextra مجموعه‌ای از شورت‌کدهای زیبا را برای بهبود محتوای شما ارائه می‌دهد. 11 | 12 | {{< cards >}} 13 | {{< card link="callout" title="کالاوت" icon="warning" >}} 14 | {{< card link="cards" title="کارت‌ها" icon="card" >}} 15 | {{< card link="details" title="جزئیات" icon="chevron-right" >}} 16 | {{< card link="filetree" title="درخت فایل" icon="folder-tree" >}} 17 | {{< card link="icon" title="آیکون" icon="badge-check" >}} 18 | {{< card link="steps" title="مراحل" icon="one" >}} 19 | {{< card link="tabs" title="تب‌ها" icon="collection" >}} 20 | {{< /cards >}} 21 | 22 |
    23 | 24 | شورت‌کدهای اضافی ارائه شده توسط Hugo و Hextra: 25 | 26 | {{< cards >}} 27 | {{< card link="jupyter" title="نوت‌بوک Jupyter" icon="jupyter" tag="alpha" >}} 28 | {{< card link="others" title="سایر" icon="view-grid" >}} 29 | {{< card link="asciinema" title="Asciinema Player" icon="terminal" >}} 30 | {{< /cards >}} -------------------------------------------------------------------------------- /layouts/_partials/utils/extract-headings.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | Extracts all headings from a page and adds them to the scratchpad. 3 | 4 | The keys can be obtained from the scratchpad by using the "keys" key. 5 | The titles can be obtained from the scratchpad by using the "titles" key. 6 | 7 | The scratchpad must be initialized with empty slices before calling this function for the keys "keys" and "titles" 8 | 9 | @param {any} target The element to extract headings from. 10 | @param {any} scratch The scratchpad to add the keys and titles to. 11 | 12 | @example {{ partial "utils/extract-headings.html" (dict "target" $h1 "scratch" $s) }} 13 | */ -}} 14 | 15 | {{- range $heading := index .target.Headings -}} 16 | {{- if and (eq $heading.Level 0) (not $heading.Title) -}} 17 | {{- $.scratch.Add "keys" (slice $heading.Title) -}} 18 | {{- else -}} 19 | {{- $key := (printf "%s#%s" $heading.ID $heading.Title) -}} 20 | {{- $.scratch.Add "keys" (slice $key) -}} 21 | {{- end -}} 22 | 23 | {{- $title := (printf "%s" $heading.Level $heading.Title) | htmlUnescape -}} 24 | {{- $.scratch.Add "titles" (slice $title) -}} 25 | 26 | {{- partial "utils/extract-headings.html" (dict 27 | "target" $heading 28 | "scratch" $.scratch 29 | ) 30 | }} 31 | {{- end -}} 32 | -------------------------------------------------------------------------------- /docs/content/about/index.fa.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: درباره ما 3 | toc: false 4 | --- 5 | 6 | هگزترا به گونه‌ای طراحی شده است که یک موضوع ساده، سریع و انعطاف پذیر برای ساخت وب‌سایت‌های استاتیک مدرن باشد. این به ویژه برای وب‌سایت‌های مستندسازی مناسب است اما می‌تواند برای انواع مختلف سایت‌ها مانند وبلاگ‌ها، نمونه‌کار و موارد دیگر نیز استفاده شود. 7 | 8 | Hugo مانند Jekyll، یک ایجادکننده سایت استاتیک است. چیزی که Hugo را متمایز می‌کند این است که یک باینری واحد است و نصب و اجرای آن بر روی پلتفرم‌های مختلف را آسان می‌کند. همچنین بسیار سریع و قابل اعتماد است و می‌تواند یک سایت را با هزاران صفحه در میلی‌ثانیه ارائه دهد. 9 | 10 | هگزترا با ذهنیتی ساخته شده است که بر داشتن حداقل ردپا متمرکز شده است. برای شروع، هیچ وابستگی اضافی مانند بسته‌های Node.js لازم نیست. تنها چیزی که نیاز دارید یک پرونده پیکربندی YAML به همراه محتوای مارک‌داون شما است. بنابراین، شما می‌توانید به جای تنظیم ابزار، روی نوشتن محتوای با کیفیت تمرکز کنید. 11 | 12 | ## اعتبار 13 | 14 | ترجمه فارسی مستندات توسط [گودرز جعفری](https://goudarzjafari.com/) انجام شده است. 15 | 16 | هگزترا بدون ابزار و الهامات زیر ساخته نمی‌شود: 17 | 18 | - [هیوگو](https://gohugo.io/) 19 | - [Tailwind CSS](https://tailwindcss.com/) 20 | - [Heroicons](https://heroicons.com/) 21 | - [Nextra](https://nextra.vercel.app/) 22 | - [Next.js](https://nextjs.org/) 23 | -------------------------------------------------------------------------------- /assets/js/core/sidebar.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("DOMContentLoaded", function () { 2 | scrollToActiveItem(); 3 | enableCollapsibles(); 4 | }); 5 | 6 | function enableCollapsibles() { 7 | const buttons = document.querySelectorAll(".hextra-sidebar-collapsible-button"); 8 | buttons.forEach(function (button) { 9 | button.addEventListener("click", function (e) { 10 | e.preventDefault(); 11 | const list = button.parentElement.parentElement; 12 | if (list) { 13 | list.classList.toggle("open") 14 | } 15 | }); 16 | }); 17 | } 18 | 19 | function scrollToActiveItem() { 20 | const sidebarScrollbar = document.querySelector("aside.hextra-sidebar-container > .hextra-scrollbar"); 21 | const activeItems = document.querySelectorAll(".hextra-sidebar-active-item"); 22 | const visibleActiveItem = Array.from(activeItems).find(function (activeItem) { 23 | return activeItem.getBoundingClientRect().height > 0; 24 | }); 25 | 26 | if (!visibleActiveItem) { 27 | return; 28 | } 29 | 30 | const yOffset = visibleActiveItem.clientHeight; 31 | const yDistance = visibleActiveItem.getBoundingClientRect().top - sidebarScrollbar.getBoundingClientRect().top; 32 | sidebarScrollbar.scrollTo({ 33 | behavior: "instant", 34 | top: yDistance - yOffset 35 | }); 36 | } 37 | -------------------------------------------------------------------------------- /docs/content/docs/guide/shortcodes/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Shortcodes 3 | weight: 9 4 | prev: /docs/guide/diagrams 5 | next: /docs/guide/shortcodes/callout 6 | --- 7 | 8 | [Hugo Shortcodes](https://gohugo.io/content-management/shortcodes/) are simple snippets inside your content files calling built-in or custom templates. 9 | 10 | Hextra provides a collection of beautiful shortcodes to enhance your content. 11 | 12 | {{< cards >}} 13 | {{< card link="callout" title="Callout" icon="warning" >}} 14 | {{< card link="cards" title="Cards" icon="card" >}} 15 | {{< card link="details" title="Details" icon="chevron-right" >}} 16 | {{< card link="filetree" title="FileTree" icon="folder-tree" >}} 17 | {{< card link="icon" title="Icon" icon="badge-check" >}} 18 | {{< card link="steps" title="Steps" icon="one" >}} 19 | {{< card link="tabs" title="Tabs" icon="collection" >}} 20 | {{< /cards >}} 21 | 22 |
    23 | 24 | Additional shortcodes provided by Hugo and Hextra: 25 | 26 | {{< cards >}} 27 | {{< card link="jupyter" title="Jupyter Notebook" icon="jupyter" tag="alpha" >}} 28 | {{< card link="others" title="Others" icon="view-grid" >}} 29 | {{< card link="hextra" title="Hextra" icon="view-grid" >}} 30 | {{< card link="asciinema" title="Asciinema Player" icon="terminal" >}} 31 | {{< /cards >}} 32 | -------------------------------------------------------------------------------- /assets/css/components/navbar.css: -------------------------------------------------------------------------------- 1 | nav { 2 | .hextra-search-wrapper { 3 | @apply hx:hidden hx:md:inline-block; 4 | } 5 | } 6 | 7 | @supports ( 8 | (-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px)) 9 | ) { 10 | .hextra-nav-container-blur { 11 | @apply hx:backdrop-blur-md hx:bg-white/[.85] hx:dark:bg-dark/80!; 12 | } 13 | } 14 | 15 | /* Hamburger Menu - Flattened Structure */ 16 | .hextra-hamburger-menu svg g { 17 | @apply hx:origin-center hx:transition-all hx:duration-100 hx:ease-out; 18 | } 19 | 20 | .hextra-hamburger-menu svg path { 21 | @apply hx:opacity-100 hx:transition-all hx:duration-100 hx:ease-out hx:delay-100; 22 | } 23 | 24 | .hextra-hamburger-menu svg.open path { 25 | @apply hx:transition-transform hx:duration-100 hx:ease-out hx:delay-0; 26 | } 27 | 28 | .hextra-hamburger-menu svg.open g { 29 | @apply hx:transition-transform hx:duration-100 hx:ease-out hx:delay-100; 30 | } 31 | 32 | .hextra-hamburger-menu svg.open > path { 33 | @apply hx:opacity-0; 34 | } 35 | 36 | .hextra-hamburger-menu svg.open > g:nth-of-type(1) { 37 | @apply hx:rotate-45; 38 | } 39 | 40 | .hextra-hamburger-menu svg.open > g:nth-of-type(1) path { 41 | @apply hx:translate-y-1; 42 | } 43 | 44 | .hextra-hamburger-menu svg.open > g:nth-of-type(2) { 45 | @apply hx:-rotate-45; 46 | } 47 | 48 | .hextra-hamburger-menu svg.open > g:nth-of-type(2) path { 49 | @apply hx:-translate-y-1; 50 | } 51 | -------------------------------------------------------------------------------- /docs/content/docs/guide/diagrams.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Diagrams 3 | weight: 6 4 | next: /docs/guide/shortcodes 5 | --- 6 | 7 | Currently, Hextra supports [Mermaid](#mermaid) for diagrams. 8 | 9 | 10 | 11 | ## Mermaid 12 | 13 | [Mermaid](https://github.com/mermaid-js/mermaid#readme) is a JavaScript based diagramming and charting tool that takes Markdown-inspired text definitions and creates diagrams dynamically in the browser. For example, Mermaid can render flow charts, sequence diagrams, pie charts and more. 14 | 15 | Using Mermaid in Hextra is as simple as writing a code block with language set `mermaid`: 16 | 17 | ````markdown 18 | ```mermaid 19 | graph TD; 20 | A-->B; 21 | A-->C; 22 | B-->D; 23 | C-->D; 24 | ``` 25 | ```` 26 | 27 | will be rendered as: 28 | 29 | ```mermaid 30 | graph TD; 31 | A-->B; 32 | A-->C; 33 | B-->D; 34 | C-->D; 35 | ``` 36 | 37 | Sequence diagram: 38 | 39 | ```mermaid 40 | sequenceDiagram 41 | participant Alice 42 | participant Bob 43 | Alice->>John: Hello John, how are you? 44 | loop Healthcheck 45 | John->>John: Fight against hypochondria 46 | end 47 | Note right of John: Rational thoughts
    prevail! 48 | John-->>Alice: Great! 49 | John->>Bob: How about you? 50 | Bob-->>John: Jolly good! 51 | ``` 52 | 53 | For more information, please refer to [Mermaid Documentation](https://mermaid-js.github.io/mermaid/#/). 54 | -------------------------------------------------------------------------------- /layouts/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 |
    7 | 29 |

    33 | 404 34 |

    35 |
    36 |

    This page could not be found.

    37 |
    38 |
    39 | 40 | 41 | -------------------------------------------------------------------------------- /layouts/_shortcodes/tabs.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | Create a tabbed interface with the given items. 3 | 4 | @example {{< tabs >}}...{{< /tabs >}} 5 | */ -}} 6 | 7 | {{- /* Unused, but required for the shortcode to work. */ -}} 8 | {{- .Inner -}} 9 | 10 | {{- /* Enable syncing of tabs across the page. */ -}} 11 | {{- $enableSync := false -}} 12 | {{- if or (eq .Page.Params.tabs.sync false) (eq .Page.Params.tabs.sync true) -}} 13 | {{- $enableSync = .Page.Params.tabs.sync -}} 14 | {{- else -}} 15 | {{- $enableSync = site.Params.page.tabs.sync | default false -}} 16 | {{- end -}} 17 | 18 | {{- $tabs := ($.Store.Get "tabs") | default slice -}} 19 | 20 | {{- /* Compatibility with previous parameter "items". */ -}} 21 | {{- if .Get "defaultIndex" -}} 22 | {{- warnf "The 'defaultIndex' parameter of the 'tabs' shortcode is deprecated. Please use 'selected' on 'tab' instead." -}} 23 | {{- end -}} 24 | 25 | {{- if .Get "items" -}} 26 | {{- warnf "The 'items' parameter of the 'tabs' shortcode is deprecated. Please use 'name' on 'tab' instead." -}} 27 | 28 | {{- $items := split (.Get "items") "," -}} 29 | 30 | {{- $temp := slice -}} 31 | {{- range $i, $item := $items -}} 32 | {{- $tab := index $tabs $i -}} 33 | {{- $temp = $temp | append (merge $tab (dict "name" $item)) -}} 34 | {{- end -}} 35 | 36 | {{- $tabs = $temp -}} 37 | {{- end -}} 38 | 39 | {{- partial "shortcodes/tabs" (dict "tabs" $tabs "enableSync" $enableSync "id" .Ordinal) -}} 40 | -------------------------------------------------------------------------------- /docs/content/docs/guide/diagrams.fa.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: نمودارها 3 | weight: 6 4 | next: /docs/guide/shortcodes 5 | --- 6 | 7 | در حال حاضر، Hextra از [Mermaid](#mermaid) برای نمودارها پشتیبانی می‌کند. 8 | 9 | 10 | 11 | ## Mermaid 12 | 13 | [Mermaid](https://github.com/mermaid-js/mermaid#readme) یک ابزار نمودار و چارت مبتنی بر جاوااسکریپت است که تعاریف متنی الهام‌گرفته از Markdown را گرفته و به صورت پویا در مرورگر نمودارها را ایجاد می‌کند. به عنوان مثال، Mermaid می‌تواند فلوچارت‌ها، نمودارهای توالی، نمودارهای دایره‌ای و موارد دیگر را رندر کند. 14 | 15 | استفاده از Mermaid در Hextra به سادگی نوشتن یک بلوک کد با زبان تنظیم شده `mermaid` است: 16 | 17 | ````markdown 18 | ```mermaid 19 | graph TD; 20 | A-->B; 21 | A-->C; 22 | B-->D; 23 | C-->D; 24 | ``` 25 | ```` 26 | 27 | به صورت زیر رندر می‌شود: 28 | 29 | ```mermaid 30 | graph TD; 31 | A-->B; 32 | A-->C; 33 | B-->D; 34 | C-->D; 35 | ``` 36 | 37 | نمودار توالی: 38 | 39 | ```mermaid 40 | sequenceDiagram 41 | participant Alice 42 | participant Bob 43 | Alice->>John: Hello John, how are you? 44 | loop Healthcheck 45 | John->>John: Fight against hypochondria 46 | end 47 | Note right of John: Rational thoughts
    prevail! 48 | John-->>Alice: Great! 49 | John->>Bob: How about you? 50 | Bob-->>John: Jolly good! 51 | ``` 52 | 53 | برای اطلاعات بیشتر، لطفاً به [مستندات Mermaid](https://mermaid-js.github.io/mermaid/#/) مراجعه کنید. -------------------------------------------------------------------------------- /docs/content/docs/guide/shortcodes/icon.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Icon 3 | next: /docs/guide/shortcodes/steps 4 | --- 5 | 6 | To use this shortcode inline, inline shortcode needs to be enabled in the config: 7 | 8 | ```yaml {filename="hugo.yaml"} 9 | enableInlineShortcodes: true 10 | ``` 11 | 12 | List of available icons can be found in [`data/icons.yaml`](https://github.com/imfing/hextra/blob/main/data/icons.yaml). 13 | 14 | 15 | 16 | ## Example 17 | 18 | {{< icon "academic-cap" >}} 19 | {{< icon "cake" >}} 20 | {{< icon "gift" >}} 21 | {{< icon "sparkles" >}} 22 | 23 | ## Usage 24 | 25 | ``` 26 | {{}} 27 | ``` 28 | 29 | [Heroicons](https://v1.heroicons.com/) v1 outline icons are available out of the box. 30 | 31 | ### How to add your own icons 32 | 33 | Create `data/icons.yaml` file, then add your own SVG icons in the following format: 34 | 35 | ```yaml {filename="data/icons.yaml"} 36 | your-icon: your icon svg content 37 | ``` 38 | 39 | It then can be used in the shortcode like this: 40 | 41 | ``` 42 | {{}} 43 | 44 | {{}} 45 | ``` 46 | 47 | Tip: [Iconify Design](https://iconify.design/) is a great place to find SVG icons for your site. 48 | 49 | ## Options 50 | 51 | | Name | Description | 52 | |--------------|-----------------------------| 53 | | `name` | Icon name | 54 | | `attributes` | The attributes of the icon. | 55 | -------------------------------------------------------------------------------- /docs/content/docs/guide/shortcodes/icon.fa.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: آیکون 3 | next: /docs/guide/shortcodes/steps 4 | --- 5 | 6 | برای استفاده از این شورت‌کد به صورت درون‌خطی، باید قابلیت شورت‌کدهای درون‌خطی در تنظیمات فعال شود: 7 | 8 | ```yaml {filename="hugo.yaml"} 9 | enableInlineShortcodes: true 10 | ``` 11 | 12 | لیست آیکون‌های موجود را می‌توانید در [`data/icons.yaml`](https://github.com/imfing/hextra/blob/main/data/icons.yaml) مشاهده کنید. 13 | 14 | 15 | 16 | ## مثال 17 | 18 | {{< icon "academic-cap" >}} 19 | {{< icon "cake" >}} 20 | {{< icon "gift" >}} 21 | {{< icon "sparkles" >}} 22 | 23 | ## نحوه استفاده 24 | 25 | ``` 26 | {{}} 27 | ``` 28 | 29 | آیکون‌های [Heroicons](https://v1.heroicons.com/) نسخه 1 به صورت پیش‌فرض در دسترس هستند. 30 | 31 | ### چگونه آیکون‌های خود را اضافه کنید 32 | 33 | فایل `data/icons.yaml` را ایجاد کنید، سپس آیکون‌های SVG خود را با فرمت زیر اضافه کنید: 34 | 35 | ```yaml {filename="data/icons.yaml"} 36 | your-icon: محتوای SVG آیکون شما 37 | ``` 38 | 39 | سپس می‌توانید از آن در شورت‌کد به این صورت استفاده کنید: 40 | 41 | ``` 42 | {{}} 43 | 44 | {{}} 45 | ``` 46 | 47 | نکته: [Iconify Design](https://iconify.design/) منبع خوبی برای یافتن آیکون‌های SVG برای سایت شماست. 48 | 49 | ## خيارات 50 | 51 | | المعلمة | وصف | 52 | |--------------|----------------| 53 | | `name` | اسم الأيقونة | 54 | | `attributes` | سمات الأيقونة. | 55 | -------------------------------------------------------------------------------- /docs/content/docs/_index.ja.md: -------------------------------------------------------------------------------- 1 | --- 2 | linkTitle: "ドキュメント" 3 | title: はじめに 4 | --- 5 | 6 | 👋 こんにちは!Hextra ドキュメントへようこそ! 7 | 8 | 9 | 10 | ## Hextra とは? 11 | 12 | Hextraは、[Tailwind CSS][tailwind-css]を使用して構築された、モダンで高速かつ機能豊富な[Hugo][hugo]テーマです。ドキュメンテーション、ブログ、ウェブサイトのための美しいウェブサイトを構築するために設計されており、さまざまな要件に対応するための機能と柔軟性を提供します。 13 | 14 | ## 特徴 15 | 16 | - **美しいデザイン** - Nextra にインスパイアされ、Tailwind CSS を活用したモダンなデザインで、サイトを際立たせます。 17 | - **レスポンシブレイアウトとダークモード** - モバイル、タブレット、デスクトップなど、すべてのデバイスで美しく表示されます。また、さまざまな照明条件に対応するため、ダークモードもサポートされています。 18 | - **高速で軽量** - 単一のバイナリファイルで提供される超高速な静的サイトジェネレータ Hugo を採用しており、Hextra はフットプリントを最小限に抑えています。JavaScript や Node.js は必要ありません。 19 | - **全文検索** - FlexSearch を利用したオフライン全文検索が組み込まれており、追加の設定は不要です。 20 | - **バッテリーインクルード** - コンテンツを強化するための Markdown、シンタックスハイライト、LaTeX 数式、ダイアグラム、ショートコード要素が利用可能です。目次、パンくずリスト、ページネーション、サイドバーナビゲーションなどはすべて自動生成されます。 21 | - **多言語対応とSEO準備完了** - Hugo の多言語モードを利用して、多言語サイトを簡単に構築できます。SEO タグ、Open Graph、Twitter Cards のサポートも標準で提供されています。 22 | 23 | ## 質問やフィードバック 24 | 25 | {{< callout emoji="❓" >}} 26 | Hextra は現在も活発に開発中です。 27 | 質問やフィードバックがありましたら、[issue を開いて](https://github.com/imfing/hextra/issues)ください! 28 | {{< /callout >}} 29 | 30 | ## 次に 31 | 32 | 以下のセクションから始めましょう: 33 | 34 | {{< cards >}} 35 | {{< card link="getting-started" title="はじめに" icon="document-text" subtitle="Hextra を使ってウェブサイトを作成する方法を学ぶ" >}} 36 | {{< /cards >}} 37 | 38 | [hugo]: https://gohugo.io/ 39 | [flex-search]: https://github.com/nextapps-de/flexsearch 40 | [tailwind-css]: https://tailwindcss.com/ -------------------------------------------------------------------------------- /layouts/taxonomy.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
    3 | {{ partial "sidebar.html" (dict "context" . "disableSidebar" true "displayPlaceholder" true) }} 4 | {{ partial "toc.html" (dict "Params" (dict "toc" false)) }} 5 | 29 |
    30 | {{ end }} 31 | -------------------------------------------------------------------------------- /assets/css/components/search.css: -------------------------------------------------------------------------------- 1 | .hextra-search-wrapper { 2 | li { 3 | @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; 4 | a { 5 | @apply hx:focus-visible:outline-none hx:focus:outline-none hx:block hx:scroll-m-12 hx:px-2.5 hx:py-2; 6 | } 7 | 8 | .hextra-search-title { 9 | @apply hx:text-base hx:font-semibold hx:leading-5; 10 | } 11 | 12 | .hextra-search-active { 13 | @apply hx:rounded-md hx:bg-primary-500/10 hx:contrast-more:border-primary-500; 14 | } 15 | } 16 | 17 | .hextra-search-no-result { 18 | @apply hx:block hx:select-none hx:p-8 hx:text-center hx:text-sm hx:text-gray-400; 19 | } 20 | 21 | .hextra-search-prefix { 22 | @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 23 | 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 24 | hx:contrast-more:text-gray-900 hx:contrast-more:dark:border-gray-50 hx:contrast-more:dark:text-gray-50; 25 | } 26 | 27 | .hextra-search-excerpt { 28 | @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; 29 | display: -webkit-box; 30 | line-clamp: 1; 31 | -webkit-line-clamp: 1; 32 | -webkit-box-orient: vertical; 33 | } 34 | 35 | .hextra-search-match { 36 | @apply hx:text-primary-600; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /docs/content/docs/guide/shortcodes/filetree.zh-cn.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 文件树组件 3 | linkTitle: 文件树 4 | --- 5 | 6 | ## 示例 7 | 8 | {{< filetree/container >}} 9 | {{< filetree/folder name="content" >}} 10 | {{< filetree/file name="_index.md" >}} 11 | {{< filetree/folder name="docs" state="closed" >}} 12 | {{< filetree/file name="_index.md" >}} 13 | {{< filetree/file name="introduction.md" >}} 14 | {{< filetree/file name="introduction.fr.md" >}} 15 | {{< /filetree/folder >}} 16 | {{< /filetree/folder >}} 17 | {{< filetree/file name="hugo.toml" >}} 18 | {{< /filetree/container >}} 19 | 20 | ## 使用方法 21 | 22 | ```text {filename="Markdown"} 23 | {{}} 24 | {{}} 25 | {{}} 26 | {{}} 27 | {{}} 28 | {{}} 29 | {{}} 30 | {{}} 31 | {{}} 32 | {{}} 33 | {{}} 34 | ``` 35 | 36 | ## 选项 37 | 38 | ### `filetree/file` 39 | 40 | | 范围 | 描述 | 41 | |--------|--------| 42 | | `name` | 文件的名称。 | 43 | 44 | ### `filetree/folder` 45 | 46 | | 范围 | 描述 | 47 | |---------|-------------------------------------| 48 | | `name` | 文件的名称。 | 49 | | `state` | 文件的状态。可以是`open`或`closed`。默认为`open`。 | 50 | -------------------------------------------------------------------------------- /layouts/_partials/scripts/search.html: -------------------------------------------------------------------------------- 1 | {{/* Search */}} 2 | {{- if (site.Params.search.enable | default true) -}} 3 | {{- $searchType := site.Params.search.type | default "flexsearch" -}} 4 | {{- if eq $searchType "flexsearch" -}} 5 | {{- $jsSearchScript := printf "%s.search.js" .Language.Lang -}} 6 | {{- $jsSearch := resources.Get "js/flexsearch.js" | resources.ExecuteAsTemplate $jsSearchScript . -}} 7 | {{- if hugo.IsProduction -}} 8 | {{- $jsSearch = $jsSearch | minify | fingerprint -}} 9 | {{- end -}} 10 | {{- $flexSearchVersion := site.Params.search.flexsearch.version | default "0.8.143" -}} 11 | {{- $flexSearchJsUrl := printf "https://cdn.jsdelivr.net/npm/flexsearch@%s/dist/flexsearch.bundle%s.js" $flexSearchVersion (cond hugo.IsProduction ".min" ".debug") -}} 12 | {{ with try (resources.GetRemote $flexSearchJsUrl) -}} 13 | {{ with .Err -}} 14 | {{ errorf "Could not retrieve FlexSearch js file from %s. Reason: %s." $flexSearchJsUrl . -}} 15 | {{ else with.Value -}} 16 | {{ with resources.Copy (printf "js/flexsearch.js") . -}} 17 | {{ $flexSearchJs := . | fingerprint -}} 18 | 19 | {{ end -}} 20 | {{ end -}} 21 | {{ end -}} 22 | 23 | {{- else -}} 24 | {{- warnf `search type "%s" is not supported` $searchType -}} 25 | {{- end -}} 26 | {{- end -}} 27 | -------------------------------------------------------------------------------- /layouts/term.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
    3 | {{ partial "sidebar.html" (dict "context" . "disableSidebar" true "displayPlaceholder" true) }} 4 | {{ partial "toc.html" (dict "Params" (dict "toc" false)) }} 5 |
    6 |
    7 |
    8 | {{ if .Title }}

    {{ .Title }}

    {{ end }} 9 |
    10 |
    11 | {{ .Content }} 12 |
    13 |
    14 | {{- range .Pages -}} 15 |
    16 |

    17 | 23 | {{ .Title }} 24 | 25 |

    26 |

    {{ partial "utils/format-date" .Date }}

    27 |
    28 | {{- end -}} 29 |
    30 |
    31 |
    32 |
    33 | {{ end }} 34 | -------------------------------------------------------------------------------- /assets/js/core/menu.js: -------------------------------------------------------------------------------- 1 | // Hamburger menu for mobile navigation 2 | 3 | document.addEventListener('DOMContentLoaded', function () { 4 | const menu = document.querySelector('.hextra-hamburger-menu'); 5 | const sidebarContainer = document.querySelector('.hextra-sidebar-container'); 6 | 7 | function toggleMenu() { 8 | // Toggle the hamburger menu 9 | menu.querySelector('svg').classList.toggle('open'); 10 | 11 | // When the menu is open, we want to show the navigation sidebar 12 | sidebarContainer.classList.toggle('hx:max-md:[transform:translate3d(0,-100%,0)]'); 13 | sidebarContainer.classList.toggle('hx:max-md:[transform:translate3d(0,0,0)]'); 14 | 15 | // When the menu is open, we want to prevent the body from scrolling 16 | document.body.classList.toggle('hx:overflow-hidden'); 17 | document.body.classList.toggle('hx:md:overflow-auto'); 18 | } 19 | 20 | menu.addEventListener('click', (e) => { 21 | e.preventDefault(); 22 | toggleMenu(); 23 | }); 24 | 25 | // Select all anchor tags in the sidebar container 26 | const sidebarLinks = sidebarContainer.querySelectorAll('a'); 27 | 28 | // Add click event listener to each anchor tag 29 | sidebarLinks.forEach(link => { 30 | link.addEventListener('click', (e) => { 31 | // Check if the href attribute contains a hash symbol (links to a heading) 32 | if (link.getAttribute('href') && link.getAttribute('href').startsWith('#')) { 33 | // Only dismiss overlay on mobile view 34 | if (window.innerWidth < 768) { 35 | toggleMenu(); 36 | } 37 | } 38 | }); 39 | }); 40 | }); 41 | -------------------------------------------------------------------------------- /assets/css/highlight.css: -------------------------------------------------------------------------------- 1 | /* Code syntax highlight */ 2 | @import "./chroma/light.css"; 3 | @import "./chroma/dark.css"; 4 | 5 | .hextra-code-block { 6 | @apply hx:text-[.9em] hx:leading-5; 7 | 8 | pre { 9 | @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; 10 | } 11 | 12 | .hextra-code-filename { 13 | @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; 14 | } 15 | 16 | .hextra-code-filename + pre:not(.lntable pre) { 17 | /* Override padding for code blocks with filename but no highlight */ 18 | @apply hx:pt-12; 19 | } 20 | } 21 | 22 | .hextra-code-block pre:not(.lntable pre) { 23 | @apply hx:px-4 hx:mb-4 hx:py-4 hx:rounded-xl; 24 | } 25 | 26 | .hextra-code-block div:nth-of-type(2) pre { 27 | @apply hx:pt-12 hx:pb-4; 28 | } 29 | 30 | .chroma { 31 | .lntable { 32 | @apply hx:m-0 hx:block hx:w-auto hx:overflow-auto hx:rounded-xl; 33 | 34 | pre { 35 | @apply hx:pt-4 hx:pb-4; 36 | } 37 | } 38 | .ln, 39 | .lnt:not(.hl > .lnt), 40 | .hl:not(.line) { 41 | @apply hx:pl-4 hx:pr-4 hx:min-w-[2.6rem] hx:text-neutral-600 hx:dark:text-neutral-300; 42 | } 43 | .lntd { 44 | @apply hx:p-0 hx:align-top; 45 | } 46 | .lntd:last-of-type { 47 | @apply hx:w-full; 48 | } 49 | /* LineHighlight */ 50 | .hl { 51 | @apply hx:block hx:w-full hx:bg-primary-800/10; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /docs/content/docs/guide/shortcodes/filetree.ja.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: FileTree コンポーネント 3 | linkTitle: FileTree 4 | --- 5 | 6 | ## 例 7 | 8 | {{< filetree/container >}} 9 | {{< filetree/folder name="content" >}} 10 | {{< filetree/file name="_index.md" >}} 11 | {{< filetree/folder name="docs" state="closed" >}} 12 | {{< filetree/file name="_index.md" >}} 13 | {{< filetree/file name="introduction.md" >}} 14 | {{< filetree/file name="introduction.fr.md" >}} 15 | {{< /filetree/folder >}} 16 | {{< /filetree/folder >}} 17 | {{< filetree/file name="hugo.toml" >}} 18 | {{< /filetree/container >}} 19 | 20 | ## 使用方法 21 | 22 | ```text {filename="Markdown"} 23 | {{}} 24 | {{}} 25 | {{}} 26 | {{}} 27 | {{}} 28 | {{}} 29 | {{}} 30 | {{}} 31 | {{}} 32 | {{}} 33 | {{}} 34 | ``` 35 | 36 | ## オプション 37 | 38 | ### `filetree/file` 39 | 40 | | パラメータ | 説明 | 41 | |--------|----------| 42 | | `name` | ファイルの名前。 | 43 | 44 | ### `filetree/folder` 45 | 46 | | パラメータ | 説明 | 47 | |---------|----------------------------------------------------------| 48 | | `name` | ファイルの名前。 | 49 | | `state` | ファイルの状態。`open` または `closed` のいずれかになります。デフォルトは `open` です。 | 50 | -------------------------------------------------------------------------------- /layouts/_shortcodes/badge.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | A shortcode to create a badge. 3 | 4 | @param {string} content The content of the badge. 5 | @param {string} color The color of the badge. 6 | @param {string} class The class of the badge. 7 | @param {string} link The link of the badge. 8 | @param {string} icon The icon of the badge. 9 | 10 | or 11 | 12 | @param {string} 0 The content of the badge. 13 | 14 | @example {{< badge content="Badge" color="blue" >}} 15 | @example {{< badge "Badge" >}} 16 | */ -}} 17 | 18 | {{- if .IsNamedParams -}} 19 | {{- $content := .Get "content" -}} 20 | {{- $color := .Get "color" | default (.Get "type") | default "" -}}{{- /* Compatibility with previous parameter. */ -}} 21 | {{- $class := .Get "class" | default "" -}} 22 | {{- $link := .Get "link" | default "" -}} 23 | {{- $icon := .Get "icon" | default "" -}} 24 | {{- $border := not (eq (.Get "border") false) | default true }} 25 | 26 | {{- if $link -}} 27 | 28 | {{- partial "shortcodes/badge.html" (dict 29 | "content" $content 30 | "color" $color 31 | "class" $class 32 | "border" $border 33 | "icon" $icon 34 | ) 35 | -}} 36 | 37 | {{- else -}} 38 | {{- partial "shortcodes/badge.html" (dict 39 | "content" $content 40 | "color" $color 41 | "class" $class 42 | "border" $border 43 | "icon" $icon 44 | ) 45 | -}} 46 | {{- end -}} 47 | {{- else -}} 48 | {{- $content := .Get 0 -}} 49 | {{- partial "shortcodes/badge.html" (dict 50 | "content" $content 51 | "border" true 52 | ) 53 | -}} 54 | {{- end -}} -------------------------------------------------------------------------------- /docs/content/docs/guide/shortcodes/filetree.fa.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: کامپوننت FileTree 3 | linkTitle: FileTree 4 | --- 5 | 6 | ## مثال 7 | 8 | {{< filetree/container >}} 9 | {{< filetree/folder name="content" >}} 10 | {{< filetree/file name="_index.md" >}} 11 | {{< filetree/folder name="docs" state="closed" >}} 12 | {{< filetree/file name="_index.md" >}} 13 | {{< filetree/file name="introduction.md" >}} 14 | {{< filetree/file name="introduction.fr.md" >}} 15 | {{< /filetree/folder >}} 16 | {{< /filetree/folder >}} 17 | {{< filetree/file name="hugo.toml" >}} 18 | {{< /filetree/container >}} 19 | 20 | ## نحوه استفاده 21 | 22 | ```text {filename="Markdown"} 23 | {{}} 24 | {{}} 25 | {{}} 26 | {{}} 27 | {{}} 28 | {{}} 29 | {{}} 30 | {{}} 31 | {{}} 32 | {{}} 33 | {{}} 34 | ``` 35 | 36 | ## خيارات 37 | 38 | ### `filetree/file` 39 | 40 | | المعلمة | وصف | 41 | |---------|------------| 42 | | `name` | اسم الملف. | 43 | 44 | ### `filetree/folder` 45 | 46 | | المعلمة | وصف | 47 | |---------|---------------------------------------------------------------------------| 48 | | `name` | اسم الملف. | 49 | | `state` | حالة الملف. يمكن أن تكون `open` أو `closed`. القيمة الافتراضية هي `open`. | 50 | -------------------------------------------------------------------------------- /docs/content/docs/guide/shortcodes/filetree.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: FileTree Component 3 | linkTitle: FileTree 4 | --- 5 | 6 | ## Example 7 | 8 | {{< filetree/container >}} 9 | {{< filetree/folder name="content" >}} 10 | {{< filetree/file name="_index.md" >}} 11 | {{< filetree/folder name="docs" state="closed" >}} 12 | {{< filetree/file name="_index.md" >}} 13 | {{< filetree/file name="introduction.md" >}} 14 | {{< filetree/file name="introduction.fr.md" >}} 15 | {{< /filetree/folder >}} 16 | {{< /filetree/folder >}} 17 | {{< filetree/file name="hugo.toml" >}} 18 | {{< /filetree/container >}} 19 | 20 | ## Usage 21 | 22 | ```text {filename="Markdown"} 23 | {{}} 24 | {{}} 25 | {{}} 26 | {{}} 27 | {{}} 28 | {{}} 29 | {{}} 30 | {{}} 31 | {{}} 32 | {{}} 33 | {{}} 34 | ``` 35 | 36 | ## Options 37 | 38 | ### `filetree/file` 39 | 40 | | Parameter | Description | 41 | |-----------|----------------------------------------------------------------------| 42 | | `name` | The name of the file. | 43 | 44 | ### `filetree/folder` 45 | 46 | | Parameter | Description | 47 | |-----------|----------------------------------------------------------------------| 48 | | `name` | The name of the file. | 49 | | `state` | The state of the file. Can be `open` or `closed`. Default is `open`. | 50 | -------------------------------------------------------------------------------- /layouts/_markup/render-image.html: -------------------------------------------------------------------------------- 1 | {{- $alt := .PlainText | safeHTML -}} 2 | {{- $lazyLoading := .Page.Site.Params.enableImageLazyLoading | default true -}} 3 | {{- $dest := .Destination -}} 4 | {{- $url := urls.Parse $dest -}} 5 | 6 | {{- $isLocal := not $url.Scheme -}} 7 | {{- $isPage := and (eq .Page.Kind "page") (not .Page.BundleType) -}} 8 | {{- $startsWithSlash := hasPrefix $dest "/" -}} 9 | {{- $startsWithRelative := hasPrefix $dest "../" -}} 10 | 11 | {{- if and $dest $isLocal -}} 12 | {{- if $startsWithSlash -}} 13 | {{- with or (.PageInner.Resources.Get $url.Path) (resources.Get $url.Path) -}} 14 | {{/* Images under assets directory */}} 15 | {{- $query := cond $url.RawQuery (printf "?%s" $url.RawQuery) "" -}} 16 | {{- $fragment := cond $url.Fragment (printf "#%s" $url.Fragment) "" -}} 17 | {{- $dest = printf "%s%s%s" .RelPermalink $query $fragment -}} 18 | {{- else -}} 19 | {{/* Images under static directory */}} 20 | {{- $dest = (relURL (strings.TrimPrefix "/" $dest)) -}} 21 | {{- end -}} 22 | {{- else if and $isPage (not $startsWithRelative) -}} 23 | {{/* Images that are sibling to the individual page file */}} 24 | {{ $dest = (printf "../%s" $dest) }} 25 | {{- end -}} 26 | {{- end -}} 27 | 28 | {{- $attributes := "" -}} 29 | {{- range $key, $value := .Attributes -}} 30 | {{- if $value -}} 31 | {{- $pair := printf "%s=%q" $key ($value | transform.HTMLEscape) -}} 32 | {{- $attributes = printf "%s %s" $attributes $pair -}} 33 | {{- end -}} 34 | {{- end -}} 35 | 36 | {{- with .Title -}} 37 |
    38 | {{ $alt }} 39 |
    {{ . }}
    40 |
    41 | {{- else -}} 42 | {{ $alt }} 43 | {{- end -}} 44 | -------------------------------------------------------------------------------- /assets/js/core/switcher-menu.js: -------------------------------------------------------------------------------- 1 | function computeMenuTranslation(switcher, optionsElement) { 2 | // Calculate the position of a language options element. 3 | const switcherRect = switcher.getBoundingClientRect(); 4 | 5 | // Must be called before optionsElement.clientWidth. 6 | optionsElement.style.minWidth = `${Math.max(switcherRect.width, 50)}px`; 7 | 8 | const isOnTop = switcher.dataset.location === 'top'; 9 | const isOnBottom = switcher.dataset.location === 'bottom'; 10 | const isOnBottomRight = switcher.dataset.location === 'bottom-right'; 11 | const isRTL = document.documentElement.dir === 'rtl' 12 | 13 | // Stuck on the left side of the switcher. 14 | let x = switcherRect.left; 15 | 16 | if (isOnTop && !isRTL || isOnBottom && isRTL || isOnBottomRight && !isRTL) { 17 | // Stuck on the right side of the switcher. 18 | x = switcherRect.right - optionsElement.clientWidth; 19 | } 20 | 21 | // Stuck on the top of the switcher. 22 | let y = switcherRect.top - window.innerHeight - 10; 23 | 24 | if (isOnTop) { 25 | // Stuck on the bottom of the switcher. 26 | y = switcherRect.top - window.innerHeight + optionsElement.clientHeight + switcher.clientHeight + 4; 27 | } 28 | 29 | return { x: x, y: y }; 30 | } 31 | 32 | function toggleMenu(switcher) { 33 | const optionsElement = switcher.nextElementSibling; 34 | 35 | optionsElement.classList.toggle('hx:hidden'); 36 | 37 | // Calculate the position of a language options element. 38 | const translate = computeMenuTranslation(switcher, optionsElement); 39 | 40 | optionsElement.style.transform = `translate3d(${translate.x}px, ${translate.y}px, 0)`; 41 | } 42 | 43 | function resizeMenu(switcher) { 44 | const optionsElement = switcher.nextElementSibling; 45 | 46 | if (optionsElement.classList.contains('hx:hidden')) return; 47 | 48 | // Calculate the position of a language options element. 49 | const translate = computeMenuTranslation(switcher, optionsElement); 50 | 51 | optionsElement.style.transform = `translate3d(${translate.x}px, ${translate.y}px, 0)`; 52 | } 53 | -------------------------------------------------------------------------------- /assets/js/core/theme.js: -------------------------------------------------------------------------------- 1 | // Light / Dark theme toggle 2 | (function () { 3 | const defaultTheme = '{{ site.Params.theme.default | default `system`}}' 4 | const themes = ["light", "dark"]; 5 | 6 | const themeToggleButtons = document.querySelectorAll(".hextra-theme-toggle"); 7 | const themeToggleOptions = document.querySelectorAll(".hextra-theme-toggle-options p"); 8 | 9 | function applyTheme(theme) { 10 | theme = themes.includes(theme) ? theme : "system"; 11 | 12 | themeToggleButtons.forEach((btn) => btn.parentElement.dataset.theme = theme ); 13 | 14 | localStorage.setItem("color-theme", theme); 15 | } 16 | 17 | function switchTheme(theme) { 18 | setTheme(theme); 19 | applyTheme(theme); 20 | } 21 | 22 | const colorTheme = "color-theme" in localStorage ? localStorage.getItem("color-theme") : defaultTheme; 23 | switchTheme(colorTheme); 24 | 25 | // Add click event handler to the menu items. 26 | themeToggleOptions.forEach((option) => { 27 | option.addEventListener("click", function (e) { 28 | e.preventDefault(); 29 | 30 | switchTheme(option.dataset.item); 31 | }) 32 | }) 33 | 34 | // Add click event handler to the buttons 35 | themeToggleButtons.forEach((toggler) => { 36 | toggler.addEventListener("click", function (e) { 37 | e.preventDefault(); 38 | 39 | toggleMenu(toggler); 40 | }); 41 | }); 42 | 43 | window.addEventListener("resize", () => themeToggleButtons.forEach(resizeMenu)) 44 | 45 | // Dismiss the menu when clicking outside 46 | document.addEventListener('click', (e) => { 47 | if (e.target.closest('.hextra-theme-toggle') === null) { 48 | themeToggleButtons.forEach((toggler) => { 49 | toggler.dataset.state = 'closed'; 50 | toggler.nextElementSibling.classList.add('hx:hidden'); 51 | }); 52 | } 53 | }); 54 | 55 | // Listen for system theme changes 56 | window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", () => { 57 | if (localStorage.getItem("color-theme") === "system") { 58 | setTheme("system"); 59 | } 60 | }); 61 | })(); 62 | -------------------------------------------------------------------------------- /layouts/_shortcodes/callout.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | A shortcode to create a callout. 3 | 4 | @param {string} type The type of the callout (default, info, warning, error, important). 5 | @param {string} content The content of the callout. 6 | @param {string} emoji The emoji of the callout. 7 | @param {string} icon The icon of the callout (related to type or can be a custom icon). 8 | 9 | @example {{< callout type="info" >}}Content{{< /callout >}} 10 | */ -}} 11 | 12 | {{- $type := .Get "type" | default "default" -}} 13 | {{- $emoji := .Get "emoji" -}} 14 | {{- $icon := .Get "icon" -}} 15 | 16 | {{- $styles := newScratch -}} 17 | {{- $styles.Set "default" (dict 18 | "icon" "light-bulb" 19 | "style" "hx:border-green-200 hx:bg-green-100 hx:text-green-900 hx:dark:border-green-200/30 hx:dark:bg-green-900/30 hx:dark:text-green-200" 20 | ) 21 | -}} 22 | {{- $styles.Set "info" (dict 23 | "icon" "information-circle" 24 | "style" "hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200" 25 | ) 26 | -}} 27 | {{- $styles.Set "warning" (dict 28 | "icon" "exclamation" 29 | "style" "hx:border-amber-200 hx:bg-amber-100 hx:text-amber-900 hx:dark:border-amber-200/30 hx:dark:bg-amber-900/30 hx:dark:text-amber-200" 30 | ) 31 | -}} 32 | {{- $styles.Set "error" (dict 33 | "icon" "ban" 34 | "style" "hx:border-red-200 hx:bg-red-100 hx:text-red-900 hx:dark:border-red-200/30 hx:dark:bg-red-900/30 hx:dark:text-red-200" 35 | ) 36 | -}} 37 | {{- $styles.Set "important" (dict 38 | "icon" "exclamation-circle" 39 | "style" "hx:border-purple-200 hx:bg-purple-100 hx:text-purple-900 hx:dark:border-purple-200/30 hx:dark:bg-purple-900/30 hx:dark:text-purple-200" 40 | ) 41 | -}} 42 | 43 | {{- $style := or ($styles.Get $type) ($styles.Get "default") -}} 44 | 45 | {{- if and (not $emoji) (not $icon) -}} 46 | {{- $icon = $style.icon -}} 47 | {{- end -}} 48 | 49 | {{- $content := .InnerDeindent | markdownify -}} 50 | 51 | {{- partial "shortcodes/callout.html" (dict 52 | "content" $content 53 | "emoji" $emoji 54 | "icon" $icon 55 | "class" $style.style 56 | ) 57 | -}} 58 | -------------------------------------------------------------------------------- /docs/content/docs/_index.fa.md: -------------------------------------------------------------------------------- 1 | --- 2 | linkTitle: "مستندات" 3 | title: معرفی 4 | --- 5 | 6 | 👋 سلام! به مستندات Hextra خوش آمدید! 7 | 8 | 9 | 10 | ## Hextra چیست؟ 11 | 12 | Hextra یک پوسته مدرن، سریع و کامل برای [Hugo][hugo] است که با [Tailwind CSS][tailwind-css] ساخته شده است. 13 | این پوسته برای ساخت وب‌سایت‌های زیبا برای مستندات، وبلاگ‌ها و وب‌سایت‌ها طراحی شده و امکاناتی را به صورت پیش‌فرض ارائه می‌دهد که انعطاف لازم برای پاسخگویی به نیازهای مختلف را دارد. 14 | 15 | ## ویژگی‌ها 16 | 17 | - **طراحی زیبا** - با الهام از Nextra، Hextra از Tailwind CSS استفاده می‌کند تا طراحی مدرنی ارائه دهد که سایت شما را برجسته می‌کند. 18 | - **چیدمان واکنش‌گرا و حالت تاریک** - در تمام دستگاه‌ها از موبایل و تبلت تا دسکتاپ عالی به نظر می‌رسد. حالت تاریک نیز پشتیبانی می‌شود تا شرایط نوری مختلف را پوشش دهد. 19 | - **سریع و سبک‌وزن** - با قدرت Hugo، یک مولد سایت استاتیک فوق‌العاده سریع که در یک فایل باینری واحد قرار دارد، Hextra ردپای کوچکی دارد. برای استفاده از آن نیازی به JavaScript یا Node.js نیست. 20 | - **جستجوی تمام‌متن** - جستجوی تمام‌متن آفلاین داخلی با قدرت FlexSearch، بدون نیاز به پیکربندی اضافی. 21 | - **کامل و آماده استفاده** - عناصر Markdown، برجسته‌سازی سینتکس، فرمول‌های ریاضی LaTeX، نمودارها و Shortcodes برای غنی‌تر کردن محتوای شما. فهرست مطالب، مسیرهای ناوبری، صفحه‌بندی، نوار کناری و موارد دیگر همگی به صورت خودکار تولید می‌شوند. 22 | - **چندزبانه و آماده برای سئو** - ساخت سایت‌های چندزبانه با حالت چندزبانه Hugo آسان شده است. پشتیبانی پیش‌فرض برای تگ‌های سئو، Open Graph و Twitter Cards وجود دارد. 23 | 24 | ## سوال یا بازخورد دارید؟ 25 | 26 | {{< callout emoji="❓" >}} 27 | Hextra هنوز در حال توسعه فعال است. 28 | سوال یا بازخوردی دارید؟ با خیال راحت [یک issue باز کنید](https://github.com/imfing/hextra/issues)! 29 | {{< /callout >}} 30 | 31 | ## بعدی 32 | 33 | برای شروع، مستقیماً به بخش زیر بروید: 34 | 35 | {{< cards >}} 36 | {{< card link="getting-started" title="شروع به کار" icon="document-text" subtitle="یاد بگیرید چگونه با استفاده از Hextra وب‌سایت بسازید" >}} 37 | {{< /cards >}} 38 | 39 | [hugo]: https://gohugo.io/ 40 | [flex-search]: https://github.com/nextapps-de/flexsearch 41 | [tailwind-css]: https://tailwindcss.com/ -------------------------------------------------------------------------------- /layouts/_partials/search.html: -------------------------------------------------------------------------------- 1 | {{- $placeholder := (T "searchPlaceholder") | default "Search..." -}} 2 | 3 | 4 |
    5 |
    6 | 13 | 16 | CTRL K 17 | 18 |
    19 | 20 |
    21 |
      25 |
      26 |
      27 | -------------------------------------------------------------------------------- /docs/content/showcase/index.fa.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ویترین 3 | description: "پروژه‌های متن‌باز که توسط هگزترا طراحی شده‌اند." 4 | toc: false 5 | layout: wide 6 | --- 7 | 8 |
      9 | 10 |

      11 | پروژه‌های متن‌باز که توسط هگزترا طراحی شده‌اند. 12 |

      13 | 14 | {{< cards >}} 15 | {{< card 16 | link="https://printn.dev" 17 | title="PrintN" 18 | image="https://raw.githubusercontent.com/printn/printn.github.io/refs/heads/main/static/images/screenshot.png" 19 | imageStyle="object-fit:cover; aspect-ratio:16/9;" 20 | >}} 21 | 22 | {{< card 23 | link="https://beginnerprivacy.com" 24 | title="Beginner Privacy" 25 | image="https://raw.githubusercontent.com/beginnerprivacy/beginnerprivacy.com/refs/heads/main/static/images/screenshot.png" 26 | imageStyle="object-fit:cover; aspect-ratio:16/9;" 27 | >}} 28 | 29 | {{< card link="https://developers.osuny.org" title="Osuny" image="https://raw.githubusercontent.com/noesya/osuny-developers/main/static/images/showcase-hextra/screenshot.png" imageStyle="object-fit:cover; aspect-ratio:16/9;" >}} 30 | {{< card link="https://porter.sh/" title="Porter" image="https://repository-images.githubusercontent.com/155893691/aa249c80-fcf3-11ea-93b0-30079e8d7de4" imageStyle="object-fit:cover; aspect-ratio:16/9;" >}} 31 | {{< card link="https://lutheranconfessions.org/" title="LutheranConfessions" image="https://github.com/imfing/hextra/assets/5097752/ad6625e4-88cd-4cad-b102-5399997d0359" imageStyle="object-fit:cover; aspect-ratio:16/9;" >}} 32 | {{< card link="https://github.com/imfing/hextra-starter-template/" title="Hextra Starter Template" image="https://user-images.githubusercontent.com/5097752/263551418-c403b9a9-a76c-47a6-8466-513d772ef0b7.jpg" imageStyle="object-fit:cover; aspect-ratio:16/9;" >}} 33 | {{< card link="https://developers.clever-cloud.com/" title="Clever Cloud Documentation" image="https://cellar-c2.services.clever-cloud.com/documentation/doc-screenshot.png" imageStyle="object-fit:cover; aspect-ratio:16/9;" >}} 34 | {{< /cards >}} 35 | -------------------------------------------------------------------------------- /layouts/_partials/components/blog-pager.html: -------------------------------------------------------------------------------- 1 | {{/* 2 | Blog pagination component for list pages (e.g., blog list, category list) 3 | 4 | Usage: {{ partial "components/blog-pager.html" $paginator }} 5 | 6 | Parameters: 7 | - . (context): Hugo paginator object 8 | */}} 9 | 10 | {{- $paginator := . -}} 11 | {{- $prevText := (T "previous") | default "Prev" -}} 12 | {{- $nextText := (T "next") | default "Next" -}} 13 | {{- $prevLabel := printf "%s %d/%d" $prevText (sub $paginator.PageNumber 1) $paginator.TotalPages -}} 14 | {{- $nextLabel := printf "%s %d/%d" $nextText (add $paginator.PageNumber 1) $paginator.TotalPages -}} 15 | 16 | {{- if or $paginator.HasPrev $paginator.HasNext -}} 17 | 39 | {{- end -}} -------------------------------------------------------------------------------- /docs/content/docs/advanced/multi-language.zh-cn.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "多语言支持" 3 | weight: 1 4 | prev: /docs/advanced 5 | --- 6 | 7 | Hextra 支持使用 Hugo 的[多语言模式](https://gohugo.io/content-management/multilingual/)创建多语言网站。 8 | 9 | 10 | 11 | ## 启用多语言功能 12 | 13 | 要使网站支持多语言,我们需要在站点配置文件中指定支持的语言: 14 | 15 | ```yaml {filename="hugo.yaml"} 16 | defaultContentLanguage: en 17 | languages: 18 | en: 19 | languageName: English 20 | weight: 1 21 | fr: 22 | languageName: Français 23 | weight: 2 24 | ja: 25 | languageName: 日本語 26 | weight: 3 27 | ``` 28 | 29 | ## 通过文件名管理翻译 30 | 31 | Hugo 支持通过文件名管理翻译。例如,如果我们有一个英文文件 `content/docs/_index.md`,可以创建 `content/docs/_index.fr.md` 作为法语翻译。 32 | 33 | {{< filetree/container >}} 34 | {{< filetree/folder name="content" >}} 35 | {{< filetree/folder name="docs" state="open" >}} 36 | {{< filetree/file name="_index.md" >}} 37 | {{< filetree/file name="_index.fr.md" >}} 38 | {{< filetree/file name="_index.ja.md" >}} 39 | {{< /filetree/folder >}} 40 | {{< /filetree/folder >}} 41 | {{< /filetree/container >}} 42 | 43 | 注意:Hugo 还支持[通过内容目录翻译](https://gohugo.io/content-management/multilingual/#translation-by-content-directory)。 44 | 45 | ## 翻译菜单项 46 | 47 | 要翻译导航栏中的菜单项,需要设置 `identifier` 字段: 48 | 49 | ```yaml {filename="hugo.yaml"} 50 | menu: 51 | main: 52 | - identifier: documentation 53 | name: Documentation 54 | pageRef: /docs 55 | weight: 1 56 | - identifier: blog 57 | name: Blog 58 | pageRef: /blog 59 | weight: 2 60 | ``` 61 | 62 | 并在对应的 i18n 文件中进行翻译: 63 | 64 | ```yaml {filename="i18n/fr.yaml"} 65 | documentation: Documentation 66 | blog: Blog 67 | ``` 68 | 69 | ## 翻译字符串 70 | 71 | 要翻译其他位置的字符串,需要将翻译添加到对应的 i18n 文件中: 72 | 73 | ```yaml {filename="i18n/fr.yaml"} 74 | readMore: Lire la suite 75 | ``` 76 | 77 | 主题中使用的字符串列表可以在 `i18n/en.yaml` 文件中找到。 78 | 79 | ## 延伸阅读 80 | 81 | - [Hugo 多语言模式](https://gohugo.io/content-management/multilingual/) 82 | - [Hugo 多语言第一部分:内容翻译](https://www.regisphilibert.com/blog/2018/08/hugo-multilingual-part-1-managing-content-translation/) 83 | - [Hugo 多语言第二部分:字符串本地化](https://www.regisphilibert.com/blog/2018/08/hugo-multilingual-part-2-i18n-string-localization/) -------------------------------------------------------------------------------- /docs/content/docs/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | linkTitle: "Documentation" 3 | title: Introduction 4 | --- 5 | 6 | 👋 Hello! Welcome to the Hextra documentation! 7 | 8 | 9 | 10 | ## What is Hextra? 11 | 12 | Hextra is a modern, fast and batteries-included [Hugo][hugo] theme built with [Tailwind CSS][tailwind-css]. 13 | Designed for building beautiful websites for documentation, blogs, and websites, it provides out-of-the-box features and flexibility to meet various requirements. 14 | 15 | ## Features 16 | 17 | - **Beautiful Design** - Inspired by Nextra, Hextra utilizes Tailwind CSS to offer a modern design that makes your site look outstanding. 18 | - **Responsive Layout and Dark Mode** - It looks great on all devices, from mobile, tablet to desktop. Dark mode is also supported to accommodate various lighting conditions. 19 | - **Fast and Lightweight** - Powered by Hugo, a lightning-fast static-site generator housed in a single binary file, Hextra keeps its footprint minimal. No JavaScript or Node.js are needed to use it. 20 | - **Full-text Search** - Built-in offline full-text search powered by FlexSearch, no additional configuration required. 21 | - **Battery-included** - Markdown, syntax highlighting, LaTeX math formulae, diagrams and Shortcodes elements to enhance your content. Table of contents, breadcrumbs, pagination, sidebar navigation and more are all automatically generated. 22 | - **Multi-language and SEO Ready** - Multi-language sites made easy with Hugo's multilingual mode. Out-of-the-box support is included for SEO tags, Open Graph, and Twitter Cards. 23 | 24 | ## Questions or Feedback? 25 | 26 | {{< callout emoji="❓" >}} 27 | Hextra is still in active development. 28 | Have a question or feedback? Feel free to [open an issue](https://github.com/imfing/hextra/issues)! 29 | {{< /callout >}} 30 | 31 | ## Next 32 | 33 | Dive right into the following section to get started: 34 | 35 | {{< cards >}} 36 | {{< card link="getting-started" title="Getting Started" icon="document-text" subtitle="Learn how to create website using Hextra" >}} 37 | {{< /cards >}} 38 | 39 | [hugo]: https://gohugo.io/ 40 | [flex-search]: https://github.com/nextapps-de/flexsearch 41 | [tailwind-css]: https://tailwindcss.com/ 42 | -------------------------------------------------------------------------------- /assets/js/core/tabs.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | function updateGroup(container, index) { 3 | const tabs = Array.from(container.querySelectorAll('.hextra-tabs-toggle')); 4 | tabs.forEach((tab, i) => { 5 | tab.dataset.state = i === index ? 'selected' : ''; 6 | if (i === index) { 7 | tab.setAttribute('aria-selected', 'true'); 8 | tab.tabIndex = 0; 9 | } else { 10 | tab.removeAttribute('aria-selected'); 11 | tab.removeAttribute('tabindex'); 12 | } 13 | }); 14 | const panelsContainer = container.parentElement.nextElementSibling; 15 | if (!panelsContainer) return; 16 | Array.from(panelsContainer.children).forEach((panel, i) => { 17 | panel.dataset.state = i === index ? 'selected' : ''; 18 | if (i === index) { 19 | panel.tabIndex = 0; 20 | } else { 21 | panel.removeAttribute('tabindex'); 22 | } 23 | }); 24 | } 25 | 26 | const syncGroups = document.querySelectorAll('[data-tab-group]'); 27 | 28 | syncGroups.forEach((group) => { 29 | const key = encodeURIComponent(group.dataset.tabGroup); 30 | const saved = localStorage.getItem('hextra-tab-' + key); 31 | if (saved !== null) { 32 | updateGroup(group, parseInt(saved, 10)); 33 | } 34 | }); 35 | 36 | document.querySelectorAll('.hextra-tabs-toggle').forEach((button) => { 37 | button.addEventListener('click', function (e) { 38 | const container = e.target.parentElement; 39 | const index = Array.from(container.querySelectorAll('.hextra-tabs-toggle')).indexOf( 40 | e.target 41 | ); 42 | 43 | if (container.dataset.tabGroup) { 44 | // Sync behavior: update all tab groups with the same name 45 | const tabGroupValue = container.dataset.tabGroup; 46 | const key = encodeURIComponent(tabGroupValue); 47 | document 48 | .querySelectorAll('[data-tab-group="' + tabGroupValue + '"]') 49 | .forEach((grp) => updateGroup(grp, index)); 50 | localStorage.setItem('hextra-tab-' + key, index.toString()); 51 | } else { 52 | // Non-sync behavior: update only this specific tab group 53 | updateGroup(container, index); 54 | } 55 | }); 56 | }); 57 | })(); 58 | -------------------------------------------------------------------------------- /README.zh-cn.md: -------------------------------------------------------------------------------- 1 |
      2 |

      Hextra

      3 | English | 简体中文فارسی 4 |

      用于创建美观的静态站点的现代化, 响应式, 功能强大的 Hugo 主题.

      5 | 6 | 演示 → [imfing.github.io/hextra](https://imfing.github.io/hextra/) 7 |
      8 | 9 | 10 | 11 | Hextra 12 | 13 | 14 |
      15 | GitHub Actions Status Netlify Status 16 |
      17 | 18 | ## 特性 19 | 20 | - **美观的设计** - 受 Nextra 的启发,Hextra 利用 Tailwind CSS 提供现代化的设计,使您的网站看起来美观有加. 21 | - **响应式布局和深色模式支持** - 在任何设备上看起来都足够美观, 无论是手机, 平板电脑或者电脑. 深色模式的支持使 Hextra 可以应对各种照明环境. 22 | - **快速且轻量** - 由 Hugo 强力支持, Hugo 是一个快如闪电的静态站点生成器, 这一切都只需一个可执行文件, Hextra 始终保持最小化, 无需 Javascript 或者 Node.js. 23 | - **全文搜索** - 集成了 Flexsearch 的全文搜索, 无需额外的配置. 24 | - **功能齐全** - Markdown, 代码高亮, LaTex 数学公式, diagrams 图表和 Shortcodes 都可以用于丰富你的内容. 目录, 面包屑导航, 分页, 侧边栏等均由 Hextra 自动生成。 25 | - **多语言和 SEO Ready** - Hugo 的多语言模式使得构建多语言网站更简单. 具有 SEO tags, Open Graph, 和 Twitter Cards 等诸多开箱即用的功能. 26 | 27 | ## 快速开始 28 | 29 | ### 使用模板 30 | 31 | 使用 [Hextra stater template](https://github.com/imfing/hextra-starter-template) 是使用 Hextra 主题的最简单方法. 点击仓库页面上的 `Use this template` 按钮开始使用. 32 | 33 | 此仓库中包含一个 [GitHub Actions workflow](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) 来帮助你免费在 GitHub Pages 上自动构建和部署网站. 34 | 35 | ### 使用 36 | 37 | 转至[文档](https://imfing.github.io/hextra/zh-cn/docs) 38 | 39 | ## 贡献 40 | 41 | 该项目正在积极开发中. 欢迎贡献! 42 | 43 | ## 许可证 44 | 45 | [MIT License](./LICENSE) 46 | -------------------------------------------------------------------------------- /assets/js/core/nav-menu.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | const hiddenClass = "hx:hidden"; 3 | const dropdownToggles = document.querySelectorAll(".hextra-nav-menu-toggle"); 4 | 5 | dropdownToggles.forEach((toggle) => { 6 | toggle.addEventListener("click", (e) => { 7 | e.preventDefault(); 8 | e.stopPropagation(); 9 | 10 | // Close all other dropdowns first 11 | dropdownToggles.forEach((otherToggle) => { 12 | if (otherToggle !== toggle) { 13 | otherToggle.dataset.state = "closed"; 14 | const otherMenuItems = otherToggle.nextElementSibling; 15 | otherMenuItems.classList.add(hiddenClass); 16 | } 17 | }); 18 | 19 | // Toggle current dropdown 20 | const isOpen = toggle.dataset.state === "open"; 21 | toggle.dataset.state = isOpen ? "closed" : "open"; 22 | const menuItemsElement = toggle.nextElementSibling; 23 | 24 | if (!isOpen) { 25 | // Position dropdown centered with toggle 26 | menuItemsElement.style.position = "absolute"; 27 | menuItemsElement.style.top = "100%"; 28 | menuItemsElement.style.left = "50%"; 29 | menuItemsElement.style.transform = "translateX(-50%)"; 30 | menuItemsElement.style.zIndex = "1000"; 31 | 32 | // Show dropdown 33 | menuItemsElement.classList.remove(hiddenClass); 34 | } else { 35 | // Hide dropdown 36 | menuItemsElement.classList.add(hiddenClass); 37 | } 38 | }); 39 | }); 40 | 41 | // Dismiss dropdown when clicking outside 42 | document.addEventListener("click", (e) => { 43 | if (e.target.closest(".hextra-nav-menu-toggle") === null) { 44 | dropdownToggles.forEach((toggle) => { 45 | toggle.dataset.state = "closed"; 46 | const menuItemsElement = toggle.nextElementSibling; 47 | menuItemsElement.classList.add(hiddenClass); 48 | }); 49 | } 50 | }); 51 | 52 | // Close dropdowns on escape key 53 | document.addEventListener("keydown", (e) => { 54 | if (e.key === "Escape") { 55 | dropdownToggles.forEach((toggle) => { 56 | toggle.dataset.state = "closed"; 57 | const menuItemsElement = toggle.nextElementSibling; 58 | menuItemsElement.classList.add(hiddenClass); 59 | }); 60 | } 61 | }); 62 | })(); 63 | -------------------------------------------------------------------------------- /layouts/_shortcodes/hextra/feature-card.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | A shortcode for displaying a feature card. 3 | 4 | @param {string} title The title of the card. 5 | @param {string} subtitle The subtitle of the card. 6 | @param {string} class The class of the card. 7 | @param {string} image The image of the card. 8 | @param {string} imageClass The class of the image. 9 | @param {string} style The style of the card. 10 | @param {string} icon The icon of the card. 11 | @param {string} link The link of the card. 12 | 13 | @example {{< hextra/feature-card title="Feature Card" subtitle="This is a feature card." >}} 14 | */ -}} 15 | 16 | {{- $title := .Get "title" -}} 17 | {{- $subtitle := .Get "subtitle" -}} 18 | {{- $class := .Get "class" -}} 19 | {{- $image := .Get "image" -}} 20 | {{- $imageClass := .Get "imageClass" -}} 21 | {{- $style := .Get "style" -}} 22 | {{- $icon := .Get "icon" -}} 23 | {{- $link := .Get "link" -}} 24 | 25 | {{- $external := hasPrefix $link "http" -}} 26 | {{- $href := cond (strings.HasPrefix $link "/") ($link | relURL) $link -}} 27 | 28 | {{- if hasPrefix $image "/" -}} 29 | {{- $image = relURL (strings.TrimPrefix "/" $image) -}} 30 | {{- end -}} 31 | 32 | 37 |
      38 |

      39 | {{ with $icon -}} 40 | 41 | {{- partial "utils/icon.html" (dict "name" . "attributes" "height=1.5rem") -}} 42 | 43 | {{ end -}} 44 | {{ $title }} 45 |

      46 |

      {{ $subtitle | markdownify }}

      47 |
      48 | {{- with $image -}} 49 | {{ $title }} 50 | {{- end -}} 51 |
      52 | -------------------------------------------------------------------------------- /layouts/list.rss.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ .Site.Title }} – {{ .Title }} 4 | {{ .Permalink }} 5 | Recent content {{ if ne .Title .Site.Title }}{{ with .Title }}in {{.}} {{ end }}{{ end }}on {{ .Site.Title }} 6 | Hugo -- gohugo.io{{ with .Site.LanguageCode }} 7 | {{.}}{{end}}{{ with .Site.Author.email }} 8 | {{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}{{end}}{{ with .Site.Author.email }} 9 | {{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}{{end}}{{ with .Site.Copyright }} 10 | {{.}}{{end}}{{ if not .Date.IsZero }} 11 | {{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}{{ end }} 12 | {{ with .OutputFormats.Get "RSS" }} 13 | {{ printf "" .Permalink .MediaType | safeHTML }} 14 | {{ end }} 15 | {{ if not $.Section }} 16 | {{ $sections := .Site.Params.rss.sections | default (slice "blog") }} 17 | {{ .Store.Set "rssPages" (first 50 (where $.Site.RegularPages "Type" "in" $sections )) }} 18 | {{ else }} 19 | {{ if $.Parent.IsHome }} 20 | {{ .Store.Set "rssPages" (first 50 (where $.Site.RegularPages "Type" $.Section )) }} 21 | {{ else }} 22 | {{ .Store.Set "rssPages" (first 50 $.Pages) }} 23 | {{ end }} 24 | {{ end }} 25 | {{ range (.Store.Get "rssPages") }} 26 | 27 | {{ .Title }} 28 | {{ .Permalink }} 29 | {{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }} 30 | {{ with .Site.Author.email }}{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}{{end}} 31 | {{ .Permalink }} 32 | 33 | {{ $img := (.Resources.ByType "image").GetMatch "*featured*" }} 34 | {{ with $img }} 35 | {{ $img := .Resize "640x" }} 36 | {{ printf "]]>" $img.Permalink $img.Width $img.Height | safeHTML }} 37 | {{ end }} 38 | {{ .Content | html }} 39 | 40 | 41 | {{ end }} 42 | 43 | 44 | -------------------------------------------------------------------------------- /layouts/_partials/components/analytics/umami.html: -------------------------------------------------------------------------------- 1 | {{- /* 2 | Umami Analytics 3 | https://umami.is/docs/tracker-configuration 4 | */ -}} 5 | 6 | {{- with .Site.Params.analytics.umami -}} 7 | 8 | {{- if not .serverURL }} 9 | {{- errorf "Missing Umami 'serverURL' configuration. See https://imfing.github.io/hextra/versions/latest/docs/guide/configuration/#umami-analytics" -}} 10 | {{- end -}} 11 | 12 | {{- if not .websiteID }} 13 | {{- errorf "Missing Umami 'websiteID' configuration. See https://imfing.github.io/hextra/versions/latest/docs/guide/configuration/#umami-analytics" -}} 14 | {{- end -}} 15 | 16 | {{- $attributes := newScratch -}} 17 | 18 | {{- $attributes.SetInMap "umami" "src" (printf "%s/%s" .serverURL (.scriptName | default "script.js")) -}} 19 | {{- $attributes.SetInMap "umami" "data-website-id" .websiteID -}} 20 | 21 | {{- if .hostURL -}} 22 | {{- /* https://umami.is/docs/tracker-configuration#data-host-url */ -}} 23 | {{- $attributes.SetInMap "umami" "data-host-url" .hostURL -}} 24 | {{- end -}} 25 | 26 | {{- if .autoTrack -}} 27 | {{- /* https://umami.is/docs/tracker-configuration#data-auto-track */ -}} 28 | {{- $attributes.SetInMap "umami" "data-auto-track" .autoTrack -}} 29 | {{- end -}} 30 | 31 | {{- if .tag -}} 32 | {{- /* https://umami.is/docs/tracker-configuration#data-tag */ -}} 33 | {{- $attributes.SetInMap "umami" "data-tag" .tag -}} 34 | {{- end -}} 35 | 36 | {{- if .excludeSearch -}} 37 | {{- /* https://umami.is/docs/tracker-configuration#data-exclude-search */ -}} 38 | {{- $attributes.SetInMap "umami" "data-exclude-search" .excludeSearch -}} 39 | {{- end -}} 40 | 41 | {{- if .excludeHash -}} 42 | {{- /* https://umami.is/docs/tracker-configuration#data-exclude-hash */ -}} 43 | {{- $attributes.SetInMap "umami" "data-exclude-hash" .excludeHash -}} 44 | {{- end -}} 45 | 46 | {{- if .doNotTrack -}} 47 | {{- /* https://umami.is/docs/tracker-configuration#data-do-not-track */ -}} 48 | {{- $attributes.SetInMap "umami" "data-do-not-track" .doNotTrack -}} 49 | {{- end -}} 50 | 51 | {{- if .domains -}} 52 | {{- /* https://umami.is/docs/tracker-configuration#data-domains */ -}} 53 | {{- $attributes.SetInMap "umami" "data-domains" .domains -}} 54 | {{- end -}} 55 | 56 | 57 | {{- end -}} 58 | -------------------------------------------------------------------------------- /layouts/_partials/components/github-style-alert.html: -------------------------------------------------------------------------------- 1 | {{- $content := .content -}} 2 | {{- $alertType := .alertType -}} 3 | {{- $alertTitle := .alertTitle -}} 4 | 5 | {{- $styles := newScratch -}} 6 | {{- $styles.Set "default" (dict 7 | "icon" "light-bulb" 8 | "style" "hx:border-green-200 hx:bg-green-100 hx:text-green-900 hx:dark:border-green-200/30 hx:dark:bg-green-900/30 hx:dark:text-green-200" 9 | ) 10 | -}} 11 | {{- $styles.Set "note" (dict 12 | "icon" "information-circle" 13 | "style" "hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200" 14 | ) 15 | -}} 16 | {{- $styles.Set "tip" (dict 17 | "icon" "light-bulb" 18 | "style" "hx:border-green-200 hx:bg-green-100 hx:text-green-900 hx:dark:border-green-200/30 hx:dark:bg-green-900/30 hx:dark:text-green-200" 19 | ) 20 | -}} 21 | {{- $styles.Set "important" (dict 22 | "icon" "information-circle" 23 | "style" "hx:border-purple-200 hx:bg-purple-100 hx:text-purple-900 hx:dark:border-purple-200/30 hx:dark:bg-purple-900/30 hx:dark:text-purple-200" 24 | ) 25 | -}} 26 | {{- $styles.Set "warning" (dict 27 | "icon" "exclamation" 28 | "style" "hx:border-amber-200 hx:bg-amber-100 hx:text-amber-900 hx:dark:border-amber-200/30 hx:dark:bg-amber-900/30 hx:dark:text-amber-200" 29 | ) 30 | -}} 31 | {{- $styles.Set "caution" (dict 32 | "icon" "exclamation-circle" 33 | "style" "hx:border-red-200 hx:bg-red-100 hx:text-red-900 hx:dark:border-red-200/30 hx:dark:bg-red-900/30 hx:dark:text-red-200" 34 | ) 35 | -}} 36 | 37 | {{- $style := or ($styles.Get $alertType) ($styles.Get "default") -}} 38 | {{- $title := or $alertTitle (or (i18n $alertType) (title $alertType)) -}} 39 | 40 |
      41 |

      42 | {{- with $style.icon -}} 43 | {{- partial "utils/icon.html" (dict "name" . "attributes" `height=16px class="hx:inline-block hx:align-middle hx:mr-2"`) -}} 44 | {{- end -}} 45 | {{- $title -}} 46 |

      47 | 48 |
      49 |
      50 | {{- $content -}} 51 |
      52 |
      53 |
      54 | -------------------------------------------------------------------------------- /docs/content/docs/advanced/multi-language.ja.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "多言語対応" 3 | weight: 1 4 | prev: /docs/advanced 5 | --- 6 | 7 | Hextra は Hugo の [多言語モード](https://gohugo.io/content-management/multilingual/) を使用して、複数言語のサイトを作成することをサポートしています。 8 | 9 | 10 | 11 | ## 多言語対応を有効にする 12 | 13 | サイトを多言語対応にするには、Hugo にサポートする言語を伝える必要があります。サイト設定ファイルに以下を追加します: 14 | 15 | ```yaml {filename="hugo.yaml"} 16 | defaultContentLanguage: en 17 | languages: 18 | en: 19 | languageName: English 20 | weight: 1 21 | fr: 22 | languageName: Français 23 | weight: 2 24 | ja: 25 | languageName: 日本語 26 | weight: 3 27 | ``` 28 | 29 | ## ファイル名による翻訳管理 30 | 31 | Hugo はファイル名による翻訳管理をサポートしています。例えば、英語のファイル `content/docs/_index.md` がある場合、フランス語の翻訳用に `content/docs/_index.fr.md` というファイルを作成できます。 32 | 33 | {{< filetree/container >}} 34 | {{< filetree/folder name="content" >}} 35 | {{< filetree/folder name="docs" state="open" >}} 36 | {{< filetree/file name="_index.md" >}} 37 | {{< filetree/file name="_index.fr.md" >}} 38 | {{< filetree/file name="_index.ja.md" >}} 39 | {{< /filetree/folder >}} 40 | {{< /filetree/folder >}} 41 | {{< /filetree/container >}} 42 | 43 | 注: Hugo は [コンテンツディレクトリによる翻訳](https://gohugo.io/content-management/multilingual/#translation-by-content-directory) もサポートしています。 44 | 45 | ## メニュー項目の翻訳 46 | 47 | ナビゲーションバーのメニュー項目を翻訳するには、`identifier` フィールドを設定する必要があります: 48 | 49 | ```yaml {filename="hugo.yaml"} 50 | menu: 51 | main: 52 | - identifier: documentation 53 | name: Documentation 54 | pageRef: /docs 55 | weight: 1 56 | - identifier: blog 57 | name: Blog 58 | pageRef: /blog 59 | weight: 2 60 | ``` 61 | 62 | そして、対応する i18n ファイルで翻訳します: 63 | 64 | ```yaml {filename="i18n/fr.yaml"} 65 | documentation: Documentation 66 | blog: Blog 67 | ``` 68 | 69 | ## 文字列の翻訳 70 | 71 | 他の場所の文字列を翻訳するには、対応する i18n ファイルに翻訳を追加する必要があります: 72 | 73 | ```yaml {filename="i18n/fr.yaml"} 74 | readMore: Lire la suite 75 | ``` 76 | 77 | テーマで使用される文字列の一覧は `i18n/en.yaml` ファイルで確認できます。 78 | 79 | ## さらに詳しく 80 | 81 | - [Hugo 多言語モード](https://gohugo.io/content-management/multilingual/) 82 | - [Hugo 多言語対応 パート1: コンテンツ翻訳](https://www.regisphilibert.com/blog/2018/08/hugo-multilingual-part-1-managing-content-translation/) 83 | - [Hugo 多言語対応 パート2: 文字列のローカライズ](https://www.regisphilibert.com/blog/2018/08/hugo-multilingual-part-2-i18n-string-localization/) -------------------------------------------------------------------------------- /docs/content/docs/guide/syntax-highlighting.zh-cn.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "语法高亮" 3 | weight: 3 4 | --- 5 | 6 | Hugo 使用纯 Go 编写的通用语法高亮工具 [Chroma](https://github.com/alecthomas/chroma) 来实现代码高亮。建议在 Markdown 内容中使用反引号标记代码块,例如: 7 | 8 | 9 | 10 | ````markdown {filename="Markdown"} 11 | ```python 12 | def say_hello(): 13 | print("Hello!") 14 | ``` 15 | ```` 16 | 17 | 将渲染为: 18 | 19 | ```python 20 | def say_hello(): 21 | print("Hello!") 22 | ``` 23 | 24 | ## 功能特性 25 | 26 | ### 文件名标注 27 | 28 | 通过设置 `filename` 属性可为代码块添加文件名或标题: 29 | 30 | ````markdown {filename="Markdown"} 31 | ```python {filename="hello.py"} 32 | def say_hello(): 33 | print("Hello!") 34 | ``` 35 | ```` 36 | 37 | ```python {filename="hello.py"} 38 | def say_hello(): 39 | print("Hello!") 40 | ``` 41 | 42 | ### 文件链接 43 | 44 | {{< new-feature version="v0.9.2" >}} 45 | 46 | 通过 `base_url` 属性可设置基础 URL,该 URL 会与文件名组合生成可点击的链接。文件名可包含相对路径以指定文件在基础路径中的位置。 47 | 48 | ````markdown {filename="Markdown"} 49 | ```go {base_url="https://github.com/imfing/hextra/blob/main/",filename="docs/hugo.work"} 50 | go 1.20 51 | ``` 52 | ```` 53 | 54 | ```go {base_url="https://github.com/imfing/hextra/blob/main/",filename="docs/hugo.work"} 55 | go 1.20 56 | ``` 57 | 58 | ### 行号显示 59 | 60 | 设置 `linenos=table` 可启用行号,并通过 `linenostart` 指定起始行号: 61 | 62 | ````markdown {filename="Markdown"} 63 | ```python {linenos=table,linenostart=42} 64 | def say_hello(): 65 | print("Hello!") 66 | ``` 67 | ```` 68 | 69 | ```python {linenos=table,linenostart=42} 70 | def say_hello(): 71 | print("Hello!") 72 | ``` 73 | 74 | ### 行高亮 75 | 76 | 通过 `hl_lines` 属性可高亮指定行号(支持数组格式): 77 | 78 | ````markdown {filename="Markdown"} 79 | ```python {linenos=table,hl_lines=[2,4],linenostart=1,filename="hello.py"} 80 | def say_hello(): 81 | print("Hello!") 82 | 83 | def main(): 84 | say_hello() 85 | ``` 86 | ```` 87 | 88 | ```python {linenos=table,hl_lines=[2,4],linenostart=1,filename="hello.py"} 89 | def say_hello(): 90 | print("Hello!") 91 | 92 | def main(): 93 | say_hello() 94 | ``` 95 | 96 | ### 复制按钮 97 | 98 | 代码块默认启用复制功能,可通过站点配置文件修改其行为: 99 | 100 | ```yaml {linenos=table,linenostart=42,filename="hugo.yaml"} 101 | params: 102 | highlight: 103 | copy: 104 | enable: true 105 | # hover | always 106 | display: hover 107 | ``` 108 | 109 | ## 支持语言 110 | 111 | 完整支持的语言列表请参阅 [Chroma 文档](https://github.com/alecthomas/chroma#supported-languages)。 112 | -------------------------------------------------------------------------------- /.github/workflows/pages.yml: -------------------------------------------------------------------------------- 1 | # Build and deploy Hextra docs site to GitHub Pages 2 | name: Deploy Hextra docs site to Pages 3 | 4 | on: 5 | # Runs on pushes targeting the default branch 6 | push: 7 | branches: ["main"] 8 | 9 | # Allows you to run this workflow manually from the Actions tab 10 | workflow_dispatch: 11 | 12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 13 | permissions: 14 | contents: read 15 | pages: write 16 | id-token: write 17 | 18 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 19 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 20 | concurrency: 21 | group: "pages" 22 | cancel-in-progress: false 23 | 24 | # Default to bash 25 | defaults: 26 | run: 27 | shell: bash 28 | 29 | jobs: 30 | # Build job 31 | build: 32 | runs-on: ubuntu-latest 33 | env: 34 | HUGO_VERSION: 0.147.7 35 | steps: 36 | - name: Checkout 37 | uses: actions/checkout@v4 38 | with: 39 | fetch-depth: 0 # fetch all history for .GitInfo and .Lastmod 40 | fetch-tags: true 41 | submodules: recursive 42 | 43 | - name: Setup Go 44 | uses: actions/setup-go@v5 45 | with: 46 | go-version: "1.24" 47 | 48 | - name: Setup Pages 49 | id: pages 50 | uses: actions/configure-pages@v5 51 | 52 | - name: Setup Hugo 53 | run: | 54 | wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \ 55 | && sudo dpkg -i ${{ runner.temp }}/hugo.deb 56 | 57 | - name: Make build script executable 58 | run: chmod +x ./build.sh 59 | 60 | - name: Build all site versions 61 | env: 62 | HUGO_ENVIRONMENT: production 63 | HUGO_ENV: production 64 | run: | 65 | ./build.sh "${{ steps.pages.outputs.base_url }}" 66 | 67 | - name: Upload artifact 68 | uses: actions/upload-pages-artifact@v3 69 | with: 70 | path: ./public 71 | 72 | # Deployment job 73 | deploy: 74 | environment: 75 | name: github-pages 76 | url: ${{ steps.deployment.outputs.page_url }} 77 | runs-on: ubuntu-latest 78 | needs: build 79 | steps: 80 | - name: Deploy to GitHub Pages 81 | id: deployment 82 | uses: actions/deploy-pages@v4 83 | -------------------------------------------------------------------------------- /layouts/blog/list.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 | {{- $readMore := (T "readMore") | default "Read more →" -}} 3 |
      4 | {{ partial "sidebar.html" (dict "context" . "disableSidebar" true "displayPlaceholder" true) }} 5 |
      6 |
      7 | {{ partial "breadcrumb.html" (dict "page" . "enable" false) }} 8 |
      9 | {{ if .Title }}

      {{ .Title }}

      {{ end }} 10 |
      {{ .Content }}
      11 | {{- $pages := partial "utils/sort-pages" (dict "page" . "by" site.Params.blog.list.sortBy "order" site.Params.blog.list.sortOrder) -}} 12 | {{- $pagerSize := site.Params.blog.list.pagerSize | default 10 -}} 13 | {{- $paginator := .Paginate $pages $pagerSize -}} 14 | {{- range $paginator.Pages }} 15 |
      16 |

      {{ .Title }}

      17 | {{ if site.Params.blog.list.displayTags }} 18 |
      19 | {{ partial "tags.html" (dict "context" .) }} 20 |
      21 | {{ end }} 22 |

      {{- partial "utils/page-description" . -}}

      23 |

      24 | 25 | {{- $readMore -}} 26 | 27 |

      28 |

      {{ partial "utils/format-date" .Date }}

      29 |
      30 | {{ end -}} 31 | 32 | {{- if gt $paginator.TotalPages 1 -}} 33 | {{ partial "components/blog-pager.html" $paginator }} 34 | {{- end -}} 35 |
      36 |
      37 |
      38 |
      39 | {{- end -}} -------------------------------------------------------------------------------- /.vscode/tailwind.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1.1, 3 | "atDirectives": [ 4 | { 5 | "name": "@tailwind", 6 | "description": "Use the `@tailwind` directive to insert Tailwind's `base`, `components`, `utilities` and `screens` styles into your CSS.", 7 | "references": [ 8 | { 9 | "name": "Tailwind Documentation", 10 | "url": "https://tailwindcss.com/docs/functions-and-directives#tailwind" 11 | } 12 | ] 13 | }, 14 | { 15 | "name": "@apply", 16 | "description": "Use the `@apply` directive to inline any existing utility classes into your own custom CSS. This is useful when you find a common utility pattern in your HTML that you’d like to extract to a new component.", 17 | "references": [ 18 | { 19 | "name": "Tailwind Documentation", 20 | "url": "https://tailwindcss.com/docs/functions-and-directives#apply" 21 | } 22 | ] 23 | }, 24 | { 25 | "name": "@responsive", 26 | "description": "You can generate responsive variants of your own classes by wrapping their definitions in the `@responsive` directive:\n```css\n@responsive {\n .alert {\n background-color: #E53E3E;\n }\n}\n```\n", 27 | "references": [ 28 | { 29 | "name": "Tailwind Documentation", 30 | "url": "https://tailwindcss.com/docs/functions-and-directives#responsive" 31 | } 32 | ] 33 | }, 34 | { 35 | "name": "@screen", 36 | "description": "The `@screen` directive allows you to create media queries that reference your breakpoints by **name** instead of duplicating their values in your own CSS:\n```css\n@screen sm {\n /* ... */\n}\n```\n…gets transformed into this:\n```css\n@media (min-width: 640px) {\n /* ... */\n}\n```\n", 37 | "references": [ 38 | { 39 | "name": "Tailwind Documentation", 40 | "url": "https://tailwindcss.com/docs/functions-and-directives#screen" 41 | } 42 | ] 43 | }, 44 | { 45 | "name": "@variants", 46 | "description": "Generate `hover`, `focus`, `active` and other **variants** of your own utilities by wrapping their definitions in the `@variants` directive:\n```css\n@variants hover, focus {\n .btn-brand {\n background-color: #3182CE;\n }\n}\n```\n", 47 | "references": [ 48 | { 49 | "name": "Tailwind Documentation", 50 | "url": "https://tailwindcss.com/docs/functions-and-directives#variants" 51 | } 52 | ] 53 | } 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /docs/content/docs/guide/shortcodes/jupyter.zh-cn.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Jupyter Notebook 组件" 3 | linktitle: "Jupyter Notebook" 4 | math: true 5 | sidebar: 6 | exclude: true 7 | --- 8 | 9 | {{< callout type="warning" >}}实验性功能:通过短代码嵌入 Jupyter Notebook。注意并非所有单元格类型都受支持。{{< /callout >}} 10 | 11 | [Jupyter Notebook](https://jupyter.org/) 是 [Project Jupyter](https://jupyter.org/) 推出的语言无关的 HTML 笔记本应用。它允许你创建和分享包含动态代码、数学公式、可视化图表和叙述性文本的文档。 12 | 13 | 14 | 15 | ## 使用方法 16 | 17 | ### 使用本地笔记本 18 | 19 | 要使用 Jupyter Notebook 短代码,你需要在项目中放置一个 Jupyter Notebook 文件。与[添加图片](../../organize-files#add-images)到项目类似,你可以将 Jupyter Notebook 放入 `assets` 文件夹。 20 | 21 | {{< filetree/container >}} 22 | {{< filetree/folder name="assets" >}} 23 | {{< filetree/file name="notebook.ipynb" >}} 24 | {{< /filetree/folder >}} 25 | {{< filetree/folder name="content" >}} 26 | {{< filetree/folder name="docs" >}} 27 | {{< filetree/file name="my-page.md" >}} 28 | {{< /filetree/folder >}} 29 | {{< /filetree/folder >}} 30 | {{< /filetree/container >}} 31 | 32 | 使用 `jupyter` 短代码将笔记本嵌入页面: 33 | 34 | ```markdown {filename="content/docs/my-page.md"} 35 | --- 36 | title: 我的页面 37 | math: true 38 | --- 39 | 40 | {{%/* jupyter "notebook.ipynb" */%}} 41 | ``` 42 | 43 | 或者,你可以利用 Hugo 的[页面包][page-bundles]功能,将 Jupyter Notebook 与 Markdown 文件组织在一起。 44 | 45 | {{< filetree/container >}} 46 | {{< filetree/folder name="content" >}} 47 | {{< filetree/folder name="docs" >}} 48 | {{< filetree/folder name="my-page" >}} 49 | {{< filetree/file name="index.md" >}} 50 | {{< filetree/file name="notebook.ipynb" >}} 51 | {{< /filetree/folder >}} 52 | {{< /filetree/folder >}} 53 | {{< /filetree/folder >}} 54 | {{< /filetree/container >}} 55 | 56 | ```markdown {filename="content/docs/my-page/index.md"} 57 | --- 58 | title: 我的页面 59 | math: true 60 | --- 61 | 62 | {{%/* jupyter "notebook.ipynb" */%}} 63 | ``` 64 | 65 | ### 使用远程笔记本 66 | 67 | 你也可以通过提供笔记本文件的 URL 来使用远程笔记本。例如,要在页面中嵌入 [什么是 Jupyter Notebook](https://github.com/jupyter/notebook/blob/main/docs/source/examples/Notebook/What%20is%20the%20Jupyter%20Notebook.ipynb) 笔记本,可以使用以下短代码: 68 | 69 | ``` 70 | {{%/* jupyter "https://raw.githubusercontent.com/jupyter/notebook/main/docs/source/examples/Notebook/What%20is%20the%20Jupyter%20Notebook.ipynb" */%}} 71 | ``` 72 | 73 | ## 示例笔记本 74 | 75 | {{< callout type="info" >}}以下示例展示的是项目 assets 文件夹中包含的笔记本文件。{{< /callout >}} 76 | 77 | {{% jupyter "example.ipynb" %}} 78 | 79 | [page-bundles]: https://gohugo.io/content-management/page-bundles/#leaf-bundles -------------------------------------------------------------------------------- /docs/content/blog/markdown.zh-cn.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Markdown 语法指南 3 | date: 2020-01-01 4 | authors: 5 | - name: imfing 6 | link: https://github.com/imfing 7 | image: https://github.com/imfing.png 8 | - name: Octocat 9 | link: https://github.com/octocat 10 | image: https://github.com/octocat.png 11 | tags: 12 | - Markdown 13 | - 示例 14 | - 指南 15 | excludeSearch: true 16 | --- 17 | 18 | 本文展示了 Hugo 内容文件中可用的基础 Markdown 语法示例。 19 | 20 | 21 | ## 基础语法 22 | 23 | ### 标题 24 | 25 | ``` 26 | # 一级标题 27 | ## 二级标题 28 | ### 三级标题 29 | #### 四级标题 30 | ##### 五级标题 31 | ###### 六级标题 32 | ``` 33 | 34 | ## 二级标题 35 | ### 三级标题 36 | #### 四级标题 37 | ##### 五级标题 38 | ###### 六级标题 39 | 40 | ### 强调 41 | 42 | ```text 43 | *这段文字会显示为斜体* 44 | _这段文字也会显示为斜体_ 45 | 46 | **这段文字会显示为粗体** 47 | __这段文字也会显示为粗体__ 48 | 49 | _你可以**组合**使用_ 50 | ``` 51 | 52 | *这段文字会显示为斜体* 53 | 54 | _这段文字也会显示为斜体_ 55 | 56 | **这段文字会显示为粗体** 57 | 58 | __这段文字也会显示为粗体__ 59 | 60 | _你可以**组合**使用_ 61 | 62 | ### 列表 63 | 64 | #### 无序列表 65 | 66 | ``` 67 | * 项目1 68 | * 项目2 69 | * 子项目2a 70 | * 子项目2b 71 | ``` 72 | 73 | * 项目1 74 | * 项目2 75 | * 子项目2a 76 | * 子项目2b 77 | 78 | #### 有序列表 79 | 80 | ``` 81 | 1. 项目1 82 | 2. 项目2 83 | 3. 项目3 84 | 1. 子项目3a 85 | 2. 子项目3b 86 | ``` 87 | 88 | ### 图片 89 | 90 | ```markdown 91 | ![GitHub Logo](https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png) 92 | ``` 93 | 94 | ![GitHub Logo](https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png) 95 | 96 | ### 链接 97 | 98 | ```markdown 99 | [Hugo](https://gohugo.io) 100 | ``` 101 | 102 | [Hugo](https://gohugo.io) 103 | 104 | ### 引用块 105 | 106 | ```markdown 107 | 正如牛顿所说: 108 | 109 | > 如果说我看得比别人更远些,那是因为我站在巨人的肩膀上。 110 | ``` 111 | 112 | > 如果说我看得比别人更远些,那是因为我站在巨人的肩膀上。 113 | 114 | ### 行内代码 115 | 116 | ```markdown 117 | 行内`代码`会用`反引号包裹`起来。 118 | ``` 119 | 120 | 行内`代码`会用`反引号包裹`起来。 121 | 122 | ### 代码块 123 | 124 | #### 语法高亮 125 | 126 | ````markdown 127 | ```go 128 | func main() { 129 | fmt.Println("Hello World") 130 | } 131 | ``` 132 | ```` 133 | 134 | ```go 135 | func main() { 136 | fmt.Println("Hello World") 137 | } 138 | ``` 139 | 140 | ### 表格 141 | 142 | ```markdown 143 | | 语法 | 描述 | 144 | | --------- | ----------- | 145 | | 标题 | 标题文本 | 146 | | 段落 | 正文内容 | 147 | ``` 148 | 149 | | 语法 | 描述 | 150 | | --------- | ----------- | 151 | | 标题 | 标题文本 | 152 | | 段落 | 正文内容 | 153 | 154 | ## 参考资料 155 | 156 | - [Markdown 语法](https://www.markdownguide.org/basic-syntax/) 157 | - [Hugo Markdown](https://gohugo.io/content-management/formats/#markdown) --------------------------------------------------------------------------------