slipway-theme 0.1.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.
Files changed (96) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/_includes/analytics.html +12 -0
  4. data/_includes/author-card.html +29 -0
  5. data/_includes/author-ids.html +2 -0
  6. data/_includes/author-url.html +11 -0
  7. data/_includes/breadcrumbs.html +67 -0
  8. data/_includes/byline.html +14 -0
  9. data/_includes/compat.html +11 -0
  10. data/_includes/component-css.html +5 -0
  11. data/_includes/copy-page.html +5 -0
  12. data/_includes/date.html +90 -0
  13. data/_includes/dir.html +4 -0
  14. data/_includes/edit-sources.html +25 -0
  15. data/_includes/feedback.html +12 -0
  16. data/_includes/footer-custom.html +5 -0
  17. data/_includes/footer.html +16 -0
  18. data/_includes/head-custom.html +5 -0
  19. data/_includes/head.html +52 -0
  20. data/_includes/header.html +38 -0
  21. data/_includes/i18n/ar.html +43 -0
  22. data/_includes/i18n/de.html +43 -0
  23. data/_includes/i18n/en.html +43 -0
  24. data/_includes/i18n/es.html +43 -0
  25. data/_includes/i18n/fa.html +43 -0
  26. data/_includes/i18n/fr.html +43 -0
  27. data/_includes/i18n/he.html +42 -0
  28. data/_includes/i18n/it.html +43 -0
  29. data/_includes/i18n/ja.html +43 -0
  30. data/_includes/i18n/nl.html +43 -0
  31. data/_includes/i18n/pt.html +43 -0
  32. data/_includes/i18n/ru.html +43 -0
  33. data/_includes/i18n/tr.html +43 -0
  34. data/_includes/i18n/zh.html +43 -0
  35. data/_includes/i18n-builtin.html +8 -0
  36. data/_includes/icons/github.svg +1 -0
  37. data/_includes/icons/linkedin.svg +1 -0
  38. data/_includes/icons/mastodon.svg +1 -0
  39. data/_includes/icons/twitter.svg +1 -0
  40. data/_includes/icons/x.svg +1 -0
  41. data/_includes/icons/youtube.svg +1 -0
  42. data/_includes/jsonld.html +41 -0
  43. data/_includes/lang-switcher.html +15 -0
  44. data/_includes/layout-url.html +8 -0
  45. data/_includes/llms-item.html +19 -0
  46. data/_includes/num.html +3 -0
  47. data/_includes/post-item.html +4 -0
  48. data/_includes/related-posts.html +37 -0
  49. data/_includes/search.html +13 -0
  50. data/_includes/seo.html +42 -0
  51. data/_includes/series.html +47 -0
  52. data/_includes/skip-link.html +1 -0
  53. data/_includes/t.html +4 -0
  54. data/_includes/taxonomy.html +22 -0
  55. data/_includes/term.html +7 -0
  56. data/_includes/theme-init.html +1 -0
  57. data/_includes/theme-var.html +4 -0
  58. data/_includes/theme-vars.html +17 -0
  59. data/_layouts/archive.html +32 -0
  60. data/_layouts/author.html +31 -0
  61. data/_layouts/base.html +19 -0
  62. data/_layouts/default.html +4 -0
  63. data/_layouts/doc.html +89 -0
  64. data/_layouts/feed.html +37 -0
  65. data/_layouts/glossary.html +23 -0
  66. data/_layouts/home.html +96 -0
  67. data/_layouts/llms-full.html +54 -0
  68. data/_layouts/llms.html +32 -0
  69. data/_layouts/not-found.html +27 -0
  70. data/_layouts/page.html +13 -0
  71. data/_layouts/post.html +72 -0
  72. data/_layouts/search-index.html +12 -0
  73. data/_layouts/sitemap.html +24 -0
  74. data/_layouts/sourcemap.html +28 -0
  75. data/_layouts/tags.html +24 -0
  76. data/_layouts/translation-status.html +44 -0
  77. data/assets/css/components/glossary.css +21 -0
  78. data/assets/css/fonts.css +47 -0
  79. data/assets/css/nav.css +104 -0
  80. data/assets/css/print.css +70 -0
  81. data/assets/css/slipway.css +952 -0
  82. data/assets/css/tokens.css +57 -0
  83. data/assets/fonts/LICENSES/InstrumentSerif-OFL.txt +93 -0
  84. data/assets/fonts/LICENSES/SourceSerif4-OFL.txt +93 -0
  85. data/assets/fonts/LICENSES/Vazirmatn-OFL.txt +93 -0
  86. data/assets/fonts/instrument-serif-latin-400-italic.woff2 +0 -0
  87. data/assets/fonts/instrument-serif-latin-400-normal.woff2 +0 -0
  88. data/assets/fonts/source-serif-4-latin-wght-italic.woff2 +0 -0
  89. data/assets/fonts/source-serif-4-latin-wght-normal.woff2 +0 -0
  90. data/assets/fonts/vazirmatn-arabic-wght-normal.woff2 +0 -0
  91. data/assets/images/social.png +0 -0
  92. data/assets/js/copy-code.js +53 -0
  93. data/assets/js/edit-prompt.js +23 -0
  94. data/assets/js/search.js +114 -0
  95. data/assets/js/theme-toggle.js +66 -0
  96. metadata +156 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8d0d2d52540ddd0bc4f734b24076c53ad9e68005db52c4842fd48c085cf598a9
