jekyll-theme-modootoday 1.2.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 67e8a88d61c5558082ea15e0708087ba58f746b25c96e6e9a7a551548a56796e
4
- data.tar.gz: b9c58c0639beae968c207837f0433e7f41dc90a13053ceb50180425d68a6c403
3
+ metadata.gz: 9eb1c4e782cdbaba12079575f273b74a14e9a0e701139858cbf72bf665409d2d
4
+ data.tar.gz: 41b86c06c720c2ca4077aed45c2e1cf8457aa2774630ffc3e28c8e8aa1041afa
5
5
  SHA512:
6
- metadata.gz: bd0016d4f7ff9d31ea3c50f312348402aba195ecae900b5eb51fb942edf09d4067e05ec4d73ebc4e733a624378f878a2f9b9241f0b90bc30cf2cf545826b32fe
7
- data.tar.gz: b0c6ad0227548f39fb8fb5429695c6c13985714cdd3cb730756601a1f322d0d580d02f6ce98da9ead3f5d997d678d120e84addbf139d938666fd937ede73c674
6
+ metadata.gz: fd67889b39a19ad4d5e462543d8eb237d8e5823a2713aeeb9d7189d72ab71bbaf252f83e97a406edfb75ba760b822d9137bd211d8670f8cd47264d39a9c6d197
7
+ data.tar.gz: b7185e039610c3d5641eb29bf34a91bc436bdf3113645dd4ed07036e5d2d55d388bb1ffc74ea932d2ad0c88e70235ac2c123f45a002f902f5da2b3abde263dcf
data/CHANGELOG.md CHANGED
@@ -6,6 +6,33 @@ The content rules have their own version header (`md-components v1`) in [RULES.m
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [1.3.0] - 2026-10-31
10
+
11
+ ### Added
12
+
13
+ - `reference` layout, opt-in API sidebar: `sidebar: true` puts the member list in a side column that stays in view from 64rem up, with members grouped under their `group:` label (in order of first use); narrower screens show the same list above the page. CSS only, in the docs-extra bundle.
14
+ - `reference` layout, opt-in package table: `packages: [{name, version, text, url, links: [{label, url}]}]` (and an optional `packages_title:` caption) lists packages or crates with name, version, description and links before the body; rows stack into cards on small screens. The table is also available as `{% include modootoday/docs-extra/packages.html items=… %}`. A page with `packages:` may leave out `members:`.
15
+ - `modootoday-check` reports a `sidebar:` that is not true or false, a package with no `name`, and a package link with no `url`.
16
+ - API reference demo (en, ko, ja) and docs for both parts; the docs audit covers the new demo page.
17
+
18
+ ## [1.2.3] - 2026-10-31
19
+
20
+ ### Changed
21
+
22
+ - In a `c: features` card, the separator after a bold title written as `**Title**: text` or `**Title**:text` is not shown, the same as ` — ` already was. Only the one separator right after an item's opening title goes; `**Title**::`, `**Title**:text` with no space, colons later in the text and bold text mid-item are unchanged.
23
+
24
+ ### Fixed
25
+
26
+ - The `redirect` layout reads the target from `page.redirect.to`, where jekyll-redirect-from 0.16 puts it, as well as from `redirect_to`; redirect stubs had an empty refresh `url=`, an empty canonical and an empty "Continue to the new page" link. The refresh, canonical and link use the same target, and the docs audit flags empty ones.
27
+ - On a site without search the header's language menu and theme toggle sit at the inline end of the row (the first trailing control takes `margin-inline-start: auto`), in LTR and RTL; headers with search are unchanged. The docs audit checks the gap at 1440px and 390px.
28
+ - `modootoday-check` accepts a link whose text is a code span, such as [`file.tsx`](…); the code text is its accessible name. Links with no text, or only emphasis marks, are still an "empty link text" error.
29
+
30
+ ### Documentation
31
+
32
+ - README (English and Korean): the page layout families, section options (`c: split`, `bleed:`, `reveal:`), the 23 label languages with RTL, and the optional extras (search, light/dark toggle, Mermaid, KaTeX, JSON-LD); the guide list links Layouts, Recipes, Math and diagrams, Translation rules and Structured data. The gem description names the layouts and languages.
33
+ - Migrate and upgrade: a 1.0/1.1 → 1.2 row (en, ko, ja). The example home page shows a `bleed:` band.
34
+ - Install (en, ko, ja): running the checker on a `remote_theme` site, where `bundle exec modootoday-check` is not available: `gem install jekyll-theme-modootoday -v '~> 1.2'`, `ruby -S` when the script is not on `PATH`, `GEM_PATH="$(gem env gemdir)"` for `Gem::GemNotFoundException`, and running `exe/modootoday-check` from the release source without installing a gem.
35
+
9
36
  ## [1.2.2] - 2026-10-31
10
37
 
11
38
  ### Fixed
@@ -248,7 +275,9 @@ Internal development milestones, never released. They are all part of 1.0.0.
248
275
  - Example: `sass.silence_deprecations: [import]` for Dart Sass; `llms.txt` per language generated instead of hand-written.
249
276
  - Raw `<name>.md` copies in `_site` on GitHub Pages: caused by content files without front matter (rendered by `jekyll-optional-front-matter` and also copied). Front matter is now required and checked.
250
277
 
251
- [Unreleased]: https://github.com/modootoday/jekyll-theme-modootoday/compare/v1.2.2...HEAD
278
+ [Unreleased]: https://github.com/modootoday/jekyll-theme-modootoday/compare/v1.3.0...HEAD
279
+ [1.3.0]: https://github.com/modootoday/jekyll-theme-modootoday/releases/tag/v1.3.0
280
+ [1.2.3]: https://github.com/modootoday/jekyll-theme-modootoday/releases/tag/v1.2.3
252
281
  [1.2.2]: https://github.com/modootoday/jekyll-theme-modootoday/releases/tag/v1.2.2
253
282
  [1.2.1]: https://github.com/modootoday/jekyll-theme-modootoday/releases/tag/v1.2.1
254
283
  [1.2.0]: https://github.com/modootoday/jekyll-theme-modootoday/releases/tag/v1.2.0
data/README.ko.md CHANGED
@@ -16,9 +16,13 @@
16
16
  - **페이지에는 표준 Markdown만.** GFM과 GitHub 알림만 쓰므로 같은 파일이 github.com에서도 잘 읽힙니다.
17
17
  - **GitHub Pages에서 동작.** 레이아웃과 include가 Liquid만 쓰므로 기본 빌드의 `remote_theme`도 되고, Jekyll 4도 됩니다.
18
18
  - **마크업 없는 컴포넌트.** 알림, 상태 배지, 카드, 탭, 버튼, 아코디언, 단계, 타임라인 등이 평범한 Markdown 패턴에서 나옵니다.
19
+ - **페이지 계열.** 문서 외에도 레이아웃이 40개쯤 있습니다. 홈, 블로그와 뉴스, 디렉터리(팀, 채용, 행사, 후원사, 포트폴리오), 상세 페이지, 마케팅(가격, 기능, 문의, 링크 모음), 문서(약관, 이력서), 문서 부가 페이지(레퍼런스, 변경 기록, 로드맵, 용어집, 강좌, 책)가 있습니다.
20
+ - **디자인된 듯한 섹션.** `sections:` 항목에 `visual:` include나 코드와 함께 쓰는 `c: split`, 전체 너비 `bleed:` 띠, `reveal:` 페이드인, 4열 카드 같은 옵션을 줄 수 있고, 분할 히어로도 같은 방식으로 씁니다.
21
+ - **23개 언어, LTR과 RTL.** 테마 문구가 23개 언어로 현지화되어 있고 언어 메뉴, `hreflang`, 오른쪽에서 왼쪽으로 쓰는 레이아웃을 지원합니다.
19
22
  - **에이전트가 읽기 쉬움.** 페이지마다 바이트 단위로 같은 Markdown 버전과 `llms.txt`, `llms-full.txt`를 둘 수 있습니다.
20
23
  - **접근성.** 키보드 단축키, 보이는 포커스, 휴대폰 안전 영역, 44 px 터치 대상, 고대비와 동작 줄이기가 기본으로 들어 있습니다.
21
24
  - **검사기.** `modootoday-check`가 원문과 빌드 결과를 검사합니다.
25
+ - **선택 기능.** 검색, 라이트/다크 전환, Mermaid 다이어그램과 KaTeX 수식(기본은 꺼져 있고 쓰는 페이지에서만 불러옵니다), schema.org JSON-LD를 제공합니다.
22
26
 
23
27
  ## 설치
24
28
 
@@ -26,7 +30,7 @@ gem 방식(`theme:`):
26
30
 
27
31
  ```ruby
28
32
  # Gemfile
29
- gem "jekyll-theme-modootoday", "~> 1.2"
33
+ gem "jekyll-theme-modootoday", "~> 1.3"
30
34
  ```
31
35
 
32
36
  ```yaml
@@ -38,7 +42,7 @@ Gemfile 없이 GitHub Pages에서(`remote_theme:`):
38
42
 
39
43
  ```yaml
40
44
  # _config.yml
41
- remote_theme: modootoday/jekyll-theme-modootoday@v1.2.2
45
+ remote_theme: modootoday/jekyll-theme-modootoday@v1.3.0
42
46
  plugins:
43
47
  - jekyll-remote-theme
44
48
  ```
@@ -49,7 +53,7 @@ plugins:
49
53
 
50
54
  ```sh
51
55
  mkdir my-docs && cd my-docs
52
- printf 'source "https://rubygems.org"\ngem "jekyll", "~> 4.4"\ngem "jekyll-theme-modootoday", "~> 1.2"\n' > Gemfile
56
+ printf 'source "https://rubygems.org"\ngem "jekyll", "~> 4.4"\ngem "jekyll-theme-modootoday", "~> 1.3"\n' > Gemfile
53
57
  printf 'theme: jekyll-theme-modootoday\nmarkdown: kramdown\nkramdown: {input: GFM}\nsass: {style: compressed, silence_deprecations: [import, global-builtin]}\n' > _config.yml
54
58
  printf -- '---\nlayout: doc\ntitle: Home\n---\n# Hello\n\n> [!TIP]\n> Plain Markdown, styled.\n' > index.md
55
59
  bundle install && bundle exec jekyll build
@@ -96,7 +100,7 @@ bundle exec modootoday-check . _site
96
100
  ## 가이드
97
101
 
98
102
  - [문서 사이트](https://modootoday.github.io/jekyll-theme-modootoday/ko/) ([`docs/`](docs/)에서 이 테마로 빌드)
99
- - [설치](https://modootoday.github.io/jekyll-theme-modootoday/ko/guides/install/) · [첫 페이지](https://modootoday.github.io/jekyll-theme-modootoday/ko/guides/first-page/) · [컴포넌트](https://modootoday.github.io/jekyll-theme-modootoday/ko/components/) · [설정](https://modootoday.github.io/jekyll-theme-modootoday/ko/guides/configuration/) · [커스터마이즈](https://modootoday.github.io/jekyll-theme-modootoday/ko/guides/customize/) · [블로그와 뉴스](https://modootoday.github.io/jekyll-theme-modootoday/ko/layouts/blog-news/) · [공개 API](https://modootoday.github.io/jekyll-theme-modootoday/ko/reference/api/) · [이전과 업그레이드](https://modootoday.github.io/jekyll-theme-modootoday/ko/guides/upgrade/) · [CSP](https://modootoday.github.io/jekyll-theme-modootoday/ko/recipes/csp/) · [접근성](https://modootoday.github.io/jekyll-theme-modootoday/ko/guides/accessibility/) · [로드맵](https://modootoday.github.io/jekyll-theme-modootoday/ko/reference/roadmap/) · [변경 기록](CHANGELOG.md)
103
+ - [설치](https://modootoday.github.io/jekyll-theme-modootoday/ko/guides/install/) · [첫 페이지](https://modootoday.github.io/jekyll-theme-modootoday/ko/guides/first-page/) · [컴포넌트](https://modootoday.github.io/jekyll-theme-modootoday/ko/components/) · [설정](https://modootoday.github.io/jekyll-theme-modootoday/ko/guides/configuration/) · [커스터마이즈](https://modootoday.github.io/jekyll-theme-modootoday/ko/guides/customize/) · [레이아웃](https://modootoday.github.io/jekyll-theme-modootoday/ko/layouts/) · [블로그와 뉴스](https://modootoday.github.io/jekyll-theme-modootoday/ko/layouts/blog-news/) · [레시피](https://modootoday.github.io/jekyll-theme-modootoday/ko/recipes/) · [수식과 다이어그램](https://modootoday.github.io/jekyll-theme-modootoday/ko/recipes/math-diagrams/) · [번역 규칙](https://modootoday.github.io/jekyll-theme-modootoday/ko/guides/translation/) · [구조화 데이터](https://modootoday.github.io/jekyll-theme-modootoday/ko/guides/structured-data/) · [공개 API](https://modootoday.github.io/jekyll-theme-modootoday/ko/reference/api/) · [이전과 업그레이드](https://modootoday.github.io/jekyll-theme-modootoday/ko/guides/upgrade/) · [CSP](https://modootoday.github.io/jekyll-theme-modootoday/ko/recipes/csp/) · [접근성](https://modootoday.github.io/jekyll-theme-modootoday/ko/guides/accessibility/) · [로드맵](https://modootoday.github.io/jekyll-theme-modootoday/ko/reference/roadmap/) · [변경 기록](CHANGELOG.md)
100
104
  - 지원 스택: GitHub Pages(`github-pages` 232, Jekyll 3.10, Ruby 3.3.4)와 Jekyll 4.4(Ruby 3.2~3.4), 모두 CI에서 테스트합니다. Jekyll 3.9를 하한으로 테스트합니다.
101
105
  - [보안 정책](SECURITY.md) · [행동 강령](CODE_OF_CONDUCT.md)
102
106
 
data/README.md CHANGED
@@ -13,9 +13,13 @@ A Jekyll theme that keeps page bodies in plain GitHub Markdown and styles them w
13
13
  - **Only standard Markdown in your pages.** GFM plus GitHub alerts; the same file reads well on github.com.
14
14
  - **Works on GitHub Pages.** Layouts and includes are Liquid only, so `remote_theme` works on the classic build; Jekyll 4 works too.
15
15
  - **Components without markup.** Alerts, status badges, card grids, tabs, buttons, accordion, steps, timeline and more come from plain Markdown patterns.
16
+ - **Page families.** About 40 layouts beyond docs: home, blog and news, directory (team, jobs, events, sponsors, portfolio), detail pages, marketing (pricing, feature, contact, links), documents (legal, resume) and docs extras (reference, changelog, roadmap, glossary, course, book).
17
+ - **Sections that look designed.** `sections:` items take options such as `c: split` with a `visual:` include or code, full-width `bleed:` bands, `reveal:` fade-ins and four-column cards; a split hero works the same way.
18
+ - **23 languages, LTR and RTL.** Theme labels ship localized for 23 languages, with a language menu, `hreflang` and right-to-left layouts.
16
19
  - **Readable by agents.** Every page can have a byte-identical Markdown twin, plus `llms.txt` and `llms-full.txt`.
17
20
  - **Accessible.** Keyboard shortcuts, visible focus, safe areas on phones, 44 px touch targets, high contrast and reduced motion are built in.
18
21
  - **Checked.** `modootoday-check` validates the sources and the built site.
22
+ - **Optional extras.** Search, a light/dark toggle, Mermaid diagrams and KaTeX math (off by default, loaded only on pages that use them) and schema.org JSON-LD.
19
23
 
20
24
  ## Install
21
25
 
@@ -23,7 +27,7 @@ As a gem (`theme:`):
23
27
 
24
28
  ```ruby
25
29
  # Gemfile
26
- gem "jekyll-theme-modootoday", "~> 1.2"
30
+ gem "jekyll-theme-modootoday", "~> 1.3"
27
31
  ```
28
32
 
29
33
  ```yaml
@@ -35,7 +39,7 @@ On GitHub Pages without a Gemfile (`remote_theme:`):
35
39
 
36
40
  ```yaml
37
41
  # _config.yml
38
- remote_theme: modootoday/jekyll-theme-modootoday@v1.2.2
42
+ remote_theme: modootoday/jekyll-theme-modootoday@v1.3.0
39
43
  plugins:
40
44
  - jekyll-remote-theme
41
45
  ```
@@ -46,7 +50,7 @@ Pin a tag or a commit. More options: [Install guide](https://modootoday.github.i
46
50
 
47
51
  ```sh
48
52
  mkdir my-docs && cd my-docs
49
- printf 'source "https://rubygems.org"\ngem "jekyll", "~> 4.4"\ngem "jekyll-theme-modootoday", "~> 1.2"\n' > Gemfile
53
+ printf 'source "https://rubygems.org"\ngem "jekyll", "~> 4.4"\ngem "jekyll-theme-modootoday", "~> 1.3"\n' > Gemfile
50
54
  printf 'theme: jekyll-theme-modootoday\nmarkdown: kramdown\nkramdown: {input: GFM}\nsass: {style: compressed, silence_deprecations: [import, global-builtin]}\n' > _config.yml
51
55
  printf -- '---\nlayout: doc\ntitle: Home\n---\n# Hello\n\n> [!TIP]\n> Plain Markdown, styled.\n' > index.md
52
56
  bundle install && bundle exec jekyll build
@@ -93,7 +97,7 @@ Walkthrough: [Write your first page](https://modootoday.github.io/jekyll-theme-m
93
97
  ## Guides
94
98
 
95
99
  - [Documentation site](https://modootoday.github.io/jekyll-theme-modootoday/) (built with this theme from [`docs/`](docs/))
96
- - [Install](https://modootoday.github.io/jekyll-theme-modootoday/guides/install/) · [First page](https://modootoday.github.io/jekyll-theme-modootoday/guides/first-page/) · [Components](https://modootoday.github.io/jekyll-theme-modootoday/components/) · [Configuration](https://modootoday.github.io/jekyll-theme-modootoday/guides/configuration/) · [Customize](https://modootoday.github.io/jekyll-theme-modootoday/guides/customize/) · [Blog and news](https://modootoday.github.io/jekyll-theme-modootoday/layouts/blog-news/) · [Public API](https://modootoday.github.io/jekyll-theme-modootoday/reference/api/) · [Migrate and upgrade](https://modootoday.github.io/jekyll-theme-modootoday/guides/upgrade/) · [CSP](https://modootoday.github.io/jekyll-theme-modootoday/recipes/csp/) · [Accessibility](https://modootoday.github.io/jekyll-theme-modootoday/guides/accessibility/) · [Roadmap](https://modootoday.github.io/jekyll-theme-modootoday/reference/roadmap/) · [Changelog](CHANGELOG.md)
100
+ - [Install](https://modootoday.github.io/jekyll-theme-modootoday/guides/install/) · [First page](https://modootoday.github.io/jekyll-theme-modootoday/guides/first-page/) · [Components](https://modootoday.github.io/jekyll-theme-modootoday/components/) · [Configuration](https://modootoday.github.io/jekyll-theme-modootoday/guides/configuration/) · [Customize](https://modootoday.github.io/jekyll-theme-modootoday/guides/customize/) · [Layouts](https://modootoday.github.io/jekyll-theme-modootoday/layouts/) · [Blog and news](https://modootoday.github.io/jekyll-theme-modootoday/layouts/blog-news/) · [Recipes](https://modootoday.github.io/jekyll-theme-modootoday/recipes/) · [Math and diagrams](https://modootoday.github.io/jekyll-theme-modootoday/recipes/math-diagrams/) · [Translation rules](https://modootoday.github.io/jekyll-theme-modootoday/guides/translation/) · [Structured data](https://modootoday.github.io/jekyll-theme-modootoday/guides/structured-data/) · [Public API](https://modootoday.github.io/jekyll-theme-modootoday/reference/api/) · [Migrate and upgrade](https://modootoday.github.io/jekyll-theme-modootoday/guides/upgrade/) · [CSP](https://modootoday.github.io/jekyll-theme-modootoday/recipes/csp/) · [Accessibility](https://modootoday.github.io/jekyll-theme-modootoday/guides/accessibility/) · [Roadmap](https://modootoday.github.io/jekyll-theme-modootoday/reference/roadmap/) · [Changelog](CHANGELOG.md)
97
101
  - Supported stacks: GitHub Pages (`github-pages` 232, Jekyll 3.10, Ruby 3.3.4) and Jekyll 4.4 on Ruby 3.2 to 3.4, all tested in CI; Jekyll 3.9 is the tested floor.
98
102
  - [Security policy](SECURITY.md) · [Code of conduct](CODE_OF_CONDUCT.md)
99
103
 
data/RULES.md CHANGED
@@ -22,7 +22,7 @@ Every content page starts with front matter; an empty block (`---` then `---`) i
22
22
  | Full-width band | front matter `bleed: true` or `bleed: wide` on `hero:` or a section item | `.mt-bleed` (plus `.mt-bleed-wide`) on the section, no wrapper; the optional `bleed` sheet paints `--mt-bleed-bg` to the viewport edges, `wide` widens the content up to the container | other values are checker errors |
23
23
  | Card badge at the bottom | `badge: bottom` on a `c: features` item | `.mt-badge-bottom` on the section; a `.mt-badge` that is a direct child of a card sits at its bottom edge | badge after the text |
24
24
  | Section mapping | each `sections:` item is a string `name` or `{c: component, name: key, ...params}`. No implicit mapping. Item count ≠ top-level `## ` count is a checker error; setext `---` headings, `##` in quotes/alerts/list items, `##` indented 1–3 spaces and `##` inside HTML comments are checker errors | `data-section`=name, `data-c`=c, class `mt-c-<c>` | none |
25
- | Card grid | under `##`, list items `- **Title** — text` or `- **Title**: text` | CSS only | list |
25
+ | Card grid | under `##`, list items `- **Title** — text` or `- **Title**: text` (the separator after the title is not shown) | CSS only | list |
26
26
  | CTA buttons | every link-only paragraph in `section.mt-hero` and in `c: cta` sections; the first link is primary. Separator text such as `·` between links is a text node, so the paragraph still counts as link-only | CSS `p:has(> a):not(:has(> :not(a)))` | links |
27
27
  | Install tabs | in a `c: tabs` section, repeated `### name` + fenced code block (info string = one language word) | `data-tabs` + i18n `tabs.label`; `assets/js/modootoday/tabs.js` builds WAI-ARIA tabs (arrows, Home, End) | all blocks in order |
28
28
  | Diagrams, math | ```` ```mermaid ```` / ```` ```math ````, a `$$` block on its own lines; inline `$…$` only with `modootoday.math.inline: true` (otherwise a checker warning) | off by default. `modootoday.mermaid` / `modootoday.math` load a version-pinned renderer with SRI `integrity` (or a self-hosted path) plus `assets/js/modootoday-{mermaid,math}.js`, only on pages with a block; front matter `mermaid: false` / `math: false` skips a page. A CDN adds its origin to `script-src` (math also `style-src`, `font-src`) and receives visitors' IP addresses; Mermaid needs `style-src 'unsafe-inline'`. Any other third-party script or stylesheet, or one without matching `integrity` and `crossorigin="anonymous"`, is a checker error (docs: Math and diagrams) | code / GitHub mermaid, math |
@@ -0,0 +1,14 @@
1
+ {%- include modootoday/i18n.html -%}
2
+ {%- comment -%}Package table: include.items is [{name, version, text, url, links: [{label, url}]}]; include.caption is optional.
3
+ One row per package (the name is the row header, the text under it); rows stack into cards on narrow screens. CSS in docs-extra.{%- endcomment -%}
4
+ <table class="mt-dx-pkgs">
5
+ {%- if include.caption %}<caption>{{ include.caption }}</caption>{% endif %}
6
+ <thead><tr><th scope="col">{{ mt_t_layouts_name }}</th><th scope="col">{{ mt_t_layouts_version }}</th><th scope="col">{{ mt_t_layouts_links }}</th></tr></thead>
7
+ <tbody>
8
+ {%- for p in include.items %}
9
+ <tr id="{{ p.id | default: p.name | slugify }}"><th scope="row"><code>{% if p.url %}<a href="{% include modootoday/link.html url=p.url %}">{{ p.name }}</a>{% else %}{{ p.name }}{% endif %}</code>{% if p.text %}<span>{{ p.text | markdownify | remove: "<p>" | remove: "</p>" | strip }}</span>{% endif %}</th>
10
+ <td data-label="{{ mt_t_layouts_version }}">{% if p.version %}<code>{{ p.version }}</code>{% endif %}</td>
11
+ <td data-label="{{ mt_t_layouts_links }}">{% if p.links.size > 0 %}<ul>{% for l in p.links %}<li><a href="{% include modootoday/link.html url=l.url %}"{% include modootoday/links/attrs.html on=l.new_window target=l.target url=l.url %}>{{ l.label }}</a></li>{% endfor %}</ul>{% endif %}</td></tr>
12
+ {%- endfor %}
13
+ </tbody>
14
+ </table>
@@ -44,6 +44,11 @@ modootoday-check fails when the item count differs from the h2 count.
44
44
  {%- if site.modootoday.lists and _cc == nil -%}{%- capture _body %}{% include modootoday/markdown/lists.html html=_p %}{% endcapture -%}{%- endif -%}
45
45
  {%- if _cc == 'cta' -%}{%- capture _body %}{% include modootoday/actions.html html=_p %}{% endcapture -%}{%- endif -%}
46
46
  {%- if _cc == 'features' -%}{%- assign _body = _body | replace: "</strong> — ", "</strong> " | replace: "</strong> – ", "</strong> " | replace: "</strong> - ", "</strong> " -%}{%- endif -%}
47
+ {%- comment -%}features: a card that starts with **Title**: or **Title**: drops that one separator (the title is its own line); later colons and other bold text stay.{%- endcomment -%}
48
+ {%- if _cc == 'features' and _body contains "<li><strong>" -%}{%- assign _fp = _body | split: "<li><strong>" -%}
49
+ {%- capture _body -%}{{ _fp[0] }}{%- for _x in _fp offset:1 -%}{%- assign _tt = _x | split: "</strong>" | first -%}{%- assign _ra = _x | remove_first: _tt | slice: 0, 11 -%}{%- assign _rb = _x | remove_first: _tt | slice: 0, 10 -%}
50
+ {%- if _tt contains "<li" or _tt contains "</li>" -%}<li><strong>{{ _x }}{%- elsif _ra == "</strong>: " -%}<li><strong>{{ _tt }}</strong> {{ _x | remove_first: _tt | remove_first: "</strong>: " }}{%- elsif _rb == "</strong>:" -%}<li><strong>{{ _tt }}</strong> {{ _x | remove_first: _tt | remove_first: "</strong>:" | lstrip }}{%- else -%}<li><strong>{{ _x }}{%- endif -%}
51
+ {%- endfor -%}{%- endcapture -%}{%- endif -%}
47
52
  {%- if _cc and mt_c_transforms contains _cc -%}{%- capture _body %}{% include modootoday/markdown/c/{{ _cc }}.html html=_body s=_s i=forloop.index id=_n %}{% endcapture -%}{%- endif -%}
48
53
  <section class="mt-section{% if _cc %} mt-c-{{ _cc }}{% endif %}{% if _cc == 'cta' %}{% unless _body contains 'data-mt-result' %} mt-cta{% endunless %}{% endif %}{% if _s.cols %} mt-cols-{{ _s.cols }}{% endif %}{% if _s.decor %} mt-has-decor{% endif %}{% if _s.reveal == true %} mt-reveal{% endif %}{% if _s.bleed %} mt-bleed{% if _s.bleed == 'wide' %} mt-bleed-wide{% endif %}{% endif %}{% if _cc == 'features' and _s.badge == 'bottom' %} mt-badge-bottom{% endif %}{% if _cc == 'split' %}{% if _s.side == 'start' %} mt-split-start{% endif %}{% if _s.ratio == '5:7' %} mt-split-5-7{% endif %}{% endif %}" data-section="{{ _n | default: forloop.index0 }}"{% if _cc %} data-c="{{ _cc }}"{% endif %}{% if _cc == 'tabs' %} data-tabs data-tabs-label="{{ _tl }}"{% endif %}>
49
54
  {%- if _cc == 'split' %}
@@ -1,10 +1,14 @@
1
- {%- comment -%}redirect: standalone page that sends visitors to page.redirect_to (meta refresh, no script, so it
1
+ {%- comment -%}redirect: standalone page that sends visitors to page.redirect.to (jekyll-redirect-from) or page.redirect_to (meta refresh, no script, so it
2
2
  works under a strict CSP), with a canonical link for search engines and a visible link for everyone else.{%- endcomment -%}
3
3
  {%- assign _lang = page.lang | default: site.lang | default: "en" -%}
4
4
  {%- include modootoday/i18n.html lang=_lang -%}
5
5
  {%- assign _rtl = "ar fa he ur yi ps sd ug dv ckb" | split: " " -%}{%- assign _b = _lang | split: "-" | first -%}
6
6
  {%- if _rtl contains _b %}{% assign _dir = "rtl" %}{% else %}{% assign _dir = nil %}{% endif %}{%- assign _dir = mt_t_direction | default: _dir -%}
7
- {%- assign _to = page.redirect_to -%}{%- unless _to contains "://" -%}{%- assign _to = _to | relative_url -%}{%- endunless -%}
7
+ {%- comment -%}jekyll-redirect-from gives page.redirect.to already resolved (site.url + baseurl); a hand-written
8
+ redirect_to is a site path or a full URL. The refresh, canonical and link all use the same target.{%- endcomment -%}
9
+ {%- if page.redirect.to -%}{%- assign _to = page.redirect.to -%}{%- assign _abs = _to -%}
10
+ {%- elsif page.redirect_to contains "://" -%}{%- assign _to = page.redirect_to -%}{%- assign _abs = _to -%}
11
+ {%- else -%}{%- assign _to = page.redirect_to | relative_url -%}{%- assign _abs = page.redirect_to | absolute_url -%}{%- endif -%}
8
12
  <!doctype html>
9
13
  <html lang="{{ _lang }}"{% if _dir %} dir="{{ _dir }}"{% endif %}>
10
14
  <head>
@@ -12,7 +16,7 @@
12
16
  <meta name="viewport" content="width=device-width, initial-scale=1">
13
17
  <title>{{ mt_t_pages_moved }}</title>
14
18
  <meta name="robots" content="noindex">
15
- <link rel="canonical" href="{% if page.redirect_to contains '://' %}{{ _to }}{% else %}{{ page.redirect_to | absolute_url }}{% endif %}">
19
+ <link rel="canonical" href="{{ _abs }}">
16
20
  <meta http-equiv="refresh" content="0; url={{ _to }}">
17
21
  </head>
18
22
  <body>
@@ -3,13 +3,22 @@ layout: default
3
3
  mt_bundle: docs-extra
4
4
  mt_main: mt-dx mt-dx-reference
5
5
  ---
6
- {%- comment -%}reference: an API or option reference. members: [{name, signature, text, since, deprecated, id}] become a contents
7
- list and one section each (h2 with the name in code, the signature, the text, since / deprecated notes); the body comes first.{%- endcomment -%}
8
- <article aria-labelledby="mt-dx-title">
6
+ {%- comment -%}reference: an API or option reference. members: [{name, signature, text, since, deprecated, id, group}] become a contents
7
+ list and one section each (h2 with the name in code, the signature, the text, since / deprecated notes); the body comes first.
8
+ Opt-in: sidebar: true puts the contents in a sticky side column (members grouped by group, in order of first use; CSS only, a plain
9
+ list on narrow screens). packages: [{name, version, text, url, links: [{label, url}]}] adds a package table (packages.html) before the body.{%- endcomment -%}
10
+ <article aria-labelledby="mt-dx-title"{% if page.sidebar %} class="mt-dx-api"{% endif %}>
9
11
  {%- include modootoday/docs-extra/head.html %}
10
- {%- if page.members.size > 1 %}
12
+ {%- if page.sidebar and page.members.size > 0 %}
13
+ <nav class="mt-dx-side" aria-label="{{ mt_t_layouts_contents }}"><ul>
14
+ {%- assign _groups = page.members | group_by: "group" %}{% for g in _groups %}
15
+ {%- capture _links %}{% for m in g.items %}<li><a href="#{{ m.id | default: m.name | slugify }}"><code>{{ m.name }}</code></a></li>{% endfor %}{% endcapture %}
16
+ {%- if g.name != "" %}<li><span class="mt-dx-side-h">{{ g.name }}</span><ul>{{ _links }}</ul></li>{% else %}{{ _links }}{% endif %}
17
+ {%- endfor %}</ul></nav>
18
+ {%- elsif page.members.size > 1 %}
11
19
  <nav class="mt-dx-toc" aria-label="{{ mt_t_layouts_contents }}"><ul>{% for m in page.members %}<li><a href="#{{ m.id | default: m.name | slugify }}"><code>{{ m.name }}</code></a></li>{% endfor %}</ul></nav>
12
20
  {%- endif %}
21
+ {%- if page.packages %}{% include modootoday/docs-extra/packages.html items=page.packages caption=page.packages_title %}{% endif %}
13
22
  <div class="mt-dx-body">
14
23
  {{ content }}
15
24
  </div>
@@ -35,3 +35,36 @@
35
35
  .mt-dx-chapters li { padding: .5rem 0; border-bottom: 1px solid mt(border); }
36
36
  @media print { .mt-dx-toc, .mt-dx-letters { display: none; } .mt-dx-col, .mt-dx-member, .mt-dx-release { break-inside: avoid; } }
37
37
  }
38
+ // Opt-in reference parts: the API sidebar (sidebar: true) and the package table (packages:).
39
+ @include mt-layer(components) {
40
+ .mt-dx-side ul { margin: 0 0 1.5rem; padding: 0; list-style: none; }
41
+ .mt-dx-side ul ul { margin: .25rem 0 .75rem; }
42
+ .mt-dx-side a { display: block; padding: .25rem .5rem; border-radius: mt(radius); text-decoration: none; }
43
+ .mt-dx-side a:hover { background: mt(muted); }
44
+ .mt-dx-side-h { display: block; padding: .5rem .5rem .25rem; font-size: .8125rem; font-weight: 600; color: mt(muted-foreground); }
45
+ @media (min-width: 64rem) {
46
+ .mt-dx-api { display: grid; grid-template-columns: 14rem minmax(0, 1fr); column-gap: 2.5rem; }
47
+ .mt-dx-api > * { grid-column: 2; }
48
+ .mt-dx-api > .mt-dx-side { grid-column: 1; grid-row: 1 / span 999; align-self: start; position: sticky; top: 4.5rem; max-height: calc(100vh - 6rem); overflow-y: auto; padding-inline-end: .5rem; border-inline-end: 1px solid mt(border); }
49
+ .mt-dx-api > .mt-dx-side ul { margin-bottom: 0; }
50
+ }
51
+ .mt-dx-pkgs { display: table; width: 100%; margin-bottom: 2rem; }
52
+ .mt-dx-pkgs caption { padding: .75rem .9rem 0; font-weight: 600; text-align: start; }
53
+ .mt-dx-pkgs thead th { color: mt(muted-foreground); }
54
+ .mt-dx-pkgs tbody th { white-space: normal; background: none; font-size: inherit; font-weight: 400; }
55
+ .mt-dx-pkgs tr:last-child > th { border-bottom: 0; }
56
+ .mt-dx-pkgs tbody th > code { font-weight: 600; }
57
+ .mt-dx-pkgs tbody th > span { display: block; margin-top: .25rem; color: mt(muted-foreground); }
58
+ .mt-dx-pkgs ul { display: flex; flex-wrap: wrap; gap: .25rem .75rem; margin: 0; padding: 0; list-style: none; }
59
+ .mt-dx-pkgs li { margin: 0; }
60
+ @media (max-width: 39.99rem) {
61
+ .mt-dx-pkgs, .mt-dx-pkgs caption, .mt-dx-pkgs tbody, .mt-dx-pkgs tr, .mt-dx-pkgs th, .mt-dx-pkgs td { display: block; }
62
+ .mt-dx-pkgs thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
63
+ .mt-dx-pkgs tr { padding: .5rem .9rem; border-bottom: 1px solid mt(border); }
64
+ .mt-dx-pkgs tr:last-child { border-bottom: 0; }
65
+ .mt-dx-pkgs tbody th, .mt-dx-pkgs td { padding: .25rem 0; border: 0; }
66
+ .mt-dx-pkgs td:empty { display: none; }
67
+ .mt-dx-pkgs td::before { content: attr(data-label) ": "; color: mt(muted-foreground); font-size: .8125rem; }
68
+ }
69
+ @media print { .mt-dx-side { display: none; } .mt-dx-api { display: block; } }
70
+ }
@@ -8,6 +8,8 @@
8
8
  .mt-header-inner, .mt-main, .mt-footer-inner { width: 100%; max-width: mt(container); margin: 0 auto;
9
9
  padding-left: calc(var(--mt-gutter) + var(--mt-safe-left)); padding-right: calc(var(--mt-gutter) + var(--mt-safe-right)); }
10
10
  .mt-header-inner { display: flex; align-items: center; gap: .5rem 1.25rem; min-height: mt(header-height); }
11
+ // The first trailing control (search, language menu or theme toggle) pushes the group to the inline end, with or without search.
12
+ .mt-header-inner > :is(.mt-search, details.mt-lang, .mt-theme-toggle):not(:is(.mt-search, details.mt-lang, .mt-theme-toggle) ~ *) { margin-inline-start: auto; }
11
13
  .mt-site-title { flex: none; display: inline-flex; align-items: center; gap: .55rem; font-weight: 700; letter-spacing: -.01em;
12
14
  text-decoration: none; color: mt(foreground); white-space: nowrap; }
13
15
  .mt-site-title:not(.mt-has-logo)::before { content: ""; width: 1.4rem; height: 1.4rem; border-radius: .4rem; flex: none;
@@ -30,6 +30,8 @@ module Modootoday
30
30
 
31
31
  def links(ctx, r, code)
32
32
  each_line(code, /(?<!!)\[([^\]]*)\]\([^)]*\)/) do |n, m|
33
+ # Inline code arrives as a `` placeholder: [`file.tsx`](…) has a name (the code text), so it is not empty.
34
+ next if m[1].include?("``")
33
35
  t = m[1].gsub(/[*_`]/, "").strip
34
36
  next ctx.errs << "#{r}:#{n}: empty link text [](…) (announced as just \"link\"); write what it opens" if t.empty?
35
37
  ctx.warns << "#{r}:#{n}: vague link text \"#{t}\"; name the destination so it makes sense out of context" if t.match?(VAGUE)
@@ -17,7 +17,16 @@ module Modootoday
17
17
  send(fm["layout"], errs, w, fm)
18
18
  end
19
19
 
20
- def reference(errs, w, fm) = Shape.list(errs, w, "members", fm["members"], any: %w[name], optional: false)
20
+ # members is required unless the page lists packages; sidebar: is true or false; packages need a name, links a label and url.
21
+ def reference(errs, w, fm)
22
+ Shape.list(errs, w, "members", fm["members"], any: %w[name], optional: fm.key?("packages"))
23
+ errs << "#{w}: sidebar must be true or false" unless [nil, true, false].include?(fm["sidebar"])
24
+ Shape.list(errs, w, "packages", fm["packages"], any: %w[name]) do |p, i|
25
+ Shape.list(errs, w, "packages[#{i}].links", p["links"], any: %w[label]) do |l, j|
26
+ errs << "#{w}: packages[#{i}].links[#{j}].url is required" unless Shape.url?(l["url"])
27
+ end
28
+ end
29
+ end
21
30
 
22
31
  def changelog(errs, w, fm)
23
32
  Shape.list(errs, w, "releases", fm["releases"], any: %w[version], optional: false) do |r, i|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-theme-modootoday
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - modootoday
@@ -30,8 +30,10 @@ dependencies:
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '5.0'
33
- description: GitHub alerts, status badges, sectioned pages, install tabs and agent-readable
34
- Markdown twins for Jekyll and GitHub Pages, plus a checker (modootoday-check).
33
+ description: GitHub alerts, status badges, sectioned pages, install tabs, about 40
34
+ page layouts (blog, news, directory, marketing, documents), labels in 23 languages
35
+ with RTL, and agent-readable Markdown twins for Jekyll and GitHub Pages, plus a
36
+ checker (modootoday-check).
35
37
  email:
36
38
  executables:
37
39
  - modootoday-check
@@ -77,6 +79,7 @@ files:
77
79
  - _includes/modootoday/doc/twin.html
78
80
  - _includes/modootoday/docs-extra/head.html
79
81
  - _includes/modootoday/docs-extra/jsonld.html
82
+ - _includes/modootoday/docs-extra/packages.html
80
83
  - _includes/modootoday/head-meta.html
81
84
  - _includes/modootoday/home-url.html
82
85
  - _includes/modootoday/i18n.html