4
+ data.tar.gz: 5bbd56dcba755da1884d0342f7b0362679e42f14fd2fa21eddd0bdad8258f4e8
5
+ SHA512:
6
+ metadata.gz: ad5b45c3c0328902ddbc3f525474efbbcea4005ea4cc38d67a653fe6bdf96a7c8224a6553cd5d452240cf27b6574449ac80c3266338e44ad5d060422e070977b
7
+ data.tar.gz: cd0beb748c32d545fafb6d463491d55080b45d5c28def720b80e3947c32640ac3ee3db4339f98be07cf3b2d5f8fd39b570ea3b66a95947261684bc8f6d7b3c7e
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Armin Azimi
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.
@@ -0,0 +1,12 @@
1
+ {%- assign sl_analytics = site.slipway.analytics -%}
2
+ {%- if sl_analytics -%}
3
+ {%- if sl_analytics.plausible -%}
4
+ <script defer data-domain="{{ sl_analytics.plausible }}" src="https://plausible.io/js/script.js"></script>
5
+ {%- endif -%}
6
+ {%- if sl_analytics.goatcounter -%}
7
+ <script data-goatcounter="{{ sl_analytics.goatcounter }}" async src="//gc.zgo.at/count.js"></script>
8
+ {%- endif -%}
9
+ {%- if sl_analytics.umami -%}
10
+ <script defer src="{{ sl_analytics.umami.url | default: 'https://analytics.umami.is/script.js' }}" data-website-id="{{ sl_analytics.umami.website_id }}"></script>
11
+ {%- endif -%}
12
+ {%- endif -%}
@@ -0,0 +1,29 @@
1
+ {%- comment -%} Avatar, name, bio, and links of include.id from _data/authors.yml. include.link links the name to the author page. Prints nothing for an unknown id. {%- endcomment -%}
2
+ {%- assign sl_ac = site.data.authors[include.id] -%}
3
+ {%- if sl_ac -%}
4
+ {%- assign sl_ac_name = sl_ac.name | default: include.id -%}
5
+ <div class="sl-author">
6
+ {%- if sl_ac.avatar %}
7
+ {%- assign sl_ac_src = sl_ac.avatar -%}
8
+ {%- unless sl_ac_src contains '://' %}{% assign sl_ac_src = sl_ac_src | relative_url %}{% endunless %}
9
+ <img class="sl-avatar" src="{{ sl_ac_src }}" alt="" width="64" height="64" loading="lazy">
10
+ {%- endif %}
11
+ <div>
12
+ {%- assign sl_ac_url = '' -%}
13
+ {%- if include.link %}{% capture sl_ac_url %}{% include author-url.html id=include.id %}{% endcapture %}{% assign sl_ac_url = sl_ac_url | strip %}{% endif %}
14
+ <p class="sl-author-name">{% if sl_ac_url != '' %}<a rel="author" href="{{ sl_ac_url }}">{{ sl_ac_name | escape }}</a>{% else %}{{ sl_ac_name | escape }}{% endif %}</p>
15
+ {%- if sl_ac.bio %}
16
+ <p class="sl-author-bio">{{ sl_ac.bio | escape }}</p>
17
+ {%- endif %}
18
+ {%- if sl_ac.links and sl_ac.links.size > 0 %}
19
+ <ul class="sl-author-links">
20
+ {%- for link in sl_ac.links %}
21
+ {%- assign sl_ac_href = link.url -%}
22
+ {%- unless sl_ac_href contains '://' %}{% assign sl_ac_href = sl_ac_href | relative_url %}{% endunless %}
23
+ <li><a href="{{ sl_ac_href | escape }}">{{ link.title | escape }}</a></li>
24
+ {%- endfor %}
25
+ </ul>
26
+ {%- endif %}
27
+ </div>
28
+ </div>
29
+ {%- endif -%}
@@ -0,0 +1,2 @@
1
+ {%- comment -%} Sets sl_ai_ids to the author ids of include.page: `author` is one id or a list of ids, keys of _data/authors.yml. {%- endcomment -%}
2
+ {%- assign sl_ai_ids = include.page.author | join: ',' | split: ',' -%}
@@ -0,0 +1,11 @@
1
+ {%- comment -%} Prints the url of the author page (layout author) for include.id, in the current language when there is one, or nothing. {%- endcomment -%}
2
+ {%- assign sl_au_lang = page.lang | default: site.lang | default: 'en' -%}
3
+ {%- assign sl_au_url = '' -%}
4
+ {%- for p in site.pages -%}
5
+ {%- if p.layout == 'author' and p.author == include.id -%}
6
+ {%- assign sl_au_page_lang = p.lang | default: site.lang | default: 'en' -%}
7
+ {%- if sl_au_page_lang == sl_au_lang -%}{%- assign sl_au_url = p.url | relative_url -%}{%- break -%}{%- endif -%}
8
+ {%- if sl_au_url == '' -%}{%- assign sl_au_url = p.url | relative_url -%}{%- endif -%}
9
+ {%- endif -%}
10
+ {%- endfor -%}
11
+ {{ sl_au_url }}
@@ -0,0 +1,67 @@
1
+ {%- assign sl_bc_parts = page.url | split: '/' -%}
2
+ {%- assign sl_bc_url = '' -%}
3
+ {%- assign sl_bc_items = '' -%}
4
+ {%- assign sl_bc_count = 0 -%}
5
+ {%- assign sl_all = site.pages | concat: site.documents -%}
6
+
7
+ {%- for part in sl_bc_parts -%}
8
+ {%- if part != '' and forloop.last == false -%}
9
+ {%- assign sl_bc_url = sl_bc_url | append: '/' | append: part -%}
10
+ {%- assign sl_bc_full = sl_bc_url | append: '/' -%}
11
+ {%- assign sl_bc_page = sl_all | where: 'url', sl_bc_full | first -%}
12
+ {%- unless sl_bc_page -%}
13
+ {%- assign sl_bc_page = sl_all | where: 'url', sl_bc_url | first -%}
14
+ {%- endunless -%}
15
+ {%- if sl_bc_page -%}
16
+ {%- capture sl_bc_item -%}
17
+ <li>
18
+ <a href="{{ sl_bc_page.url | relative_url }}">{{ sl_bc_page.title }}</a>
19
+ <span class="sl-breadcrumb-separator" aria-hidden="true">/</span>
20
+ </li>
21
+ {%- endcapture -%}
22
+ {%- assign sl_bc_items = sl_bc_items | append: sl_bc_item -%}
23
+ {%- assign sl_bc_count = sl_bc_count | plus: 1 -%}
24
+ {%- endif -%}
25
+ {%- endif -%}
26
+ {%- endfor -%}
27
+
28
+ {%- if sl_bc_count > 0 -%}
29
+ {%- capture sl_bc_label %}{% include t.html key='breadcrumbs' %}{% endcapture -%}
30
+ {%- capture sl_home_label %}{% include t.html key='home' %}{% endcapture -%}
31
+ <nav class="sl-breadcrumbs" aria-label="{{ sl_bc_label | strip | escape }}">
32
+ <ol>
33
+ <li>
34
+ <a href="{{ '/' | relative_url }}">{{ sl_home_label | strip }}</a>
35
+ <span class="sl-breadcrumb-separator" aria-hidden="true">/</span>
36
+ </li>
37
+ {{ sl_bc_items }}
38
+ <li aria-current="page">{{ page.title }}</li>
39
+ </ol>
40
+ </nav>
41
+
42
+ {%- assign sl_bc_url = '' -%}
43
+ {%- assign sl_bc_pos = 1 -%}
44
+ {%- capture sl_bc_json -%}
45
+ {"@type":"ListItem","position":{{ sl_bc_pos }},"name":{{ sl_home_label | strip | jsonify }},"item":{{ '/' | absolute_url | jsonify }}}
46
+ {%- endcapture -%}
47
+ {%- assign sl_bc_pos = sl_bc_pos | plus: 1 -%}
48
+
49
+ {%- for part in sl_bc_parts -%}
50
+ {%- if part != '' and forloop.last == false -%}
51
+ {%- assign sl_bc_url = sl_bc_url | append: '/' | append: part -%}
52
+ {%- assign sl_bc_full = sl_bc_url | append: '/' -%}
53
+ {%- assign sl_bc_page = sl_all | where: 'url', sl_bc_full | first -%}
54
+ {%- unless sl_bc_page -%}
55
+ {%- assign sl_bc_page = sl_all | where: 'url', sl_bc_url | first -%}
56
+ {%- endunless -%}
57
+ {%- if sl_bc_page -%}
58
+ {%- capture sl_bc_json -%}{{ sl_bc_json }},{"@type":"ListItem","position":{{ sl_bc_pos }},"name":{{ sl_bc_page.title | jsonify }},"item":{{ sl_bc_page.url | absolute_url | jsonify }}}{%- endcapture -%}
59
+ {%- assign sl_bc_pos = sl_bc_pos | plus: 1 -%}
60
+ {%- endif -%}
61
+ {%- endif -%}
62
+ {%- endfor -%}
63
+
64
+ {%- capture sl_bc_json -%}{{ sl_bc_json }},{"@type":"ListItem","position":{{ sl_bc_pos }},"name":{{ page.title | jsonify }}}{%- endcapture -%}
65
+ {%- capture sl_bc_list -%}{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{{ sl_bc_json }}]}{%- endcapture %}
66
+ <script type="application/ld+json">{{ sl_bc_list | strip_newlines | replace: '<', '\u003c' }}</script>
67
+ {%- endif -%}
@@ -0,0 +1,14 @@
1
+ {%- comment -%} "By A, B and C" for include.page, each name linked to its author page when there is one. Unknown ids print as they are. {%- endcomment -%}
2
+ {%- include author-ids.html page=include.page -%}
3
+ {%- if sl_ai_ids.size > 0 -%}
4
+ {%- assign sl_bl_ids = sl_ai_ids -%}
5
+ <span class="sl-byline">{% include t.html key='by' %}
6
+ {%- for id in sl_bl_ids %}
7
+ {%- assign sl_bl_author = site.data.authors[id] -%}
8
+ {%- assign sl_bl_name = sl_bl_author.name | default: id -%}
9
+ {%- capture sl_bl_url %}{% include author-url.html id=id %}{% endcapture %}{% assign sl_bl_url = sl_bl_url | strip -%}
10
+ {%- unless forloop.first %}{% if forloop.last %} {% include t.html key='and' %}{% else %}{% include t.html key='comma' %}{% endif %}{% endunless %}
11
+ {% if sl_bl_url != '' %}<a rel="author" href="{{ sl_bl_url }}">{{ sl_bl_name | escape }}</a>{% else %}<span>{{ sl_bl_name | escape }}</span>{% endif %}
12
+ {%- endfor -%}
13
+ </span>
14
+ {%- endif -%}
@@ -0,0 +1,11 @@
1
+ {%- comment -%}
2
+ Reads a renamed config key or front-matter field (ADR 0012, rule 4): the new name wins when it is
3
+ set, else the deprecated old one. The result is in sl_compat. Call it with the include tag,
4
+ new= the new name and old= the old one (each under site or page), then print sl_compat.
5
+ Every entry in schema/deprecations.json has one such call; tools/theme/deprecations.test.mjs checks it.
6
+ {%- endcomment -%}
7
+ {%- if include.new == nil -%}
8
+ {%- assign sl_compat = include.old -%}
9
+ {%- else -%}
10
+ {%- assign sl_compat = include.new -%}
11
+ {%- endif -%}
@@ -0,0 +1,5 @@
1
+ {%- assign _sl_css_check = "," | append: include.name | append: "," -%}
2
+ {%- unless slipway_components_css contains _sl_css_check -%}
3
+ {%- assign slipway_components_css = slipway_components_css | default: "," | append: include.name | append: "," -%}
4
+ <link rel="stylesheet" href="{{ '/assets/css/components/' | append: include.name | append: '.css' | relative_url }}">
5
+ {%- endunless -%}
@@ -0,0 +1,5 @@
1
+ {%- assign sl_twin = page.slipway_twin %}
2
+ {%- unless sl_twin %}{% assign sl_twin = site.pages | where: 'twin_of', page.path | map: 'url' | first %}{% endunless %}
3
+ {%- if sl_twin %}
4
+ <button type="button" class="sl-copy-page" data-copy-page="{{ sl_twin | relative_url }}" hidden>{% include t.html key='copy_page_md' %}</button>
5
+ {%- endif %}
@@ -0,0 +1,90 @@
1
+ {%- comment -%}
2
+ Prints include.date as YYYY-MM-DD, or as "D Month YYYY" in the Jalali calendar when the page is Persian and
3
+ slipway.persian.jalali is on. Prints in the Hijri calendar when the page is Arabic and slipway.arabic.hijri is on.
4
+ Integer arithmetic of the 33-year cycle (Borkowski) for Jalali; 30-year tabular (civil epoch) for Hijri.
5
+ (Tabular Islamic calendar has a known offset of up to 1-2 days from Umm al-Qura).
6
+ Digits follow slipway.persian.digits or slipway.arabic.digits.
7
+ {%- endcomment -%}
8
+ {%- assign sl_d_lang = page.lang | default: site.lang | default: 'en' | split: '-' | first -%}
9
+ {%- capture sl_d_text -%}
10
+ {%- assign gy = include.date | date: '%Y' | plus: 0 -%}
11
+ {%- if sl_d_lang == 'fa' and site.slipway.persian.jalali and gy > 0 -%}
12
+ {%- assign gm = include.date | date: '%-m' | plus: 0 -%}
13
+ {%- assign gd = include.date | date: '%-d' | plus: 0 -%}
14
+ {%- assign offsets = '0,31,59,90,120,151,181,212,243,273,304,334' | split: ',' -%}
15
+ {%- assign idx = gm | minus: 1 -%}
16
+ {%- assign off = offsets[idx] | plus: 0 -%}
17
+ {%- assign gy2 = gy -%}
18
+ {%- if gm > 2 -%}{%- assign gy2 = gy | plus: 1 -%}{%- endif -%}
19
+ {%- assign a = gy2 | plus: 3 | divided_by: 4 -%}
20
+ {%- assign b = gy2 | plus: 99 | divided_by: 100 -%}
21
+ {%- assign c = gy2 | plus: 399 | divided_by: 400 -%}
22
+ {%- assign days = gy | times: 365 | plus: 355666 | plus: a | minus: b | plus: c | plus: gd | plus: off -%}
23
+ {%- assign jy = days | divided_by: 12053 | times: 33 | minus: 1595 -%}
24
+ {%- assign days = days | modulo: 12053 -%}
25
+ {%- assign jy = days | divided_by: 1461 | times: 4 | plus: jy -%}
26
+ {%- assign days = days | modulo: 1461 -%}
27
+ {%- if days > 365 -%}
28
+ {%- assign dm1 = days | minus: 1 -%}
29
+ {%- assign jy = dm1 | divided_by: 365 | plus: jy -%}
30
+ {%- assign days = dm1 | modulo: 365 -%}
31
+ {%- endif -%}
32
+ {%- if days < 186 -%}
33
+ {%- assign jm = days | divided_by: 31 | plus: 1 -%}
34
+ {%- assign jd = days | modulo: 31 | plus: 1 -%}
35
+ {%- else -%}
36
+ {%- assign r = days | minus: 186 -%}
37
+ {%- assign jm = r | divided_by: 30 | plus: 7 -%}
38
+ {%- assign jd = r | modulo: 30 | plus: 1 -%}
39
+ {%- endif -%}
40
+ {%- assign months = 'فروردین,اردیبهشت,خرداد,تیر,مرداد,شهریور,مهر,آبان,آذر,دی,بهمن,اسفند' | split: ',' -%}
41
+ {%- assign mi = jm | minus: 1 -%}
42
+ {{- jd }} {{ months[mi] }} {{ jy -}}
43
+ {%- elsif sl_d_lang == 'ar' and site.slipway.arabic.hijri and gy > 0 -%}
44
+ {%- assign gm = include.date | date: '%-m' | plus: 0 -%}
45
+ {%- assign gd = include.date | date: '%-d' | plus: 0 -%}
46
+ {%- assign a = 14 | minus: gm | divided_by: 12 -%}
47
+ {%- assign y_p = gy | plus: 4800 | minus: a -%}
48
+ {%- assign m_p = a | times: 12 | plus: gm | minus: 3 -%}
49
+ {%- assign jd = m_p | times: 153 | plus: 2 | divided_by: 5 | plus: gd -%}
50
+ {%- assign y_p365 = y_p | times: 365 -%}
51
+ {%- assign y_p4 = y_p | divided_by: 4 -%}
52
+ {%- assign y_p100 = y_p | divided_by: 100 -%}
53
+ {%- assign y_p400 = y_p | divided_by: 400 -%}
54
+ {%- assign jd = jd | plus: y_p365 | plus: y_p4 | minus: y_p100 | plus: y_p400 | minus: 32045 -%}
55
+ {%- assign days = jd | minus: 1948440 -%}
56
+ {%- if days < 0 -%}
57
+ {{- include.date | date: '%Y-%m-%d' -}}
58
+ {%- assign hy = gy -%}
59
+ {%- else -%}
60
+ {%- assign cycle = days | divided_by: 10631 -%}
61
+ {%- assign rem = days | modulo: 10631 -%}
62
+ {%- assign h_year = rem | times: 30 | plus: 10646 | divided_by: 10631 -%}
63
+ {%- assign h_year_m1 = h_year | minus: 1 -%}
64
+ {%- assign days_before = h_year_m1 | times: 354 -%}
65
+ {%- assign leap_days = h_year | times: 11 | plus: 3 | divided_by: 30 -%}
66
+ {%- assign days_before = days_before | plus: leap_days -%}
67
+ {%- assign rem_days = rem | minus: days_before -%}
68
+ {%- assign hm = rem_days | times: 11 | plus: 330 | divided_by: 325 -%}
69
+ {%- assign hm_m1 = hm | minus: 1 -%}
70
+ {%- assign days_in_prev = hm_m1 | times: 29 -%}
71
+ {%- assign days_in_prev_leap = hm | divided_by: 2 -%}
72
+ {%- assign days_in_prev = days_in_prev | plus: days_in_prev_leap -%}
73
+ {%- assign hd = rem_days | minus: days_in_prev | plus: 1 -%}
74
+ {%- assign hy = cycle | times: 30 | plus: h_year -%}
75
+ {%- assign months = 'محرم,صفر,ربيع الأول,ربيع الثاني,جمادى الأولى,جمادى الآخرة,رجب,شعبان,رمضان,شوال,ذو القعدة,ذو الحجة' | split: ',' -%}
76
+ {%- assign mi = hm | minus: 1 -%}
77
+ {{- hd }} {{ months[mi] }} {{ hy -}}
78
+ {%- endif -%}
79
+ {%- else -%}
80
+ {{- include.date | date: '%Y-%m-%d' -}}
81
+ {%- endif -%}
82
+ {%- endcapture -%}
83
+ {%- if sl_d_lang == 'fa' and site.slipway.persian.jalali and gy > 0 -%}
84
+ {%- assign sl_d_year = jy -%}
85
+ {%- elsif sl_d_lang == 'ar' and site.slipway.arabic.hijri and gy > 0 and hy -%}
86
+ {%- assign sl_d_year = hy -%}
87
+ {%- else -%}
88
+ {%- assign sl_d_year = include.date | date: '%Y' -%}
89
+ {%- endif -%}
90
+ {%- include num.html value=sl_d_text -%}
@@ -0,0 +1,4 @@
1
+ {%- comment -%} Prints rtl or ltr for include.lang. {%- endcomment -%}
2
+ {%- assign sl_dir_rtl = 'ar,arc,ckb,dv,fa,he,ks,ku,ps,sd,syr,ug,ur,yi' | split: ',' -%}
3
+ {%- assign sl_dir_base = include.lang | split: '-' | first -%}
4
+ {%- if sl_dir_rtl contains sl_dir_base -%}rtl{%- else -%}ltr{%- endif -%}
@@ -0,0 +1,25 @@
1
+ {%- comment -%}
2
+ include.html with a data-source attribute on every h2 and h3, for "Edit with your agent"
3
+ (assets/js/edit-prompt.js): "path:line" when the Actions plugin set page.slipway_sections from the
4
+ source map, the page's file alone otherwise (classic mode cannot know lines, ADR 0007).
5
+ {%- endcomment -%}
6
+ {%- assign sl_src_path = page.path | escape -%}
7
+ {%- assign sl_src_parts = include.html | split: '<h' -%}
8
+ {%- for part in sl_src_parts -%}
9
+ {%- if forloop.first %}{{ part }}{% continue %}{% endif -%}
10
+ {%- assign sl_src_level = part | slice: 0, 1 -%}
11
+ {%- assign sl_src_next = part | slice: 1, 1 -%}
12
+ {%- if sl_src_level == '2' or sl_src_level == '3' -%}
13
+ {%- if sl_src_next == ' ' or sl_src_next == '>' -%}
14
+ {%- assign sl_src = sl_src_path -%}
15
+ {%- assign sl_src_tag = part | split: '>' | first -%}
16
+ {%- if sl_src_tag contains 'id="' -%}
17
+ {%- assign sl_src_id = sl_src_tag | split: 'id="' | last | split: '"' | first -%}
18
+ {%- for section in page.slipway_sections -%}
19
+ {%- if section.id == sl_src_id %}{% assign sl_src = sl_src_path | append: ':' | append: section.line %}{% break %}{% endif -%}
20
+ {%- endfor -%}
21
+ {%- endif -%}
22
+ <h{{ sl_src_level }} data-source="{{ sl_src }}"{{ part | slice: 1, part.size }}
23
+ {%- else -%}<h{{ part }}{%- endif -%}
24
+ {%- else -%}<h{{ part }}{%- endif -%}
25
+ {%- endfor -%}
@@ -0,0 +1,12 @@
1
+ {%- assign sl_repo_url = site.github.repository_url -%}
2
+ {%- if sl_repo_url == nil -%}
3
+ {%- assign sl_repo_url = site.repository_url -%}
4
+ {%- endif -%}
5
+ {%- if sl_repo_url -%}
6
+ <div class="sl-feedback">
7
+ <p>Was this helpful?
8
+ <a href="{{ sl_repo_url }}/issues/new?assignees=&amp;labels=feedback&amp;projects=&amp;template=feedback.yml&amp;title=Feedback+on+{{ page.url | url_encode }}" target="_blank" rel="noopener noreferrer" class="sl-feedback-link">Yes</a> /
9
+ <a href="{{ sl_repo_url }}/issues/new?assignees=&amp;labels=feedback&amp;projects=&amp;template=feedback.yml&amp;title=Feedback+on+{{ page.url | url_encode }}" target="_blank" rel="noopener noreferrer" class="sl-feedback-link">No</a>
10
+ </p>
11
+ </div>
12
+ {%- endif -%}
@@ -0,0 +1,5 @@
1
+ {%- comment -%}
2
+ Override slot: rendered inside <footer> on every page, after the site title. Empty in the theme.
3
+ To fill it, create _includes/footer-custom.html in your site; your file replaces this one.
4
+ See docs/overrides.md.
5
+ {%- endcomment -%}
@@ -0,0 +1,16 @@
1
+ <footer class="sl-footer">
2
+ <p>{{ site.title }}</p>
3
+ {% if site.data.social %}
4
+ <ul class="sl-social-links">
5
+ {% for link in site.data.social %}
6
+ <li>
7
+ <a href="{{ link.url }}" rel="me" aria-label="{{ link.network }}">
8
+ {% assign icon_file = "icons/" | append: link.network | append: ".svg" %}
9
+ {% include {{ icon_file }} %}
10
+ </a>
11
+ </li>
12
+ {% endfor %}
13
+ </ul>
14
+ {% endif %}
15
+ {% include footer-custom.html %}
16
+ </footer>
@@ -0,0 +1,5 @@
1
+ {%- comment -%}
2
+ Override slot: rendered at the end of <head> on every page. Empty in the theme.
3
+ To fill it, create _includes/head-custom.html in your site; your file replaces this one.
4
+ See docs/overrides.md.
5
+ {%- endcomment -%}
@@ -0,0 +1,52 @@
1
+ <head>
2
+ <meta charset="utf-8">
3
+ <meta name="viewport" content="width=device-width, initial-scale=1">
4
+ {% include theme-init.html %}
5
+ <title>{{ page.title | default: site.title }}</title>
6
+ {%- comment %} Without a description, the opening words of the page stand in, so a bare site still has one. {% endcomment %}
7
+ {%- assign sl_desc = page.description %}
8
+ {%- unless sl_desc %}{% assign sl_desc = content | strip_html | normalize_whitespace | strip | truncate: 160 %}{% endunless %}
9
+ {%- if sl_desc != '' %}
10
+ <meta name="description" content="{{ sl_desc | escape }}">
11
+ {%- endif %}
12
+ {%- include jsonld.html %}
13
+ {%- include seo.html %}
14
+ {%- if site.slipway.fonts != "system" %}
15
+ <link rel="preload" href="{{ '/assets/fonts/source-serif-4-latin-wght-normal.woff2' | relative_url }}" as="font" type="font/woff2" crossorigin>
16
+ {%- endif %}
17
+ {%- capture sl_feed_url %}{% include layout-url.html layout='feed' %}{% endcapture %}
18
+ {%- assign sl_feed_url = sl_feed_url | strip %}
19
+ {%- if sl_feed_url != '' %}
20
+ <link rel="alternate" type="application/atom+xml" href="{{ sl_feed_url }}" title="{{ site.title | escape }}">
21
+ {%- endif %}
22
+ {%- if site.slipway.logo.favicon_svg %}
23
+ <link rel="icon" href="{{ site.slipway.logo.favicon_svg | relative_url }}" type="image/svg+xml">
24
+ {%- endif %}
25
+ {%- if site.slipway.logo.touch_icon %}
26
+ <link rel="apple-touch-icon" href="{{ site.slipway.logo.touch_icon | relative_url }}">
27
+ {%- endif %}
28
+ {%- comment %} The Markdown twin (ADR 0006): set by the Actions plugin, or the stub page from `npm run twins` on classic Pages. {% endcomment %}
29
+ {%- assign sl_twin = page.slipway_twin %}
30
+ {%- unless sl_twin %}{% assign sl_twin = site.pages | where: 'twin_of', page.path | map: 'url' | first %}{% endunless %}
31
+ {%- if sl_twin %}
32
+ <link rel="alternate" type="text/markdown" href="{{ sl_twin | relative_url }}">
33
+ {%- endif %}
34
+ {%- if site.slipway.fonts != "system" %}
35
+ <link rel="stylesheet" href="{{ '/assets/css/fonts.css' | relative_url }}">
36
+ {%- endif %}
37
+ <link rel="stylesheet" href="{{ '/assets/css/tokens.css' | relative_url }}">
38
+ <link rel="stylesheet" href="{{ '/assets/css/slipway.css' | relative_url }}">
39
+ <link rel="stylesheet" href="{{ '/assets/css/nav.css' | relative_url }}">
40
+ <link rel="stylesheet" href="{{ '/assets/css/print.css' | relative_url }}" media="print">
41
+ {% include theme-vars.html %}
42
+ {%- assign sl_custom_css = site.static_files | where: 'path', '/assets/css/custom.css' | first %}
43
+ {%- if sl_custom_css %}
44
+ <link rel="stylesheet" href="{{ '/assets/css/custom.css' | relative_url }}">
45
+ {%- endif %}
46
+ <script src="{{ '/assets/js/theme-toggle.js' | relative_url }}" defer></script>
47
+ <script src="{{ '/assets/js/search.js' | relative_url }}" defer></script>
48
+ <script src="{{ '/assets/js/copy-code.js' | relative_url }}" defer></script>
49
+ <script src="{{ '/assets/js/edit-prompt.js' | relative_url }}" defer></script>
50
+ {% include analytics.html %}
51
+ {% include head-custom.html %}
52
+ </head>
@@ -0,0 +1,38 @@
1
+ {%- comment -%} slipway.header picks the variant: classic (title at the start, the rest at the end), centered (stacked and centered), or minimal (title, language switcher, and theme toggle only). {%- endcomment -%}
2
+ {%- assign sl_header = site.slipway.header | default: 'classic' -%}
3
+ <header class="sl-header{% if sl_header == 'centered' or sl_header == 'minimal' %} sl-header-{{ sl_header }}{% endif %}">
4
+ <a class="sl-site-title" href="{{ '/' | relative_url }}">
5
+ {%- if site.slipway.logo.light -%}
6
+ <img src="{{ site.slipway.logo.light | relative_url }}" alt="{{ site.title | escape }}"{% if site.slipway.logo.dark %} class="sl-logo-light"{% endif %}>
7
+ {%- if site.slipway.logo.dark %}
8
+ <img src="{{ site.slipway.logo.dark | relative_url }}" alt="{{ site.title | escape }}" class="sl-logo-dark">
9
+ {%- endif -%}
10
+ {%- else -%}
11
+ {{ site.title }}
12
+ {%- endif -%}
13
+ </a>
14
+ {%- assign sl_nav_lang = page.lang | default: site.lang | default: 'en' | split: '-' | first -%}
15
+ {%- assign sl_nav_key = 'main_' | append: sl_nav_lang -%}
16
+ {%- assign sl_main = site.data.navigation[sl_nav_key] | default: site.data.navigation.main -%}
17
+ {%- if sl_main.size > 0 and sl_header != 'minimal' %}
18
+ <input type="checkbox" id="sl-nav-state" class="sl-nav-state" aria-label="{% include t.html key='main_nav' %}">
19
+ <label for="sl-nav-state" class="sl-nav-toggle">
20
+ <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/></svg>
21
+ </label>
22
+ <label for="sl-nav-state" class="sl-nav-backdrop"></label>
23
+ <div class="sl-nav-drawer">
24
+ <nav class="sl-main-nav" aria-label="{% include t.html key='main_nav' %}">
25
+ <ul>
26
+ {%- for item in sl_main %}
27
+ {%- assign sl_here = false %}
28
+ {%- if page.url == item.url %}{% assign sl_here = true %}{% elsif item.url != '/' and page.url contains item.url %}{% assign sl_here = true %}{% endif %}
29
+ <li><a href="{{ item.url | relative_url }}"{% if sl_here %} aria-current="page"{% endif %}>{{ item.title }}</a></li>
30
+ {%- endfor %}
31
+ </ul>
32
+ </nav>
33
+ </div>
34
+ {%- endif %}
35
+ {% unless sl_header == 'minimal' %}{% include search.html %}{% endunless %}
36
+ {% include lang-switcher.html %}
37
+ <button type="button" class="sl-theme-toggle" data-theme-toggle data-label-auto="{% include t.html key='mode_auto' %}" data-label-light="{% include t.html key='mode_light' %}" data-label-dark="{% include t.html key='mode_dark' %}" hidden>{% include t.html key='theme' %}</button>
38
+ </header>
@@ -0,0 +1,43 @@
1
+ {%- case include.key -%}
2
+ {%- when 'about_author' -%}عن الكاتب
3
+ {%- when 'and' -%}و
4
+ {%- when 'breadcrumbs' -%}مسار التنقل
5
+ {%- when 'by' -%}بقلم
6
+ {%- when 'categories' -%}التصنيفات
7
+ {%- when 'comma' -%}،
8
+ {%- when 'copied' -%}تم النسخ
9
+ {%- when 'copy' -%}نسخ
10
+ {%- when 'copy_failed' -%}اضغط Ctrl+C
11
+ {%- when 'copy_page_md' -%}نسخ الصفحة كماركداون
12
+ {%- when 'docs_nav' -%}التوثيق
13
+ {%- when 'edit_label' -%}التحرير مع وكيلك
14
+ {%- when 'edit_prompt' -%}حرّر الملف {source}. النص الحالي: «{text}». التغيير:
15
+ {%- when 'go_home' -%}الانتقال إلى الصفحة الرئيسية
16
+ {%- when 'home' -%}الرئيسية
17
+ {%- when 'language' -%}اللغة
18
+ {%- when 'latest_posts' -%}أحدث التدوينات
19
+ {%- when 'main_nav' -%}القائمة الرئيسية
20
+ {%- when 'min_read' -%}دقيقة قراءة
21
+ {%- when 'mode_auto' -%}تلقائي
22
+ {%- when 'mode_dark' -%}داكن
23
+ {%- when 'mode_light' -%}فاتح
24
+ {%- when 'next' -%}التالي
25
+ {%- when 'not_found_text' -%}هذا العنوان غير موجود أو نُقل. استخدم حقل البحث أو انتقل إلى الصفحة الرئيسية.
26
+ {%- when 'not_found_title' -%}الصفحة غير موجودة
27
+ {%- when 'on_this_page' -%}في هذه الصفحة
28
+ {%- when 'pager' -%}الصفحة السابقة والتالية
29
+ {%- when 'post_pager' -%}التدوينة السابقة والتالية
30
+ {%- when 'posts' -%}التدوينات
31
+ {%- when 'previous' -%}السابق
32
+ {%- when 'related_posts' -%}تدوينات ذات صلة
33
+ {%- when 'search' -%}بحث
34
+ {%- when 'search_count' -%}{n} نتيجة
35
+ {%- when 'search_none' -%}لا توجد نتائج
36
+ {%- when 'series' -%}سلسلة
37
+ {%- when 'series_pager' -%}الجزء السابق والتالي من السلسلة
38
+ {%- when 'series_part' -%}الجزء {n} من {total}
39
+ {%- when 'skip' -%}انتقال إلى المحتوى
40
+ {%- when 'tags' -%}الوسوم
41
+ {%- when 'theme' -%}المظهر
42
+ {%- when 'translation_key' -%}مفتاح الترجمة
43
+ {%- endcase -%}
@@ -0,0 +1,43 @@
1
+ {%- case include.key -%}
2
+ {%- when 'about_author' -%}Über den Autor
3
+ {%- when 'and' -%}und
4
+ {%- when 'breadcrumbs' -%}Brotkrümelnavigation
5
+ {%- when 'by' -%}Von
6
+ {%- when 'categories' -%}Kategorien
7
+ {%- when 'comma' -%},
8
+ {%- when 'copied' -%}Kopiert
9
+ {%- when 'copy' -%}Kopieren
10
+ {%- when 'copy_failed' -%}Drücken Sie Strg+C
11
+ {%- when 'copy_page_md' -%}Seite als Markdown kopieren
12
+ {%- when 'docs_nav' -%}Dokumentation
13
+ {%- when 'edit_label' -%}Mit Ihrem Agenten bearbeiten
14
+ {%- when 'edit_prompt' -%}{source} bearbeiten. Aktueller Text: "{text}". Änderung:
15
+ {%- when 'go_home' -%}Zur Startseite gehen
16
+ {%- when 'home' -%}Startseite
17
+ {%- when 'language' -%}Sprache
18
+ {%- when 'latest_posts' -%}Neueste Beiträge
19
+ {%- when 'main_nav' -%}Hauptmenü
20
+ {%- when 'min_read' -%}Min. Lesezeit
21
+ {%- when 'mode_auto' -%}Auto
22
+ {%- when 'mode_dark' -%}Dunkel
23
+ {%- when 'mode_light' -%}Hell
24
+ {%- when 'next' -%}Weiter
25
+ {%- when 'not_found_text' -%}Diese Adresse existiert nicht oder wurde verschoben. Verwenden Sie das Suchfeld oder gehen Sie zur Startseite.
26
+ {%- when 'not_found_title' -%}Seite nicht gefunden
27
+ {%- when 'on_this_page' -%}Auf dieser Seite
28
+ {%- when 'pager' -%}Zurück und Weiter
29
+ {%- when 'post_pager' -%}Vorheriger und nächster Beitrag
30
+ {%- when 'posts' -%}Beiträge
31
+ {%- when 'previous' -%}Zurück
32
+ {%- when 'related_posts' -%}Ähnliche Beiträge
33
+ {%- when 'search' -%}Suche
34
+ {%- when 'search_count' -%}{n} Ergebnisse
35
+ {%- when 'search_none' -%}Keine Ergebnisse
36
+ {%- when 'series' -%}Serie
37
+ {%- when 'series_pager' -%}Zurück und Weiter in dieser Serie
38
+ {%- when 'series_part' -%}Teil {n} von {total}
39
+ {%- when 'skip' -%}Zum Inhalt springen
40
+ {%- when 'tags' -%}Tags
41
+ {%- when 'theme' -%}Design
42
+ {%- when 'translation_key' -%}Übersetzungsschlüssel
43
+ {%- endcase -%}
@@ -0,0 +1,43 @@
1
+ {%- case include.key -%}
2
+ {%- when 'about_author' -%}About the author
3
+ {%- when 'and' -%}and
4
+ {%- when 'breadcrumbs' -%}Breadcrumbs
5
+ {%- when 'by' -%}By
6
+ {%- when 'categories' -%}Categories
7
+ {%- when 'comma' -%},
8
+ {%- when 'copied' -%}Copied
9
+ {%- when 'copy' -%}Copy
10
+ {%- when 'copy_failed' -%}Press Ctrl+C
11
+ {%- when 'copy_page_md' -%}Copy page as Markdown
12
+ {%- when 'docs_nav' -%}Documentation
13
+ {%- when 'edit_label' -%}Edit with your agent
14
+ {%- when 'edit_prompt' -%}Edit {source}. Current text: "{text}". Change:
15
+ {%- when 'go_home' -%}Go to the home page
16
+ {%- when 'home' -%}Home
17
+ {%- when 'language' -%}Language
18
+ {%- when 'latest_posts' -%}Latest posts
19
+ {%- when 'main_nav' -%}Main
20
+ {%- when 'min_read' -%}min read
21
+ {%- when 'mode_auto' -%}Auto
22
+ {%- when 'mode_dark' -%}Dark
23
+ {%- when 'mode_light' -%}Light
24
+ {%- when 'next' -%}Next
25
+ {%- when 'not_found_text' -%}This address does not exist or has moved. Use the search field or go to the home page.
26
+ {%- when 'not_found_title' -%}Page not found
27
+ {%- when 'on_this_page' -%}On this page
28
+ {%- when 'pager' -%}Previous and next
29
+ {%- when 'post_pager' -%}Previous and next post
30
+ {%- when 'posts' -%}Posts
31
+ {%- when 'previous' -%}Previous
32
+ {%- when 'related_posts' -%}Related posts
33
+ {%- when 'search' -%}Search
34
+ {%- when 'search_count' -%}{n} results
35
+ {%- when 'search_none' -%}No results
36
+ {%- when 'series' -%}Series
37
+ {%- when 'series_pager' -%}Previous and next in this series
38
+ {%- when 'series_part' -%}Part {n} of {total}
39
+ {%- when 'skip' -%}Skip to content
40
+ {%- when 'tags' -%}Tags
41
+ {%- when 'theme' -%}Theme
42
+ {%- when 'translation_key' -%}Translation key
43
+ {%- endcase -%}
@@ -0,0 +1,43 @@
1
+ {%- case include.key -%}
2
+ {%- when 'about_author' -%}Sobre el autor
3
+ {%- when 'and' -%}y
4
+ {%- when 'breadcrumbs' -%}Ruta de navegación
5
+ {%- when 'by' -%}Por
6
+ {%- when 'categories' -%}Categorías
7
+ {%- when 'comma' -%},
8
+ {%- when 'copied' -%}Copiado
9
+ {%- when 'copy' -%}Copiar
10
+ {%- when 'copy_failed' -%}Presione Ctrl+C
11
+ {%- when 'copy_page_md' -%}Copiar página como Markdown
12
+ {%- when 'docs_nav' -%}Documentación
13
+ {%- when 'edit_label' -%}Editar con tu agente
14
+ {%- when 'edit_prompt' -%}Editar {source}. Texto actual: "{text}". Cambio:
15
+ {%- when 'go_home' -%}Ir a la página de inicio
16
+ {%- when 'home' -%}Inicio
17
+ {%- when 'language' -%}Idioma
18
+ {%- when 'latest_posts' -%}Últimas publicaciones
19
+ {%- when 'main_nav' -%}Principal
20
+ {%- when 'min_read' -%}min de lectura
21
+ {%- when 'mode_auto' -%}Auto
22
+ {%- when 'mode_dark' -%}Oscuro
23
+ {%- when 'mode_light' -%}Claro
24
+ {%- when 'next' -%}Siguiente
25
+ {%- when 'not_found_text' -%}Esta dirección no existe o se ha movido. Use el campo de búsqueda o vaya a la página de inicio.
26
+ {%- when 'not_found_title' -%}Página no encontrada
27
+ {%- when 'on_this_page' -%}En esta página
28
+ {%- when 'pager' -%}Anterior y siguiente
29
+ {%- when 'post_pager' -%}Publicación anterior y siguiente
30
+ {%- when 'posts' -%}Publicaciones
31
+ {%- when 'previous' -%}Anterior
32
+ {%- when 'related_posts' -%}Publicaciones relacionadas
33
+ {%- when 'search' -%}Buscar
34
+ {%- when 'search_count' -%}{n} resultados
35
+ {%- when 'search_none' -%}No hay resultados
36
+ {%- when 'series' -%}Serie
37
+ {%- when 'series_pager' -%}Anterior y siguiente en esta serie
38
+ {%- when 'series_part' -%}Parte {n} de {total}
39
+ {%- when 'skip' -%}Saltar al contenido
40
+ {%- when 'tags' -%}Etiquetas
41
+ {%- when 'theme' -%}Tema
42
+ {%- when 'translation_key' -%}Clave de traducción
43
+ {%- endcase -%}