diff --git a/apps/test/content/posts/rtl-test/index.ar.md b/apps/test/content/posts/rtl-test/index.ar.md new file mode 100644 index 00000000..dfb0df7e --- /dev/null +++ b/apps/test/content/posts/rtl-test/index.ar.md @@ -0,0 +1,189 @@ +--- +title: اختبار دعم اللغة العربية والكتابة من اليمين إلى اليسار +date: 2026-08-23T10:00:00+08:00 +collections: + - اختبارات +categories: + - ميزات +tags: + - RTL + - عربي + - اختبار +--- + +هذا مقال اختباري شامل لدعم اللغة العربية والكتابة من اليمين إلى اليسار في سمة [FixIt](https://github.com/hugo-fixit/FixIt/). يهدف هذا المقال إلى اختبار جميع عناصر الويب المختلفة مع المحتوى العربي. + + + +## المقدمة + +مرحباً بكم في هذا المقال الاختباري الشامل. اللغة العربية هي واحدة من أكثر اللغات انتشاراً في العالم، وتتميز بكتابتها من اليمين إلى اليسار. يتطلب دعم هذه اللغة في تصميمات الويب اهتماماً خاصاً بالعديد من الجوانب التقنية. + +### لماذا RTL مهم؟ + +عندما نصمم مواقع ويب تدعم اللغات التي تُكتب من اليمين إلى اليسار، يجب علينا مراعاة عدة عوامل: + +- **اتجاه النص**: يجب أن يتدفق النص بشكل طبيعي من اليمين إلى اليسار +- **تخطيط الصفحة**: يجب أن تكون العناصر مرتبة بشكل منطقي +- **الرموز والأيقونات**: قد تحتاج بعضها إلى انعكاس +- **التباعد بين الأسطر**: يحتاج النص العربي إلى مساحة أكبر للتشكيل + +## النص المختلط + +هذا نص يحتوي على كلمات إنجليزية مثل JavaScript و HTML و CSS مع نص عربي. يجب أن يظهر كل شيء بشكل صحيح. + +## الروابط + +- [موقع Hugo](https://gohugo.io) +- [سمة FixIt](https://fixit.lruihao.cn) +- [وثائق RTL](https://rtlstyling.com) + +## القوائم + +القوائم غير المرتبة: + +- عنصر القائمة الأول +- عنصر القائمة الثاني +- عنصر القائمة الثالث + - عنصر فرعي + - عنصر فرعي آخر + +القوائم المرتبة: + +1. الخطوة الأولى في العملية +2. الخطوة الثانية +3. الخطوة الثالثة والأخيرة + +قوائم المهام: + +- [x] إعداد بيئة التطوير +- [x] كتابة المحتوى الأساسي +- [ ] اختبار التوافق مع المتصفحات +- [ ] مراجعة التصميم النهائي +- [ ] نشر الموقع + +## الجداول + +| اللغة | الاتجاه | الحروف المتصلة | +| ---------: | ------: | -------------: | +| العربية | RTL | نعم | +| الفارسية | RTL | نعم | +| العبرية | RTL | لا | +| الإنجليزية | LTR | لا | + +## الاقتباسات + +> العلم نور والجهل ظلام +> — مثل عربي + +اقتباس طويل: + +> إن الله لا يغير ما بقوم حتى يغيروا ما بأنفسهم وإذا أراد الله بقوم سوءاً فلا مرد له وما لهم من دونه من وال + +## الأيقونات + +أيقونات يتم قلبها في RTL: + +- :(fa-solid fa-tag): وسم +- :(fa-solid fa-tags): وسوم +- :(fa-solid fa-folder): مجلد +- :(fa-solid fa-folder-open): مجلد مفتوح +- :(fa-solid fa-pen-to-square): قلم تعديل + +أيقونات لا يتم قلبها في RTL: + +- :(fa-solid fa-share): مشاركة +- :(fa-solid fa-search): بحث + +## التبويبات + +{{< tabs >}} +{{% tab title="العلامة الأولى" %}} +محتوى التبويب الأول. +{{% /tab %}} +{{% tab title="العلامة الثانية" %}} +محتوى التبويب الثاني. +{{% /tab %}} +{{< /tabs >}} + +## التفاصيل القابلة للطي + +
+انقر لعرض التفاصيل + +هذا محتوى مخفي يمكنBOOLE توسيعه بالنقر. + +المحتوى يمكن أن يكون نصاً أو كوداً أو أي عنصر آخر. + +
+ +## التنبيهات + +{{< admonition >}} +هذا تنبيه عادي يحتوي على معلومات مفيدة للمستخدم. +{{< /admonition >}} + +> [!IMPORTANT] +> تأكد من اختبار جميع التغييرات قبل النشر. + +## المحتوى المشفر + +{{< fixit-encryptor password="1212" message="أدخل كلمة المرور (1212) لعرض المحتوى" >}} +هذا محتوى مشفر. يجب إدخال كلمة المرور لعرضه. +{{< /fixit-encryptor >}} + +## أمثلة على المحتوى LTR + +في صفحة RTL، بعض العناصر تبقى باتجاه LTR لأن محتاها لغوي بحت أو برمجي. فيما يلي أمثلة: + +### كتلة الكود + +```c +#include + +int main() { + printf("Hello, World!\n"); + return 0; +} +``` + +### عارض JSON + +```json +{ + "name": "FixIt", + "version": "1.0.0", + "features": ["RTL", "i18n", "shortcodes"] +} +``` + +### تبويبات الكود + +```python {group=tab1} +print("Python") +``` + +```go {group=tab1} +fmt.Println("Go") +``` + +### الصيغ الرياضية + +معادلة بسيطة: $E = mc^2$ + +معادلة معقدة: + +$$\sum_{i=1}^{n} i = \frac{n(n+1)}{2}$$ + +### مخططات Mermaid + +```mermaid +graph LR + A[بداية] --> B[عملية] + B --> C[نهاية] +``` + +--- +{.awesome-hr} + +_تم إنشاء هذا المقال لاختبار دعم اللغة العربية في سمة FixIt._ diff --git a/apps/test/content/posts/rtl-test/index.en.md b/apps/test/content/posts/rtl-test/index.en.md new file mode 100644 index 00000000..460accd1 --- /dev/null +++ b/apps/test/content/posts/rtl-test/index.en.md @@ -0,0 +1,187 @@ +--- +title: Arabic RTL Test +date: 2026-08-23T10:00:00+08:00 +collections: + - Tests +categories: + - Features +tags: + - RTL + - Arabic +--- + +A comprehensive test article for Arabic language and Right-to-Left layout support in the [FixIt](https://github.com/hugo-fixit/FixIt/) theme. This article tests various web elements with Arabic content. + + + +## Introduction + +Welcome to this comprehensive test article. Arabic is one of the most widely spoken languages in the world, characterized by its Right-to-Left writing direction. Supporting this language in web designs requires special attention to many technical aspects. + +### Why RTL Matters + +When designing websites that support Right-to-Left languages, we need to consider several factors: + +- **Text direction**: Text should flow naturally from right to left +- **Page layout**: Elements should be arranged in a logical order +- **Symbols and icons**: Some may need to be mirrored +- **Line spacing**: Arabic text needs more space for diacritics + +## Mixed Text + +This text contains English words like JavaScript, HTML, and CSS alongside Arabic text. Everything should display correctly. + +## Links + +- [Hugo Website](https://gohugo.io) +- [FixIt Theme](https://fixit.lruihao.cn) +- [RTL Styling](https://rtlstyling.com) + +## Lists + +Unordered lists: + +- First list item +- Second list item +- Third list item + - Sub item + - Another sub item + +Ordered lists: + +1. First step in the process +2. Second step +3. Third and final step + +Task lists: + +- [x] Set up development environment +- [x] Write basic content +- [ ] Test browser compatibility +- [ ] Review final design +- [ ] Deploy website + +## Tables + +| Language | Direction | Connected Letters | +| ---------- | --------- | ----------------- | +| Arabic | RTL | Yes | +| Persian | RTL | Yes | +| Hebrew | RTL | No | +| English | LTR | No | + +## Blockquotes + +> Knowledge is light and ignorance is darkness +> — Arabic proverb + +Long quote: + +> Indeed, Allah does not change the condition of a people until they change what is in themselves + +## Icons + +Icons that are flipped in RTL: + +- :(fa-solid fa-tag): Tag +- :(fa-solid fa-tags): Tags +- :(fa-solid fa-folder): Folder +- :(fa-solid fa-folder-open): Folder Open +- :(fa-solid fa-pen-to-square): Edit + +Icons that are NOT flipped in RTL: + +- :(fa-solid fa-share): Share +- :(fa-solid fa-search): Search + +## Tabs + +{{< tabs >}} +{{% tab title="First Tab" %}} +Content of the first tab. +{{% /tab %}} +{{% tab title="Second Tab" %}} +Content of the second tab. +{{% /tab %}} +{{< /tabs >}} + +## Collapsible Details + +
+Click to show details + +This is hidden content that can be expanded by clicking. + +Content can be text, code, or any other element. + +
+ +## Alerts + +{{< admonition >}} +This is a regular admonition with useful information for the user. +{{< /admonition >}} + +> [!IMPORTANT] +> Make sure to test all changes before deploying. + +## Encrypted Content + +{{< fixit-encryptor password="1212" message="Enter password (1212) to view content" >}} +This is encrypted content. You must enter the password to view it. +{{< /fixit-encryptor >}} + +## LTR Content Examples + +In an RTL page, some elements remain in LTR direction because their content is purely linguistic or programmatic. Here are examples: + +### Code Block + +```c +#include + +int main() { + printf("Hello, World!\n"); + return 0; +} +``` + +### JSON Viewer + +```json +{ + "name": "FixIt", + "version": "1.0.0", + "features": ["RTL", "i18n", "shortcodes"] +} +``` + +### Code Tabs + +```python {group=tab1} +print("Python") +``` + +```go {group=tab1} +fmt.Println("Go") +``` + +### Math + +Simple equation: $E = mc^2$ + +Complex equation: + +$$\sum_{i=1}^{n} i = \frac{n(n+1)}{2}$$ + +### Mermaid Diagram + +```mermaid +graph LR + A[Start] --> B[Process] + B --> C[End] +``` + +--- + +_Created to test Arabic language support in the FixIt theme._ diff --git a/apps/test/content/posts/tabs-comprehensive-test.md b/apps/test/content/posts/tabs-comprehensive-test.md index 0f17b9a0..56ce3f60 100644 --- a/apps/test/content/posts/tabs-comprehensive-test.md +++ b/apps/test/content/posts/tabs-comprehensive-test.md @@ -34,7 +34,7 @@ See Types section for various test cases. ### Underline (Default) - + {{< tabs placement="top" >}} {{% tab title="Tab 1" %}}Content for underline style tab 1{{% /tab %}} @@ -44,7 +44,7 @@ See Types section for various test cases. ### Pill - + {{< tabs type="pill" placement="top" >}} {{% tab title="Tab 1" %}}Content for pill style tab 1{{% /tab %}} @@ -54,7 +54,7 @@ See Types section for various test cases. ### Card - + {{< tabs type="card" placement="top" >}} {{% tab title="Tab 1" %}}Content for card style tab 1{{% /tab %}} @@ -126,7 +126,7 @@ Nested tab C with a table: {{% tab title="Outer Tab 3" %}} This tab contains vertical nested tabs: -{{< tabs type="card" placement="left" >}} +{{< tabs type="card" placement="end" >}} {{% tab title="Vertical A" %}} Content for vertical nested tab A. diff --git a/apps/test/hugo.toml b/apps/test/hugo.toml index 202282ca..41ac5381 100644 --- a/apps/test/hugo.toml +++ b/apps/test/hugo.toml @@ -9,16 +9,22 @@ ignoreLogs = [ "warning-file-tree" ] defaultContentLanguage = "en" # test for multilingual support -# [languages] +[languages] -# [languages.en] -# locale = "en" -# label = "English" +[languages.en] +locale = "en" +label = "English" +# [todo] 优化中文排版 # [languages.zh-cn] # locale = "zh-CN" # label = "简体中文" +[languages.ar] +direction = "rtl" +locale = "ar" +label = "العربية" + [permalinks] [permalinks.page] diff --git a/assets/data/cdn/jsdelivr.yml b/assets/data/cdn/jsdelivr.yml index d4747fee..cc95a6a3 100644 --- a/assets/data/cdn/jsdelivr.yml +++ b/assets/data/cdn/jsdelivr.yml @@ -34,8 +34,8 @@ libFiles: gitalkJS: gitalk@1.8.0/dist/gitalk.min.js # instant.page@5.2.0 https://github.com/instantpage/instant.page instantPage: instant.page@5.2.0/instantpage.min.js - # json-viewer-element@1.0.4 https://github.com/Lruihao/json-viewer-element - jsonViewerElementJS: json-viewer-element@1.0.4/dist/json-viewer-element.umd.js + # json-viewer-element@1.0.6 https://github.com/Lruihao/json-viewer-element + jsonViewerElementJS: json-viewer-element@1.0.6/dist/json-viewer-element.umd.js # katex@0.17.0 https://github.com/KaTeX/KaTeX katexCopyTexJS: katex@0.17.0/dist/contrib/copy-tex.min.js katexCSS: katex@0.17.0/dist/katex.min.css diff --git a/assets/data/cdn/unpkg.yml b/assets/data/cdn/unpkg.yml index 48f1c6af..9483ccf3 100644 --- a/assets/data/cdn/unpkg.yml +++ b/assets/data/cdn/unpkg.yml @@ -34,8 +34,8 @@ libFiles: gitalkJS: gitalk@1.8.0/dist/gitalk.min.js # instant.page@5.2.0 https://github.com/instantpage/instant.page instantPage: instant.page@5.2.0/instantpage.js - # json-viewer-element@1.0.4 https://github.com/Lruihao/json-viewer-element - jsonViewerElementJS: json-viewer-element@1.0.4/dist/json-viewer-element.umd.js + # json-viewer-element@1.0.6 https://github.com/Lruihao/json-viewer-element + jsonViewerElementJS: json-viewer-element@1.0.6/dist/json-viewer-element.umd.js # katex@0.17.0 https://github.com/KaTeX/KaTeX katexCopyTexJS: katex@0.17.0/dist/contrib/copy-tex.min.js katexCSS: katex@0.17.0/dist/katex.min.css diff --git a/assets/lib/json-viewer-element/json-viewer-element.umd.js b/assets/lib/json-viewer-element/json-viewer-element.umd.js index dc6c2524..c6547991 100644 --- a/assets/lib/json-viewer-element/json-viewer-element.umd.js +++ b/assets/lib/json-viewer-element/json-viewer-element.umd.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).JsonViewerElement={})}(this,function(e){"use strict";const t=document.createElement("template");t.innerHTML='\n\n
\n\n';class n extends HTMLElement{constructor(){super(),this._value=null,this.root=this.attachShadow({mode:"open"}),this.root.appendChild(t.content.cloneNode(!0)),this.container=this.root.getElementById("root")}static get observedAttributes(){return["value","expand-depth","copyable","sort","boxed","theme","parse"]}connectedCallback(){this.render()}attributeChangedCallback(){this.render()}set value(e){e!==this._value&&(this._value=e,this.render())}get value(){return this._value??this.getAttribute("value")}set sort(e){this.setAttribute("sort",e?"true":"false")}get sort(){return this.hasAttribute("sort")}set parse(e){this.setAttribute("parse",e?"true":"false")}get parse(){return"false"!==this.getAttribute("parse")}set copyable(e){!1===e?this.removeAttribute("copyable"):this.setAttribute("copyable",JSON.stringify(e))}get copyable(){if(!this.hasAttribute("copyable"))return!1;const e=this.getAttribute("copyable"),t={copyText:"Copy",copiedText:"Copied",timeout:2e3,align:"right"};if(""===e||null===e)return t;try{return{...t,...JSON.parse(e)}}catch{return t}}get expandDepth(){return Number(this.getAttribute("expand-depth")??1)}copyText(e){return navigator.clipboard?(this.copyText=e=>navigator.clipboard.writeText(e),this.copyText(e)):(this.copyText=e=>new Promise((t,n)=>{const o=document.createElement("input");o.value=e,document.body.appendChild(o),o.select(),document.execCommand("copy")?(document.body.removeChild(o),t()):(document.body.removeChild(o),n(new Error("Copy failed")))}),this.copyText(e))}render(){if("string"==typeof this.value&&this.parse)try{this._value=JSON.parse(this.value)}catch{}this.container.innerHTML="",this.container.appendChild(this.build(this._value,0));const e=this.copyable;if(e){const t=e.align||"right",n=this.root.querySelector('slot[name="copy-button"]'),o=n.assignedElements()[0],r=this.root.querySelector(".jv-copy");if(n.hidden=!1,n.className=`align-${t}`,!o){let t;r.textContent=e.copyText;const n=r.cloneNode(!0);r.replaceWith(n),n.textContent=e.copyText,n.addEventListener("click",()=>{const o=JSON.stringify(this._value,null,2);this.copyText(o).then(()=>{n.textContent=e.copiedText,t=window.setTimeout(()=>{n.textContent=e.copyText,clearTimeout(t)},e.timeout),this.dispatchEvent(new CustomEvent("copy-success",{detail:{text:o,options:e}}))}).catch(()=>{console.warn("Failed to copy text to clipboard"),this.dispatchEvent(new CustomEvent("copy-error",{detail:{text:o,options:e}}))})})}}}build(e,t){if(null===e)return this.leaf("null","jv-null");if(void 0===e)return this.leaf("undefined","jv-undefined");if("boolean"==typeof e)return this.leaf(String(e),"jv-boolean");if("number"==typeof e)return this.leaf(String(e),"jv-number");if("string"==typeof e)return this.leaf(`"${e}"`,"jv-string");if("function"==typeof e)return this.leaf("","jv-function");if(e instanceof RegExp)return this.leaf("","jv-regexp");if(e instanceof Date)return this.leaf(`"${e.toLocaleString()}"`,"jv-string");const n=Array.isArray(e),o=document.createElement("span");o.className="jv-node",o.setAttribute("part","node");const r=document.createElement("div");r.className="jv-list",r.setAttribute("part","list");const s=n?this.sort?[...e.keys()].sort((e,t)=>e-t):[...e.keys()]:this.sort?Object.keys(e).sort():Object.keys(e);for(const l of s){const o=document.createElement("div"),s=this.build(e[l],t+1);if(o.className="jv-item",s instanceof Element&&s.classList.contains("jv-node")){const e=s.querySelector(".jv-toggle");e&&(e.remove(),o.append(e))}if(!n){const e=document.createElement("span");e.className="jv-key",e.setAttribute("part","key"),e.textContent=`"${l}": `,o.append(e)}o.append(s),r.append(o)}const i=document.createElement("span");i.className="jv-toggle",i.setAttribute("part","toggle"),o.classList.contains("collapsed")||i.classList.add("open"),i.addEventListener("click",()=>{o.classList.toggle("collapsed"),i.classList.toggle("open"),this.dispatchEvent(new CustomEvent("toggle",{detail:{node:o,data:e,isCollapsed:o.classList.contains("collapsed")}}))});const a=document.createElement("span");return a.className="jv-ellipsis",a.setAttribute("part","ellipsis"),a.textContent=`...${s.length}`,a.addEventListener("click",()=>{o.classList.remove("collapsed"),i.classList.add("open")}),t>=this.expandDepth&&(o.classList.add("collapsed"),i.classList.remove("open")),s.length||o.classList.add("empty"),o.append(i,n?"[":"{",a,r,n?"]":"}"),o}leaf(e,t){const n=document.createElement("span");return n.className=`jv-value ${t}`,n.setAttribute("part",`value ${t.replace("jv-","")}`),n.textContent=e,n}}customElements.define("json-viewer",n),e.JsonViewerElement=n,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})}); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).JsonViewerElement={})}(this,function(e){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});var t=document.createElement("template");t.innerHTML='\n\n
\n\n';var n=class extends HTMLElement{static get observedAttributes(){return["value","expand-depth","copyable","sort","boxed","theme","parse"]}constructor(){super(),this._value=null,this.root=this.attachShadow({mode:"open"}),this.root.appendChild(t.content.cloneNode(!0)),this.container=this.root.getElementById("root")}connectedCallback(){this.render()}attributeChangedCallback(){this.render()}set value(e){e!==this._value&&(this._value=e,this.render())}get value(){return this._value??this.getAttribute("value")}set sort(e){this.setAttribute("sort",e?"true":"false")}get sort(){return this.hasAttribute("sort")}set parse(e){this.setAttribute("parse",e?"true":"false")}get parse(){return"false"!==this.getAttribute("parse")}set copyable(e){!1===e?this.removeAttribute("copyable"):this.setAttribute("copyable",JSON.stringify(e))}get copyable(){if(!this.hasAttribute("copyable"))return!1;const e=this.getAttribute("copyable"),t={copyText:"Copy",copiedText:"Copied",timeout:2e3,align:"right"};if(""===e||null===e)return t;try{return{...t,...JSON.parse(e)}}catch{return t}}get expandDepth(){return Number(this.getAttribute("expand-depth")??1)}copyText(e){return navigator.clipboard?(this.copyText=e=>navigator.clipboard.writeText(e),this.copyText(e)):(this.copyText=e=>new Promise((t,n)=>{const o=document.createElement("input");o.value=e,document.body.appendChild(o),o.select(),document.execCommand("copy")?(document.body.removeChild(o),t()):(document.body.removeChild(o),n(new Error("Copy failed")))}),this.copyText(e))}render(){if("string"==typeof this.value&&this.parse)try{this._value=JSON.parse(this.value)}catch{}this.container.innerHTML="",this.container.appendChild(this.build(this._value,0));const e=this.copyable;if(e){const t=e.align||"right",n=this.root.querySelector('slot[name="copy-button"]'),o=n.assignedElements()[0],r=this.root.querySelector(".jv-copy");if(n.hidden=!1,n.className=`align-${t}`,!o){let t;r.textContent=e.copyText??null;const n=r.cloneNode(!0);r.replaceWith(n),n.textContent=e.copyText??null,n.addEventListener("click",()=>{const o=JSON.stringify(this._value,null,2);this.copyText(o).then(()=>{n.textContent=e.copiedText??null,t=window.setTimeout(()=>{n.textContent=e.copyText??null,clearTimeout(t)},e.timeout),this.dispatchEvent(new CustomEvent("copy-success",{detail:{text:o,options:e}}))}).catch(()=>{console.warn("Failed to copy text to clipboard"),this.dispatchEvent(new CustomEvent("copy-error",{detail:{text:o,options:e}}))})})}}}build(e,t){if(null===e)return this.leaf("null","jv-null");if(void 0===e)return this.leaf("undefined","jv-undefined");if("boolean"==typeof e)return this.leaf(String(e),"jv-boolean");if("number"==typeof e)return this.leaf(String(e),"jv-number");if("string"==typeof e)return this.leaf(`"${e}"`,"jv-string");if("function"==typeof e)return this.leaf("","jv-function");if(e instanceof RegExp)return this.leaf("","jv-regexp");if(e instanceof Date)return this.leaf(`"${e.toLocaleString()}"`,"jv-string");const n=Array.isArray(e),o=document.createElement("span");o.className="jv-node",o.setAttribute("part","node");const r=document.createElement("div");r.className="jv-list",r.setAttribute("part","list");const i=n?this.sort?[...e.keys()].sort((e,t)=>e-t):[...e.keys()]:this.sort?Object.keys(e).sort():Object.keys(e);for(const a of i){const o=document.createElement("div"),i=this.build(e[a],t+1);if(o.className="jv-item",i instanceof Element&&i.classList.contains("jv-node")){const e=i.querySelector(".jv-toggle");e&&(e.remove(),o.append(e))}if(!n){const e=document.createElement("span");e.className="jv-key",e.setAttribute("part","key"),e.textContent=`"${a}": `,o.append(e)}o.append(i),r.append(o)}const s=document.createElement("span");s.className="jv-toggle",s.setAttribute("part","toggle"),o.classList.contains("collapsed")||s.classList.add("open"),s.addEventListener("click",()=>{o.classList.toggle("collapsed"),s.classList.toggle("open"),this.dispatchEvent(new CustomEvent("toggle",{detail:{node:o,data:e,isCollapsed:o.classList.contains("collapsed")}}))});const l=document.createElement("span");return l.className="jv-ellipsis",l.setAttribute("part","ellipsis"),l.textContent=`...${i.length}`,l.addEventListener("click",()=>{o.classList.remove("collapsed"),s.classList.add("open")}),t>=this.expandDepth&&(o.classList.add("collapsed"),s.classList.remove("open")),i.length||o.classList.add("empty"),o.append(s,n?"[":"{",l,r,n?"]":"}"),o}leaf(e,t){const n=document.createElement("span");return n.className=`jv-value ${t}`,n.setAttribute("part",`value ${t.replace("jv-","")}`),n.textContent=e,n}};customElements.define("json-viewer",n),e.JsonViewerElement=n}); \ No newline at end of file diff --git a/assets/scss/content/_alert.scss b/assets/scss/content/_alert.scss index f2712510..68279db4 100644 --- a/assets/scss/content/_alert.scss +++ b/assets/scss/content/_alert.scss @@ -7,7 +7,7 @@ padding: 0.5rem 1rem; margin-block: 1rem; color: inherit; - border-left: 0.25em solid fi-var(alert-border-color); + border-inline-start: 0.25em solid fi-var(alert-border-color); > :first-child { margin-top: 0; diff --git a/assets/scss/content/_code.scss b/assets/scss/content/_code.scss index b9bcc898..448d76be 100644 --- a/assets/scss/content/_code.scss +++ b/assets/scss/content/_code.scss @@ -22,13 +22,13 @@ display: inline-block; width: fi-var(color-code-size); height: fi-var(color-code-size); - @include border-radius(full); - margin-right: 0.25em; + margin-inline-end: 0.25em; vertical-align: middle; border: 1px solid; pointer-events: none; translate: 0 -1px; border-color: light-dark(#d1d9e0b3, #3d444db3); + @include border-radius(full); } } @@ -42,6 +42,7 @@ font-family: fi-var(code-font-family); background-color: fi-var(code-block-background-color); tab-size: 4; + direction: ltr; @include border-radius; + pre { @@ -91,6 +92,7 @@ .highlight { margin: 0.5rem 0; position: relative; + direction: ltr; @include border-radius; // lineNumbersInTable=true @@ -161,7 +163,7 @@ &:not(.code-block) { .lntd:last-child pre.chroma { - padding-left: 0; + padding-inline-start: 0; } } @@ -224,6 +226,10 @@ @include border-radius(top); @include sticky-top-offset; + [dir="rtl"] & { + direction: rtl; + } + + .code-wrapper { @include border-radius(bottom); @@ -237,7 +243,7 @@ padding: 0.4rem; &::after { - padding-left: 0.2rem; + padding-inline-start: 0.2rem; content: attr(data-name, fi-var(code-type, 'Code')); } @@ -366,7 +372,7 @@ .copy-icon-btn { position: absolute; top: 0.5rem; - right: 0.5rem; + inset-inline-end: 0.5rem; } // classic mode code block collapsed @@ -483,7 +489,7 @@ counter-increment: codeNos; content: counter(codeNos); white-space: nowrap; - text-align: right; + text-align: end; width: calc(#{fi-var(line-digit)} * 1ch); min-width: 0.75rem; padding-inline: 0.75rem; @@ -509,7 +515,7 @@ &:not(.line-nos-hidden) { .lntd:last-child pre.chroma:not([contenteditable='true']), .code-wrapper > pre.chroma:not(:has(.ln)) { - padding-left: 0; + padding-inline-start: 0; } } @@ -616,7 +622,7 @@ &:not(:last-child)::after { content: ''; position: absolute; - right: 0; + inset-inline-end: 0; top: 50%; translate: 0 -50%; width: 1px; @@ -653,6 +659,10 @@ pointer-events: none; transition: 0.3s ease-in-out; @include border-radius; + + [dir="rtl"] & { + translate: -2px 2px; + } } } diff --git a/assets/scss/content/_content.scss b/assets/scss/content/_content.scss index 23a4900c..222b5f65 100644 --- a/assets/scss/content/_content.scss +++ b/assets/scss/content/_content.scss @@ -15,14 +15,14 @@ display: inline-block; width: max-content; rotate: 30deg; - margin-right: 0.25em; + margin-inline-end: 0.25em; color: fi-var(danger); } .icon-repost { display: inline-block; width: max-content; - margin-right: 0.25em; + margin-inline-end: 0.25em; color: fi-var(success); } @@ -116,21 +116,25 @@ text-rendering: auto; -webkit-font-smoothing: antialiased; position: absolute; - left: 5%; + inset-inline-start: 5%; top: 50%; translate: 0 -50%; color: fi-var(hr-active-color); font-size: 20px; line-height: 1; - transition: left 1s ease-in-out, color 0.3s ease, border-color 0.3s ease; + transition: inset-inline-start 1s ease-in-out, color 0.3s ease, border-color 0.3s ease; font-family: var(--fa-family-classic); font-weight: 600; content: '\f0c4'; @include z-index(base); + + [dir="rtl"] & { + scale: -1 1; + } } &:hover::before { - left: calc(95% - 20px); + inset-inline-start: calc(95% - 20px); } } } @@ -217,7 +221,7 @@ } :is(ol, ul) :is(ol, ul) { - padding-left: 20px; + padding-inline-start: 20px; } li::marker { @@ -232,7 +236,8 @@ &[data-task] { list-style: none; @include task-icon { - margin: 0 0.25em 0 -1.5em; + margin-block: 0; + margin-inline: -1.5em 0.25em; color: fi-var(task-icon-color, fi-var(secondary)); }; @include task-text { @@ -343,12 +348,12 @@ th, td { padding: 0.3rem 1rem; - border-right: 1px solid fi-var(table-border-color); + border-inline-end: 1px solid fi-var(table-border-color); border-bottom: 1px solid fi-var(table-border-color); } tr > :last-child { - border-right: none; + border-inline-end: none; } > :last-child > tr:last-child > * { @@ -392,14 +397,14 @@ blockquote { display: block; - border-left: 0.25em solid fi-var(global-border-color); + border-inline-start: 0.25em solid fi-var(global-border-color); color: fi-var(blockquote-color); padding: 0 1em; margin: 1rem 0; ul, ol { - padding-left: 1.5em; + padding-inline-start: 1.5em; } dl dd { @@ -427,7 +432,7 @@ ol { margin-block: 1em; - padding-left: 1rem; + padding-inline-start: 1rem; } hr { @@ -465,6 +470,7 @@ .diagram-container { position: relative; margin-block: 0.5rem; + direction: ltr; > .copy-icon-btn { position: absolute; @@ -480,12 +486,17 @@ overflow-y: hidden; // neutralize the margin-right setting of .katex .vlist-t2 // to prevent scrollbars from appearing when the width is not full - padding-right: 2px; + padding-inline-end: 2px; + } + .katex { + display: inline-block; + direction: ltr; } .katex-error { padding: 0.14em 0.28em; background-color: mark; cursor: help; + direction: ltr; @include border-radius; } @@ -526,7 +537,7 @@ &.special { .single-title, .single-subtitle { - text-align: right; + text-align: end; } } } diff --git a/assets/scss/content/_fixit-decryptor.scss b/assets/scss/content/_fixit-decryptor.scss index b6e15e83..c64e621a 100644 --- a/assets/scss/content/_fixit-decryptor.scss +++ b/assets/scss/content/_fixit-decryptor.scss @@ -165,8 +165,9 @@ article fixit-encryptor { .fixit-decryptor-field { flex: 1; height: 2.5rem; - border-right: none; - border-radius: fi-var(global-border-radius) 0 0 fi-var(global-border-radius); + border-inline-end: none; + @include border-radius(start); + @include border-radius(end, 0); &:focus-within + .fixit-decryptor-btn { border-color: var(--fi-primary); @@ -177,8 +178,9 @@ article fixit-encryptor { .fixit-decryptor-btn { width: auto; padding: 0 0.85rem; - border-radius: 0 fi-var(global-border-radius) fi-var(global-border-radius) 0; transition: border-color 0.2s ease, box-shadow 0.2s ease; + @include border-radius(start, 0); + @include border-radius(end); } &.decrypted > .fixit-decryptor-container { diff --git a/assets/scss/content/shortcodes/_admonition.scss b/assets/scss/content/shortcodes/_admonition.scss index ca3bd459..ffc93a53 100644 --- a/assets/scss/content/shortcodes/_admonition.scss +++ b/assets/scss/content/shortcodes/_admonition.scss @@ -8,10 +8,10 @@ position: relative; margin: 1rem 0; padding: 0 0.75rem; - border-left: .25rem solid; + border-inline-start: .25rem solid; overflow: hidden; background-color: fi-var(admonition-bg-color); - border-left-color: fi-var(admonition-color); + border-inline-start-color: fi-var(admonition-color); @include border-radius; .admonition-title { @@ -30,11 +30,12 @@ // title-only admonition without content &:not(:has(+ .details-content)) { @include set-fi-var(admonition-title-font-weight, normal); - padding: 0.75rem 1rem 0.75rem 2.2rem; + padding-inline: 2.2rem 1rem; + padding-block: 0.75rem; border: 0; i.icon { - left: 1.1rem; + inset-inline-start: 1.1rem; font-size: 1rem; } } @@ -73,15 +74,23 @@ font-size: 0.85rem; position: absolute; top: 50%; - left: 0.9rem; + inset-inline-start: 0.9rem; translate: -50% -50%; + + [dir="rtl"] & { + translate: 50% -50%; + } } i.details-icon { position: absolute; top: 50%; - right: 0.9rem; + inset-inline-end: 0.9rem; translate: 50% -50%; + + [dir="rtl"] & { + translate: -50% -50%; + } } // set color for each admonition type diff --git a/assets/scss/content/shortcodes/_cardlink.scss b/assets/scss/content/shortcodes/_cardlink.scss index fbae38fd..3c8a0882 100644 --- a/assets/scss/content/shortcodes/_cardlink.scss +++ b/assets/scss/content/shortcodes/_cardlink.scss @@ -20,8 +20,8 @@ position: absolute; top: 0.75rem; bottom: 0.75rem; - left: 0; - right: 0; + inset-inline-start: 0; + inset-inline-end: 0; background-image: fi-var(logo-img); background-repeat: no-repeat; filter: blur(0.5rem); @@ -67,20 +67,22 @@ width: 1rem; height: 1rem; flex-shrink: 0; - margin-right: 0.25rem; + margin-inline-end: 0.25rem; } &url { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; + // URL direction should stay LTR + direction: ltr; } &shortcut-icon { width: 4rem; height: 4rem; flex-shrink: 0; - margin-left: 0.25rem; + margin-inline-start: 0.25rem; &:is(i) { text-align: center; @@ -95,7 +97,7 @@ width: 4rem; height: 4rem !important; flex-shrink: 0; - margin-left: 0.25rem; + margin-inline-start: 0.25rem; object-fit: cover; @include border-radius(full); } diff --git a/assets/scss/content/shortcodes/_center-quote.scss b/assets/scss/content/shortcodes/_center-quote.scss index 9e98ee42..70abf844 100644 --- a/assets/scss/content/shortcodes/_center-quote.scss +++ b/assets/scss/content/shortcodes/_center-quote.scss @@ -1,7 +1,7 @@ @use "core/functions" as *; .single blockquote.blockquote-center { - border-left: none; + border-inline-start: none; margin: 40px 0; padding: 0; position: relative; @@ -10,7 +10,7 @@ &::after, &::before { - left: 0; + inset-inline-start: 0; line-height: 1; opacity: 0.6; position: absolute; @@ -19,19 +19,27 @@ &::before { border-top: 1px solid fi-var(global-border-color); - text-align: left; + text-align: start; top: -20px; font-family: var(--fa-family-classic); font-weight: 900; content: '\f10d'; + + [dir="rtl"] & { + content: '\f10e'; + } } &::after { border-bottom: 1px solid fi-var(global-border-color); bottom: -20px; - text-align: right; + text-align: end; font-family: var(--fa-family-classic); font-weight: 900; content: '\f10e'; + + [dir="rtl"] & { + content: '\f10d'; + } } } diff --git a/assets/scss/content/shortcodes/_douyin.scss b/assets/scss/content/shortcodes/_douyin.scss index 9f573abc..214602d3 100644 --- a/assets/scss/content/shortcodes/_douyin.scss +++ b/assets/scss/content/shortcodes/_douyin.scss @@ -12,7 +12,7 @@ position: absolute; width: 100%; height: 100%; - left: 0; + inset-inline-start: 0; top: 0; } diff --git a/assets/scss/content/shortcodes/_file-tree.scss b/assets/scss/content/shortcodes/_file-tree.scss index fc8cd32b..c112c8f6 100644 --- a/assets/scss/content/shortcodes/_file-tree.scss +++ b/assets/scss/content/shortcodes/_file-tree.scss @@ -8,6 +8,7 @@ line-height: 1; margin-block: 0.5rem; transition: box-shadow 0.2s ease; + direction: ltr; @include border-radius; &:hover { diff --git a/assets/scss/content/shortcodes/_mermaid.scss b/assets/scss/content/shortcodes/_mermaid.scss index 451ae73c..f7f04e50 100644 --- a/assets/scss/content/shortcodes/_mermaid.scss +++ b/assets/scss/content/shortcodes/_mermaid.scss @@ -18,7 +18,7 @@ svg { max-width: 100%; - height: auto; + height: auto; } } @@ -60,12 +60,16 @@ &::before { content: ''; position: absolute; - left: 0; + inset-inline-start: 0; top: 50%; width: 1px; translate: -2px -50%; height: fi-var(code-block-font-size); background-color: fi-var(global-border-color-weight); + + [dir="rtl"] & { + translate: 2px -50%; + } } } diff --git a/assets/scss/content/shortcodes/_tabs.scss b/assets/scss/content/shortcodes/_tabs.scss index 0c2207cb..adb7688b 100644 --- a/assets/scss/content/shortcodes/_tabs.scss +++ b/assets/scss/content/shortcodes/_tabs.scss @@ -73,8 +73,8 @@ tab-container { } } - &[placement='left'], - &[placement='right'] { + &[placement='start'], + &[placement='end'] { max-width: 100%; &::part(tablist-wrapper) { @@ -103,7 +103,7 @@ tab-container { flex-direction: column-reverse; } - &[placement='right'] { + &[placement='end'] { flex-direction: row-reverse; } @@ -166,8 +166,8 @@ tab-container { } } - &[placement='left'], - &[placement='right'] { + &[placement='start'], + &[placement='end'] { > .tab-button { @include tab-button-size(1rem, 0); } @@ -202,34 +202,44 @@ tab-container { } // Left placement - &[placement='left'] { + &[placement='start'] { &::part(tablist-tab-wrapper) { - border-right: 2px solid fi-var(global-border-color); + border-inline-end: 2px solid fi-var(global-border-color); } &::part(tablist-wrapper)::before { box-shadow: inset -2px 0 0 fi-var(primary); translate: 2px 0; + + [dir="rtl"] & { + box-shadow: inset 2px 0 0 fi-var(primary); + translate: -2px 0; + } } > .tab-button { - text-align: right; + text-align: end; } } // Right placement - &[placement='right'] { + &[placement='end'] { &::part(tablist-tab-wrapper) { - border-left: 2px solid fi-var(global-border-color); + border-inline-start: 2px solid fi-var(global-border-color); } &::part(tablist-wrapper)::before { box-shadow: inset 2px 0 0 fi-var(primary); translate: -2px 0; + + [dir="rtl"] & { + box-shadow: inset -2px 0 0 fi-var(primary); + translate: 2px 0; + } } > .tab-button { - text-align: left; + text-align: start; } } } @@ -268,8 +278,8 @@ tab-container { } } - &[placement='left'], - &[placement='right'] { + &[placement='start'], + &[placement='end'] { padding-bottom: 0.5rem; &::part(tablist) { @@ -296,27 +306,35 @@ tab-container { } // Left placement - &[placement='left'] { + &[placement='start'] { &::part(tablist) { - margin-left: 0.5rem; + margin-inline-end: 0.5rem; } > .tab-button { &:hover { translate: 2px 0; + + [dir="rtl"] & { + translate: -2px 0; + } } } } // Right placement - &[placement='right'] { + &[placement='end'] { &::part(tablist) { - margin-right: 0.5rem; + margin-inline-start: 0.5rem; } > .tab-button { &:hover { translate: -2px 0; + + [dir="rtl"] & { + translate: 2px 0; + } } } } @@ -362,13 +380,13 @@ tab-container { > .tab-button { &:first-of-type { position: sticky; - left: 0; + inset-inline-start: 0; @include z-index(base, 1); } &:last-of-type { position: sticky; - right: 0; + inset-inline-end: 0; @include z-index(base, 1); } } @@ -417,44 +435,52 @@ tab-container { } // Left placement - &[placement='left'] { + &[placement='start'] { &::part(tablist-tab-wrapper) { - border-right: 1px solid fi-var(global-border-color); + border-inline-end: 1px solid fi-var(global-border-color); } > .tab-button { translate: 1px 0; - @include border-radius(left); + @include border-radius(start); + + [dir="rtl"] & { + translate: -1px 0; + } &[aria-selected='true'] { - border-right-color: fi-var(global-background-color); + border-inline-end-color: fi-var(global-background-color); } } > .tab-panel { - border-left: none; - @include border-radius(right); + border-inline-start: none; + @include border-radius(end); } } // Right placement - &[placement='right'] { + &[placement='end'] { &::part(tablist-tab-wrapper) { - border-left: 1px solid fi-var(global-border-color); + border-inline-start: 1px solid fi-var(global-border-color); } > .tab-button { translate: -1px 0; - @include border-radius(right); + @include border-radius(end); + + [dir="rtl"] & { + translate: 1px 0; + } &[aria-selected='true'] { - border-left-color: fi-var(global-background-color); + border-inline-start-color: fi-var(global-background-color); } } > .tab-panel { - border-right: none; - @include border-radius(left); + border-inline-end: none; + @include border-radius(start); } } } @@ -608,14 +634,22 @@ tab-container .tab-panel:not([hidden]) { border-top: 2px solid fi-var(tab-button-border-color); } - &[placement='left'] > .tab-button { + &[placement='start'] > .tab-button { translate: 2px 0; - border-right: 2px solid fi-var(tab-button-border-color); + border-inline-end: 2px solid fi-var(tab-button-border-color); + + [dir="rtl"] & { + translate: -2px 0; + } } - &[placement='right'] > .tab-button { + &[placement='end'] > .tab-button { translate: -2px 0; - border-left: 2px solid fi-var(tab-button-border-color); + border-inline-start: 2px solid fi-var(tab-button-border-color); + + [dir="rtl"] & { + translate: 2px 0; + } } } diff --git a/assets/scss/content/shortcodes/_timeline.scss b/assets/scss/content/shortcodes/_timeline.scss index 5425a70b..f32b221e 100644 --- a/assets/scss/content/shortcodes/_timeline.scss +++ b/assets/scss/content/shortcodes/_timeline.scss @@ -81,7 +81,7 @@ position: absolute; top: 1.25rem; translate: 0 -50%; - left: 0; + inset-inline-start: 0; text-align: center; border-style: solid; color: transparent; @@ -99,7 +99,7 @@ content: ''; position: absolute; top: 0; - left: calc(#{fi-var(timeline-circle-size)} / 2 + #{fi-var(timeline-width)} / 2); + inset-inline-start: calc(#{fi-var(timeline-circle-size)} / 2 + #{fi-var(timeline-width)} / 2); width: fi-var(timeline-width); height: 100%; background-color: fi-var(timeline-color); diff --git a/assets/scss/core/_index.scss b/assets/scss/core/_index.scss index 5d752bff..c7313c97 100644 --- a/assets/scss/core/_index.scss +++ b/assets/scss/core/_index.scss @@ -1,4 +1,5 @@ @use "common"; @use "reboot"; @use "root"; +@use "rtl"; @use "layouts"; diff --git a/assets/scss/core/_reboot.scss b/assets/scss/core/_reboot.scss index f5da39b4..eb1421a0 100644 --- a/assets/scss/core/_reboot.scss +++ b/assets/scss/core/_reboot.scss @@ -219,7 +219,7 @@ fieldset { // 2. Fix wrapping bug. legend { - float: left; // 1 + float: inline-start; // 1 width: 100%; padding: 0; margin-bottom: 0.5rem; @@ -228,7 +228,7 @@ legend { font-size: 1.5rem; + * { - clear: left; // 2 + clear: inline-start; // 2 } } @@ -276,20 +276,6 @@ textarea { } } -// 1. A few input types should stay LTR -// See https://rtlstyling.com/posts/rtl-styling#form-inputs -// 2. RTL only output -// See https://rtlcss.com/learn/usage-guide/control-directives/#raw - -/* rtl:raw: -[type="tel"], -[type="url"], -[type="email"], -[type="number"] { - direction: ltr; -} -*/ - // Remove the inner padding in Chrome and Safari on macOS. ::-webkit-search-decoration { diff --git a/assets/scss/core/_rtl.scss b/assets/scss/core/_rtl.scss new file mode 100644 index 00000000..7cf06d13 --- /dev/null +++ b/assets/scss/core/_rtl.scss @@ -0,0 +1,50 @@ +/// ================================================================================== +/// Right-to-Left (RTL) Support +/// +/// @see https://rtlstyling.com/posts/rtl-styling/ +/// @see https://developer.apple.com/design/human-interface-guidelines/right-to-left/ +/// ================================================================================== + +[dir="rtl"] { + // A few input types should stay LTR + [type="tel"], + [type="url"], + [type="email"], + [type="number"] { + direction: ltr; + } + + // Flip directional icons in RTL + .fa-tags, + .fa-tag, + .fa-folder, + .fa-folder-tree, + .fa-folder-open, + .fa-folder-closed, + .fa-pencil, + .fa-pen-to-square, + .fa-pen-clip, + .fa-square-pen, + .fa-list-ul, + .fa-list-check, + .fa-clipboard-list, + .fa-rectangle-list, + .fa-comments, + .fa-comment, + .fa-comment-dots, + .fa-message, + .fa-retweet, + .octicon-report-16 { + scale: -1 1; + } +} + +// Arabic-script languages (Arabic, Persian, Urdu) typography corrections +// Hebrew and other non-connected RTL scripts don't need these adjustments + +// Letter-spacing breaks connected letter forms +:lang(ar), +:lang(fa), +:lang(ur) { + letter-spacing: 0; +} diff --git a/assets/scss/core/layouts/_footer.scss b/assets/scss/core/layouts/_footer.scss index 76d14d5c..4513816f 100644 --- a/assets/scss/core/layouts/_footer.scss +++ b/assets/scss/core/layouts/_footer.scss @@ -17,8 +17,7 @@ footer { .footer-divider:not(:first-child)::before { content: '|'; - margin-left: 0.25rem; - margin-right: 0.25rem; + margin-inline: 0.25rem; } .hugo-icon, diff --git a/assets/scss/core/layouts/_header.scss b/assets/scss/core/layouts/_header.scss index ae44eb14..da2feb9f 100644 --- a/assets/scss/core/layouts/_header.scss +++ b/assets/scss/core/layouts/_header.scss @@ -119,7 +119,7 @@ header { list-style: none; .dropdown-icon { - margin-left: 0.25rem; + margin-inline-start: 0.25rem; font-size: .875em; color: fi-var(global-font-color); @@ -155,6 +155,10 @@ header { position: relative; @include focus-visible-ring; + [dir="rtl"] & { + scale: -1 1; + } + i { display: inline-block; rotate: 225deg; @@ -195,10 +199,10 @@ header { padding: 0 2rem; height: 100%; - &[data-github-corner='left'] { + &[data-github-corner='start'] { padding-inline-start: fi-var(header-height); } - &[data-github-corner='right'] { + &[data-github-corner='end'] { padding-inline-end: fi-var(header-height); } @@ -211,9 +215,17 @@ header { &:hover .sub-menu { display: block; translate: -0.5rem 0; + + [dir="rtl"] & { + translate: 0.5rem 0; + } } &.language-switch:hover .sub-menu { translate: calc(1.75rem - 100%) 0; + + [dir="rtl"] & { + translate: calc(100% - 1.75rem) 0; + } } } @@ -229,7 +241,7 @@ header { width: 0; margin: 18.5px 0.5rem; padding: 0; - border-left: 1.5px solid fi-var(global-border-color); + border-inline-start: 1.5px solid fi-var(global-border-color); } } @@ -448,7 +460,7 @@ header { .language-select { position: absolute; opacity: 0; - left: 0; + inset-inline-start: 0; top: 0; width: 100%; height: 100%; @@ -457,7 +469,7 @@ header { } .sub-menu { - padding-left: 0; + padding-inline-start: 0; display: none; &.open { diff --git a/assets/scss/core/mixins/_border-radius.scss b/assets/scss/core/mixins/_border-radius.scss index 8e340458..7dae9abb 100644 --- a/assets/scss/core/mixins/_border-radius.scss +++ b/assets/scss/core/mixins/_border-radius.scss @@ -1,12 +1,13 @@ @use "core/functions" as *; /// Mixin to set border-radius -/// @param {String|Number|List} $value - The value of the border-radius, position (top, bottom, left, right) or keyword (full) +/// @param {String|Number|List} $value - The value of the border-radius, position (top, bottom, start, end) or keyword (full) /// @param {Number} $radius - The radius of the border (only for position) /// @example /// @include border-radius; /// @include border-radius(full); /// @include border-radius(top); +/// @include border-radius(start); /// @include border-radius(top, 10px); /// @include border-radius(10px 20px 10px 20px); @mixin border-radius($value: fi-var(global-border-radius), $radius: fi-var(global-border-radius)) { @@ -16,10 +17,12 @@ border-radius: $radius $radius 0 0; } @else if $value == bottom { border-radius: 0 0 $radius $radius; - } @else if $value == left { - border-radius: $radius 0 0 $radius; - } @else if $value == right { - border-radius: 0 $radius $radius 0; + } @else if $value == start { + border-start-start-radius: $radius; + border-end-start-radius: $radius; + } @else if $value == end { + border-start-end-radius: $radius; + border-end-end-radius: $radius; } @else { border-radius: $value; } diff --git a/assets/scss/pages/archives/_index.scss b/assets/scss/pages/archives/_index.scss index 7afc782d..3a4fbbcd 100644 --- a/assets/scss/pages/archives/_index.scss +++ b/assets/scss/pages/archives/_index.scss @@ -8,7 +8,7 @@ font-size: 1.6rem; font-weight: bold; line-height: 140%; - text-align: right; + text-align: end; } .single-subtitle { @@ -16,7 +16,7 @@ font-size: 1.2rem; font-weight: normal; line-height: 100%; - text-align: right; + text-align: end; } .group-title { diff --git a/assets/scss/pages/archives/_terms.scss b/assets/scss/pages/archives/_terms.scss index bc22000f..0adf9c61 100644 --- a/assets/scss/pages/archives/_terms.scss +++ b/assets/scss/pages/archives/_terms.scss @@ -12,7 +12,7 @@ .card-item { font-size: 0.875rem; - text-align: left; + text-align: start; width: 45%; display: flex; align-items: flex-start; @@ -37,8 +37,8 @@ } .more-post { - text-align: right; - padding-right: 1rem; + text-align: end; + padding-inline-end: 1rem; } } @@ -53,7 +53,8 @@ justify-content: space-between; align-items: center; box-sizing: border-box; - margin: 0.25rem 0 0.25rem 1.5rem; + margin-block: 0.25rem; + margin-inline: 1.5rem 0; } .archive-item-link { @@ -65,7 +66,7 @@ } .archive-item-date { - text-align: right; + text-align: end; color: fi-var(global-font-secondary-color); white-space: nowrap; font-variant-numeric: tabular-nums lining-nums; diff --git a/assets/scss/pages/home/_index.scss b/assets/scss/pages/home/_index.scss index 3643c594..4452a7b6 100644 --- a/assets/scss/pages/home/_index.scss +++ b/assets/scss/pages/home/_index.scss @@ -111,7 +111,7 @@ position: absolute; width: 100%; height: 100%; - left: 0; + inset-inline-start: 0; top: 0; object-fit: cover; } @@ -152,7 +152,11 @@ .post-tag:not(:last-child)::after { content: ','; - margin-right: 0.25rem; + margin-inline-end: 0.25rem; + + [dir="rtl"] & { + scale: -1 1; + } } } } diff --git a/assets/scss/pages/posts/_collections.scss b/assets/scss/pages/posts/_collections.scss index f79836dc..ffd99e2d 100644 --- a/assets/scss/pages/posts/_collections.scss +++ b/assets/scss/pages/posts/_collections.scss @@ -16,7 +16,7 @@ &:has(.collection-nav-item:nth-child(2))::before { content: ''; position: absolute; - left: 50%; + inset-inline-start: 50%; bottom: 0.75rem; width: 1px; height: 2rem; @@ -55,6 +55,10 @@ i { flex-shrink: 0; + + [dir="rtl"] & { + scale: -1 1; + } } span { @@ -65,7 +69,7 @@ } &[rel='next'] { - text-align: right; + text-align: end; } &[rel='prev']:hover { @@ -158,7 +162,7 @@ .collection-item > span::before { content: '|'; font-weight: 600; - margin-right: 0.5em; + margin-inline-end: 0.5em; position: relative; bottom: 2px; color: fi-var(single-link-color); @@ -181,6 +185,10 @@ gap: 0.5em; background-color: light-dark(color.adjust($global-background-color, $lightness: -5%), color.adjust($global-background-color-dark, $lightness: 5%)); + [dir="rtl"] & i { + scale: -1 1; + } + a.collection-nav-item { padding-inline: 2px; @include border-radius(full); diff --git a/assets/scss/pages/posts/_footer.scss b/assets/scss/pages/posts/_footer.scss index f8adfc58..d5bb7e61 100644 --- a/assets/scss/pages/posts/_footer.scss +++ b/assets/scss/pages/posts/_footer.scss @@ -18,7 +18,7 @@ .post-info-mod { font-size: 0.8em; - color: fi-var(global-font-secondary-color); + color: fi-var(global-font-secondary-color); @include link(false, false); } @@ -38,8 +38,7 @@ >span:not(:first-child)::before { content: '|'; - margin-left: 0.25rem; - margin-right: 0.25rem; + margin-inline: 0.25rem; color: fi-var(global-font-secondary-color); } } @@ -71,16 +70,15 @@ .post-tags { max-width: 65%; - - * { - display: inline; - } - @include link(true, true); .post-tag:not(:last-child)::after { content: ','; - margin-right: 0.25rem; + margin-inline-end: 0.25rem; + + [dir="rtl"] & { + scale: -1 1; + } } } @@ -96,8 +94,12 @@ font-weight: 600; transition: all 0.3s ease-out; + [dir="rtl"] & i { + scale: -1 1; + } + &[rel='next'] { - text-align: right; + text-align: end; } &[rel='prev']:hover { diff --git a/assets/scss/pages/posts/_related.scss b/assets/scss/pages/posts/_related.scss index fe501a48..0fb95a4a 100644 --- a/assets/scss/pages/posts/_related.scss +++ b/assets/scss/pages/posts/_related.scss @@ -59,7 +59,7 @@ .related-item > span::before { content: '|'; font-weight: 600; - margin-right: 0.5em; + margin-inline-end: 0.5em; position: relative; bottom: 2px; color: fi-var(single-link-color); diff --git a/assets/scss/pages/posts/_toc.scss b/assets/scss/pages/posts/_toc.scss index 73e83252..2dbe48b3 100644 --- a/assets/scss/pages/posts/_toc.scss +++ b/assets/scss/pages/posts/_toc.scss @@ -21,29 +21,29 @@ ul { margin: 0; text-indent: -0.8em; - padding-left: 0.8em; + padding-inline-start: 0.8em; list-style: none; a:first-child::before { content: '|'; font-weight: bolder; - margin-right: 0.5em; + margin-inline-end: 0.5em; position: relative; bottom: 2px; color: fi-var(single-link-color); } ul { - padding-left: 1em; + padding-inline-start: 1em; } } ol { margin: 0; - padding-left: 2.25em; + padding-inline-start: 2.25em; ol { - padding-left: 1.25em; + padding-inline-start: 1.25em; } li:has(> a:hover)::marker { @@ -107,7 +107,7 @@ &::before { content: '|'; font-weight: bolder; - margin-right: 0.5em; + margin-inline-end: 0.5em; position: relative; bottom: 2px; color: fi-var(global-border-color); @@ -121,6 +121,10 @@ &.toc-hidden i.toc-icon { rotate: -90deg; transition: rotate 0.2s ease; + + [dir="rtl"] & { + rotate: 90deg; + } } .toc-content { @@ -225,9 +229,9 @@ height: 100dvh; max-width: 100%; max-height: 100%; - margin-right: 0; + margin-inline-end: 0; border: none; - border-left: 1px solid fi-var(global-border-color-light); + border-inline-start: 1px solid fi-var(global-border-color-light); background-color: fi-var(global-background-color); transition: display 0.2s allow-discrete, @@ -235,10 +239,14 @@ translate 0.2s, opacity 0.2s 0.4s; + [dir="rtl"] & { + translate: -100vw 0; + } + .toc-close-btn { position: absolute; top: 1.25rem; - right: 1rem; + inset-inline-end: 1rem; padding: 0.25rem; color: fi-var(global-font-secondary-color); transition: color 0.2s ease; @@ -302,6 +310,10 @@ &[open] { translate: 100vw 0; + + [dir="rtl"] & { + translate: -100vw 0; + } } } } diff --git a/assets/scss/widgets/_details.scss b/assets/scss/widgets/_details.scss index 790f2ca8..9ae0639b 100644 --- a/assets/scss/widgets/_details.scss +++ b/assets/scss/widgets/_details.scss @@ -14,6 +14,10 @@ color: fi-var(global-font-secondary-color); transition: all 0.2s ease; + [dir="rtl"] & { + scale: -1 1; + } + &:hover { color: fi-var(global-font-color); } @@ -33,6 +37,10 @@ i.details-icon { rotate: 90deg; + + [dir="rtl"] & { + rotate: -90deg; + } } } diff --git a/assets/scss/widgets/_fixed-button.scss b/assets/scss/widgets/_fixed-button.scss index be603e7b..156add8f 100644 --- a/assets/scss/widgets/_fixed-button.scss +++ b/assets/scss/widgets/_fixed-button.scss @@ -3,7 +3,7 @@ .fixed-buttons { position: fixed; - right: 1.5rem; + inset-inline-end: 1.5rem; bottom: 1.5rem; display: flex; flex-direction: column; @@ -49,7 +49,7 @@ svg { position: absolute; top: 0; - left: 0; + inset-inline-start: 0; width: 100%; height: 100%; // Rotate to start from top diff --git a/assets/scss/widgets/_mask.scss b/assets/scss/widgets/_mask.scss index b164ba1a..8703e5ee 100644 --- a/assets/scss/widgets/_mask.scss +++ b/assets/scss/widgets/_mask.scss @@ -5,7 +5,7 @@ background-position: center; position: fixed; top: 0; - left: 0; + inset-inline-start: 0; width: 100%; height: 100%; @include z-index(hide); diff --git a/assets/scss/widgets/_search-modal.scss b/assets/scss/widgets/_search-modal.scss index 7eaf45be..9dbce573 100644 --- a/assets/scss/widgets/_search-modal.scss +++ b/assets/scss/widgets/_search-modal.scss @@ -12,8 +12,7 @@ dialog.search-dialog { // Anchor to top and center horizontally with fixed dimensions // to prevent position jumps when results appear/disappear. top: 15vh; - left: 50%; - margin: 0; + margin: 0 auto; &::backdrop { background-color: rgba(0, 0, 0, 0.25); @@ -219,7 +218,7 @@ dialog.search-dialog { .suggestion-heading-mark { color: fi-var(global-font-tertiary-color); - margin-right: 0.125rem; + margin-inline-end: 0.125rem; } em { @@ -255,7 +254,7 @@ dialog.search-dialog { color: fi-var(global-font-tertiary-color); i { - margin-right: 0.125rem; + margin-inline-end: 0.125rem; } } @@ -370,7 +369,7 @@ dialog.search-dialog { @include media('sm', 'up') { opacity: 0; - translate: -50% 12px; + translate: 0 12px; scale: 0.98; transition: display 0.2s allow-discrete, @@ -381,7 +380,7 @@ dialog.search-dialog { &[open] { opacity: 1; - translate: -50% 0; + translate: 0 0; scale: 1; } @@ -404,7 +403,7 @@ dialog.search-dialog { } &[open] { - translate: -50% 12px; + translate: 0 12px; scale: 0.98; } } diff --git a/assets/scss/widgets/third-party/_github-corner.scss b/assets/scss/widgets/third-party/_github-corner.scss index 5c59604c..ba48f8d9 100644 --- a/assets/scss/widgets/third-party/_github-corner.scss +++ b/assets/scss/widgets/third-party/_github-corner.scss @@ -33,16 +33,17 @@ fill: fi-var(github-corner-fill); } - &.left { - left: 0; - - svg { - scale: -1 1; - } + &.start { + inset-inline-start: 0; } - &.right { - right: 0; + &.end { + inset-inline-end: 0; + } + + // Flip octocat to face the start side + :is([dir="ltr"] &.start, [dir="rtl"] &.end) svg { + scale: -1 1; } @include media('print') { diff --git a/hugo.toml b/hugo.toml index 8bdd1bc6..22d94b5a 100644 --- a/hugo.toml +++ b/hugo.toml @@ -90,7 +90,7 @@ pre = "" # You can add extra information after the name (HTML format is supported), such as icons. post = "" name = "Archives" -url = "/archives/" +url = "archives/" # Title will be shown when you hover on this menu link. title = "" weight = 1 @@ -116,7 +116,7 @@ parent = "" pre = "" post = "" name = "Categories" -url = "/categories/" +url = "categories/" title = "" weight = 2 @@ -129,7 +129,7 @@ parent = "" pre = "" post = "" name = "Tags" -url = "/tags/" +url = "tags/" title = "" weight = 3 @@ -719,8 +719,8 @@ keep_static = false # Whether to make the table of the contents in the sidebar automatically collapsed. auto = true # Position of TOC. -# available values: ["left", "right"] -position = "right" +# available values: ["start", "end"] +position = "end" # Supersede `markup.tableOfContents` settings. ordered = false start_level = 2 @@ -1766,13 +1766,13 @@ polyfill = false # Whether to use object-fit-images to be compatible with older browsers. object_fit = false -# GitHub banner in the top-right or top-left corner. +# GitHub banner in the header corner. [params.github_corner] enable = false permalink = "https://github.com/hugo-fixit/FixIt" title = "View source on GitHub" -# available values: ["left", "right"] -position = "right" +# available values: ["start", "end"] +position = "end" # Gravatar configuration. [params.gravatar] @@ -1793,8 +1793,8 @@ scrollpercent = false # Reading progress bar. [params.reading_progress] enable = false -# available values: ["left", "right"] -start = "left" +# available values: ["start", "end"] +start = "start" # available values: ["top", "bottom"] position = "top" reversed = false diff --git a/i18n/ar.toml b/i18n/ar.toml new file mode 100644 index 00000000..ba3804b2 --- /dev/null +++ b/i18n/ar.toml @@ -0,0 +1,265 @@ +# Translations for Arabic +# الترجمة إلى العربية +# https://gohugo.io/content-management/multilingual/#translation-of-strings + +# === Init === +[init] +hugoVersionError = "إصدار Hugo منخفض جداً.\n\nالإصدار الحالي هو {{ .Current }}، والإصدار الأدنى المطلوب لـ FixIt هو {{ .Minimal }}.\n\nإذا كنت تستخدم Hugo على جهازك الشخصي، راجع https://gohugo.io/getting-started/installing/#upgrade-hugo لدليل الترقية.\n\nإذا كنت تستخدم Hugo على منصة طرف ثالث، يرجى تكوين إصدار Hugo وفقاً لذلك." +hugoExtendedWarn = "إصدار Hugo Extended مطلوب لدعم SCSS." +configurationError = "خطأ في التكوين\nلم تقم بتكوين معامل إصدار FixIt بشكل صحيح بعد. راجع https://fixit.lruihao.cn/docs/getting-started/configuration/params/" +compatibilityError = "خطأ في التوافق ({{ .From }} -> {{ .To }}):\nلديك تحديث غير متوافق. راجع https://github.com/hugo-fixit/FixIt/releases" +devVersionWarn = "أنت تستخدم إصدار تطوير من FixIt. يُرجى التفكير في استخدام إصدار مستقر.\nراجع https://github.com/hugo-fixit/FixIt/releases" +devEnvWarn = "البيئة الحالية هي \"development\". سيتم تعطيل \"نظام التعليقات\"، \"PWA\"، \"CDN\"، \"البصمة الرقمية\" و\"التحليلات\"." +quicklyUpgrade = "للترقية السريعة استخدم الأمر: " +# === Init === + +# === Base Layout === +[baseof] +backToTop = "العودة للأعلى" +viewComments = "عرض التعليقات" +noscript = "يعمل هذا الموقع بشكل أفضل مع تمكين JavaScript." +# === Base Layout === + +# === Taxonomy === +[archives] +other = "الأرشيف" + +[allSome] +other = "جميع {{ .Some }}" + +[category] +other = "التصنيف" + +[categories] +other = "التصنيفات" + +[collection] +other = "المجموعة" + +[collections] +other = "المجموعات" + +[tag] +other = "الوسم" + +[tags] +other = "الوسوم" + +[posts] +other = "المقالات" + +# === Taxonomy === + +# === Section === +[section] +recentlyUpdated = "تم التحديث مؤخراً" + +[section.totalWordCount] +one = "كلمة واحدة" +other = "{{ .Count }} كلمة" + +[section.archiveCounter] +one = "مقال واحد فقط" +other = "{{ .Count }} مقالة" +# === Section === + +# === Pagination === +[pagination] +more = "المزيد" +# === Pagination === + +# === Header === +[header] +selectLanguage = "اختر اللغة" +noTranslations = "لا توجد ترجمات" +switchTheme = "تغيير السمة" +# === Header === + +# === Footer === +[footer] +poweredBySome = "بدعم من {{ .Hugo }} | السمة - {{ .Theme }}" +siteUV = "إجمالي الزوار" +sitePV = "إجمالي الزيارات" +siteRunning = "الموقع يعمل منذ ..." +# === Footer === + +# === Comment === +[comment] +valinePlaceholder = "تعليقك ..." +# === Comment === + +# === Assets === +[assets] +search = "بحث" +searchPlaceholder = "ابحث في العناوين أو المحتوى ..." +searchIn = "ابحث في {{ . }}" +searchBy = "بحث بواسطة" +gotoResultsPage = "الذهاب إلى صفحة نتائج البحث ..." +clear = "مسح" +cancel = "إلغاء" +navigate = "تنقل" +select = "تحديد" +close = "إغلاق" +refresh = "تحديث" +noResultsFound = "لم يتم العثور على نتائج" +copyToClipboard = "نسخ إلى الحافظة" +copyText = "نسخ" +copiedText = "تم النسخ" +toggleLineNumbers = "إظهار/إخفاء أرقام الأسطر" +toggleLineWrap = "إظهار/إخفاء التفاف الأسطر" +toggleCodeEditable = "إظهار/إخفاء تحرير كتلة الكود" +downloadCode = "تحميل الكود" +expandCode = "توسيع أو طي كتلة الكود" +fullscreen = "ملء الشاشة" +exitFullscreen = "الخروج من ملء الشاشة" +cookieconsentMessage = "يستخدم هذا الموقع ملفات تعريف الارتباط لتحسين تجربتك." +cookieconsentDismiss = "فهمت!" +cookieconsentLink = "اعرف المزيد" +# === Assets === + +# === Share === +[shareOn] +other = "مشاركة على" +# === Share === + +# === Single Post === +[single] +contents = "المحتويات" +pin = "تثبيت في الأعلى" +repost = "إعادة النشر" +publishedOnDate = "نُشر في {{ .Date }}" +views = "مشاهدات" +comments = "تعليقات" +author = "المؤلف" +updatedOnDate = "تم التحديث في {{ .Date }}" +readMarkdown = "قراءة Markdown" +viewSource = "عرض المصدر" +editThisPage = "تعديل هذه الصفحة" +reportIssue = "الإبلاغ عن مشكلة" +openInEditor = "فتح في المحرر" +back = "رجوع" +home = "الرئيسية" +readMore = "اقرأ المزيد" +expirationReminder = "تم تحديث هذا المقال آخر مرة في {{ .Date }}، وقد يكون المحتوى قديماً." +encryptedAbstract = "تم تشفير هذا المقال، لذا المحتوى الأصلي غير مرئي!" +encryptedMessage = "يرجى إدخال كلمة المرور" +password = "كلمة المرور" +enterBtn = "دخول" +encryptyAgain = "تشفير مرة أخرى" +encryptionWarning = "تم اكتشاف تشفير المحتوى، لكنه لا يزال بنص عادي!" +encryptionCommand = "قم بتشغيل `npx @hugo-fixit/encrypt` بعد البناء لتشفيره فعلياً." +relatedContent = "محتوى ذي صلة" + +[single.includedIn] +categories = "مدرجة في {{ .Categories }}" +collections = "مدرجة في {{ .Collections }}" +both = "مدرجة في {{ .Categories }} و {{ .Collections }}" + +[single.wordCount] +one = "كلمة واحدة" +other = "{{ .Count }} كلمة" + +[single.fuzzyWordCount] +other = "حوالي {{ .Count }} كلمة" + +[single.readingTime] +one = "دقيقة واحدة" +other = "{{ .Count }} دقائق" + +[single.reward] +donate = "تبرع" +wechatpay = "WeChat Pay" +alipay = "Alipay" +paypal = "PayPal" +bitcoin = "Bitcoin" +# === Single Post === + +# === Error Pages === +[pageNotFound] +other = "الصفحة غير موجودة" + +[pageNotFoundText] +other = "الصفحة التي تبحث عنها غير موجودة. نعتذر عن ذلك." +# === Error Pages === + +# === Offline === +[offlineTitle] +other = "غير متصل" + +[offlineText] +other = "أنت غير متصل بالإنترنت، ستكون فقط الصفحات المخزنة مؤقتاً متاحة." +# === Offline === + +# === Service Worker === +[serviceWorker] +updateTitle = "تحديث متاح" +updateText = "يتوفر إصدار جديد من هذا الموقع." +# === Service Worker === + +# === Link Redirection === +[linkRedirection] +title = "إشعار إعادة التوجيه" +message = "أنت على وشك مغادرة {{ .Title }}، يرجى الانتباه إلى أمان حسابك وممتلكاتك." +confirm = "متابعة الزيارة" +# === Link Redirection === + +# === Alert === +[alert] +note = "ملاحظة" +tip = "نصيحة" +important = "مهم" +warning = "تحذير" +caution = "انتبه" +# === Alert === + +# === Task List === +[taskList] +x = "تم التحقق" +" " = "لم يتم التحقق" +"/" = "قيد التنفيذ" +"-" = "ملغى" +"<" = "مجدول" +">" = "أُعيد جدولته" +"!" = "مهم" +"!x" = "مهم - تم التحقق" +"?" = "سؤال" +# === Task List === + +# === Admonition === +[admonition] +note = "ملاحظة" +abstract = "ملخص" +info = "معلومات" +todo = "المهام" +tip = "نصيحة" +success = "نجاح" +question = "سؤال" +warning = "تحذير" +failure = "فشل" +danger = "خطر" +bug = "خلل" +example = "مثال" +quote = "اقتباس" +# === Admonition === + +# === Version === +[version] +new = "جديد" +changed = "تم التغيير" +deleted = "تم الحذف" +deprecated = "متقادم" +# === Version === + +# === Diagram === +[diagram] +zoomIn = "تكبير" +zoomOut = "تصغير" +reset = "إعادة تعيين" +download = "تحميل SVG" +# === Diagram === + +# === Tabs === +[tabs] +diagram = "مخطط" +code = "الكود" +# === Tabs === diff --git a/i18n/de.toml b/i18n/de.toml index 98b2cb9b..7563d475 100644 --- a/i18n/de.toml +++ b/i18n/de.toml @@ -70,7 +70,7 @@ more = "Mehr" # === Header === [header] selectLanguage = "Sprache wählen" -noMoretTranslations = "Keine weiteren Übersetzungen" +noTranslations = "Keine Übersetzungen" switchTheme = "Darstellung ändern" # === Header === diff --git a/i18n/en.toml b/i18n/en.toml index f8ebd430..c0b4cef7 100644 --- a/i18n/en.toml +++ b/i18n/en.toml @@ -70,7 +70,7 @@ more = "More" # === Header === [header] selectLanguage = "Select Language" -noMoretTranslations = "No more translations" +noTranslations = "No translations" switchTheme = "Switch Theme" # === Header === diff --git a/i18n/es.toml b/i18n/es.toml index f9062177..6775d501 100644 --- a/i18n/es.toml +++ b/i18n/es.toml @@ -70,7 +70,7 @@ more = "Más" # === Header === [header] selectLanguage = "Selecciona el lenguage" -noMoretTranslations = "No hay más traducciones" +noTranslations = "Sin traducciones" switchTheme = "Cambia el tema" # === Header === diff --git a/i18n/fa.toml b/i18n/fa.toml new file mode 100644 index 00000000..d70c3d28 --- /dev/null +++ b/i18n/fa.toml @@ -0,0 +1,265 @@ +# Translations for Persian +# ترجمه به فارسی +# https://gohugo.io/content-management/multilingual/#translation-of-strings + +# === Init === +[init] +hugoVersionError = "نسخه Hugo بسیار پایین است.\n\nنسخه فعلی Hugo {{ .Current }} است و حداقل نسخه پشتیبانی‌شده برای FixIt {{ .Minimal }} می‌باشد.\n\nاگر Hugo را روی رایانه شخصی خود اجرا می‌کنید، برای راهنمای ارتقا به https://gohugo.io/getting-started/installing/#upgrade-hugo مراجعه کنید.\n\nاگر از پلت‌فرم شخص ثالث استفاده می‌کنید، لطفاً نسخه Hugo را مطابق با آن پیکربندی کنید." +hugoExtendedWarn = "نسخه Extended Hugo برای پشتیبانی از SCSS ضروری است." +configurationError = "خطای پیکربندی\nشما هنوز پارامتر نسخه FixIt را به درستی پیکربندی نکرده‌اید. به https://fixit.lruihao.cn/docs/getting-started/configuration/params/ مراجعه کنید" +compatibilityError = "خطای سازگاری ({{ .From }} -> {{ .To }}):\nشما یک به‌روزرسانی ناسازگار دارید. به https://github.com/hugo-fixit/FixIt/releases مراجعه کنید" +devVersionWarn = "شما از نسخه توسعه FixIt استفاده می‌کنید. لطفاً از نسخه پایدار استفاده کنید.\nبه https://github.com/hugo-fixit/FixIt/releases مراجعه کنید" +devEnvWarn = "محیط فعلی «development» است. «سیستم نظرات»، «PWA»، «CDN»، «اثر انگشت» و «تحلیل‌ها» غیرفعال خواهند شد." +quicklyUpgrade = "ارتقاء سریع با دستور: " +# === Init === + +# === Base Layout === +[baseof] +backToTop = "بازگشت به بالا" +viewComments = "مشاهده نظرات" +noscript = "این وبسایت با فعال بودن JavaScript بهتر عمل می‌کند." +# === Base Layout === + +# === Taxonomy === +[archives] +other = "بایگانی" + +[allSome] +other = "همه {{ .Some }}" + +[category] +other = "دسته‌بندی" + +[categories] +other = "دسته‌بندی‌ها" + +[collection] +other = "مجموعه" + +[collections] +other = "مجموعه‌ها" + +[tag] +other = "برچسب" + +[tags] +other = "برچسب‌ها" + +[posts] +other = "نوشته‌ها" + +# === Taxonomy === + +# === Section === +[section] +recentlyUpdated = "به‌روزرسانی‌های اخیر" + +[section.totalWordCount] +one = "مجموع یک کلمه" +other = "مجموع {{ .Count }} کلمه" + +[section.archiveCounter] +one = "فقط یک مقاله" +other = "مجموعاً {{ .Count }} مقاله" +# === Section === + +# === Pagination === +[pagination] +more = "بیشتر" +# === Pagination === + +# === Header === +[header] +selectLanguage = "انتخاب زبان" +noTranslations = "ترجمه‌ای موجود نیست" +switchTheme = "تغییر پوسته" +# === Header === + +# === Footer === +[footer] +poweredBySome = "قدرت‌گرفته از {{ .Hugo }} | پوسته - {{ .Theme }}" +siteUV = "مجموع بازدیدکنندگان" +sitePV = "مجموع بازدیدها" +siteRunning = "وبسایت در حال اجرا ..." +# === Footer === + +# === Comment === +[comment] +valinePlaceholder = "نظر شما ..." +# === Comment === + +# === Assets === +[assets] +search = "جستجو" +searchPlaceholder = "جستجوی عناوین یا محتوا ..." +searchIn = "جستجو در {{ . }}" +searchBy = "جستجو بر اساس" +gotoResultsPage = "رفتن به صفحه نتایج جستجو ..." +clear = "پاک کردن" +cancel = "لغو" +navigate = "پیمایش" +select = "انتخاب" +close = "بستن" +refresh = "بازخوانی" +noResultsFound = "نتیجه‌ای یافت نشد" +copyToClipboard = "کپی در کلیپ‌بورد" +copyText = "کپی" +copiedText = "کپی شد" +toggleLineNumbers = "نمایش/مخفی کردن شماره خطوط" +toggleLineWrap = "نمایش/مخفی کردن پیچش کد" +toggleCodeEditable = "قابل ویرایش کردن بلوک کد" +downloadCode = "دانلود کد" +expandCode = "باز کردن یا بستن بلوک کد" +fullscreen = "تمام‌صفحه" +exitFullscreen = "خروج از تمام‌صفحه" +cookieconsentMessage = "این وبسایت از کوکی‌ها برای بهبود تجربه شما استفاده می‌کند." +cookieconsentDismiss = "متوجه شدم!" +cookieconsentLink = "اطلاعات بیشتر" +# === Assets === + +# === Share === +[shareOn] +other = "اشتراک‌گذاری در" +# === Share === + +# === Single Post === +[single] +contents = "فهرست مطالب" +pin = "سنجاق کردن به بالا" +repost = "بازنشر" +publishedOnDate = "منتشر شده در {{ .Date }}" +views = "بازدید" +comments = "نظرات" +author = "نویسنده" +updatedOnDate = "به‌روزرسانی شده در {{ .Date }}" +readMarkdown = "خواندن Markdown" +viewSource = "مشاهده سورس" +editThisPage = "ویرایش این صفحه" +reportIssue = "گزارش مشکل" +openInEditor = "باز کردن در ویرایشگر" +back = "بازگشت" +home = "خانه" +readMore = "ادامه مطلب" +expirationReminder = "این مقاله آخرین بار در {{ .Date }} به‌روزرسانی شده است و ممکن است محتوای آن قدیمی باشد." +encryptedAbstract = "این مقاله رمزنگاری شده است، بنابراین محتوای خام آن قابل مشاهده نیست!" +encryptedMessage = "لطفاً رمز عبور را وارد کنید" +password = "رمز عبور" +enterBtn = "ورود" +encryptyAgain = "رمزنگاری مجدد" +encryptionWarning = "رمزنگاری محتوا شناسایی شد، اما هنوز به صورت متن ساده هستند!" +encryptionCommand = "پس از ساخت، دستور `npx @hugo-fixit/encrypt` را اجرا کنید تا واقعاً رمزنگاری شوند." +relatedContent = "مطالب مرتبط" + +[single.includedIn] +categories = "قرار گرفته در {{ .Categories }}" +collections = "قرار گرفته در {{ .Collections }}" +both = "قرار گرفته در {{ .Categories }} و {{ .Collections }}" + +[single.wordCount] +one = "یک کلمه" +other = "{{ .Count }} کلمه" + +[single.fuzzyWordCount] +other = "حدود {{ .Count }} کلمه" + +[single.readingTime] +one = "یک دقیقه" +other = "{{ .Count }} دقیقه" + +[single.reward] +donate = "حمایت مالی" +wechatpay = "WeChat Pay" +alipay = "Alipay" +paypal = "PayPal" +bitcoin = "Bitcoin" +# === Single Post === + +# === Error Pages === +[pageNotFound] +other = "صفحه یافت نشد" + +[pageNotFoundText] +other = "صفحه‌ای که به دنبال آن هستید وجود ندارد. متأسفیم." +# === Error Pages === + +# === Offline === +[offlineTitle] +other = "آفلاین" + +[offlineText] +other = "شما به اینترنت متصل نیستید، فقط صفحات ذخیره‌شده در دسترس خواهند بود." +# === Offline === + +# === Service Worker === +[serviceWorker] +updateTitle = "به‌روزرسانی موجود است" +updateText = "نسخه جدیدی از این سایت موجود است." +# === Service Worker === + +# === Link Redirection === +[linkRedirection] +title = "اعلامیه تغییر مسیر" +message = "شما در حال ترک {{ .Title }} هستید، لطفاً از امنیت حساب و دارایی خود اطمینان حاصل کنید." +confirm = "ادامه بازدید" +# === Link Redirection === + +# === Alert === +[alert] +note = "توجه" +tip = "نکته" +important = "مهم" +warning = "هشدار" +caution = "احتیاط" +# === Alert === + +# === Task List === +[taskList] +x = "تیک‌خورده" +" " = "بدون تیک" +"/" = "در حال انجام" +"-" = "لغو شده" +"<" = "برنامه‌ریزی شده" +">" = "برنامه‌ریزی مجدد شده" +"!" = "مهم" +"!x" = "مهم تیک‌خورده" +"?" = "سوال" +# === Task List === + +# === Admonition === +[admonition] +note = "توجه" +abstract = "چکیده" +info = "اطلاعات" +todo = "انجام دادنی" +tip = "نکته" +success = "موفقیت" +question = "سوال" +warning = "هشدار" +failure = "شکست" +danger = "خطر" +bug = "خطا" +example = "مثال" +quote = "نقل‌قول" +# === Admonition === + +# === Version === +[version] +new = "جدید" +changed = "تغییر یافته" +deleted = "حذف شده" +deprecated = "منسوخ شده" +# === Version === + +# === Diagram === +[diagram] +zoomIn = "بزرگ‌نمایی" +zoomOut = "کوچک‌نمایی" +reset = "بازنشانی" +download = "دانلود SVG" +# === Diagram === + +# === Tabs === +[tabs] +diagram = "نمودار" +code = "کد" +# === Tabs === diff --git a/i18n/fr.toml b/i18n/fr.toml index bc73933e..ae6c46b3 100644 --- a/i18n/fr.toml +++ b/i18n/fr.toml @@ -70,7 +70,7 @@ more = "Plus" # === Header === [header] selectLanguage = "Choisir la langue" -noMoretTranslations = "Plus de traductions" +noTranslations = "Aucune traduction" switchTheme = "Changer de Thème" # === Header === diff --git a/i18n/hi.toml b/i18n/hi.toml index ca1e509b..c827648a 100644 --- a/i18n/hi.toml +++ b/i18n/hi.toml @@ -71,7 +71,7 @@ more = "और देखें" # === Header === [header] selectLanguage = "भाषा चुने" -noMoretTranslations = "कोई और अनुवाद नहीं" +noTranslations = "कोई अनुवाद नहीं" switchTheme = "थीम बदलें" # === Header === diff --git a/i18n/it.toml b/i18n/it.toml index 326f3ab5..b8bc9745 100644 --- a/i18n/it.toml +++ b/i18n/it.toml @@ -70,7 +70,7 @@ more = "Più" # === Header === [header] selectLanguage = "Scegliere la lingua" -noMoretTranslations = "Non ci sono altre traduzioni" +noTranslations = "Nessuna traduzione" switchTheme = "Cambiare il tema" # === Header === diff --git a/i18n/ja.toml b/i18n/ja.toml index 0e9d4252..85bed649 100644 --- a/i18n/ja.toml +++ b/i18n/ja.toml @@ -68,7 +68,7 @@ more = "もっと見る" # === Header === [header] selectLanguage = "言語を選択" -noMoretTranslations = "これ以上の翻訳はありません" +noTranslations = "翻訳なし" switchTheme = "テーマを切り替え" # === Header === diff --git a/i18n/ko.toml b/i18n/ko.toml index 733aa1d9..58e6c3a6 100644 --- a/i18n/ko.toml +++ b/i18n/ko.toml @@ -68,7 +68,7 @@ more = "더 보기" # === Header === [header] selectLanguage = "언어 선택" -noMoretTranslations = "더 이상 번역이 없습니다" +noTranslations = "번역 없음" switchTheme = "테마 전환" # === Header === diff --git a/i18n/pl.toml b/i18n/pl.toml index 730a90fa..f75c207f 100644 --- a/i18n/pl.toml +++ b/i18n/pl.toml @@ -70,7 +70,7 @@ more = "Więcej" # === Header === [header] selectLanguage = "Wybierz język" -noMoretTranslations = "Brak dalszych tłumaczeń" +noTranslations = "Brak tłumaczeń" switchTheme = "Przełącz schemat" # === Header === diff --git a/i18n/pt-BR.toml b/i18n/pt-BR.toml index cf7ecd2b..74f33bdf 100644 --- a/i18n/pt-BR.toml +++ b/i18n/pt-BR.toml @@ -71,7 +71,7 @@ more = "Mais" # === Header === [header] selectLanguage = "Selecione o idioma" -noMoretTranslations = "Não há mais traduções" +noTranslations = "Sem traduções" switchTheme = "Trocar tema" # === Header === diff --git a/i18n/ro.toml b/i18n/ro.toml index 8771dd8f..4bc5fde6 100644 --- a/i18n/ro.toml +++ b/i18n/ro.toml @@ -70,7 +70,7 @@ more = "Mai mult" # === Header === [header] selectLanguage = "Selectare Limbă" -noMoretTranslations = "Nu mai sunt traduceri disponibile" +noTranslations = "Fără traduceri" switchTheme = "Schimbare Temă" # === Header === diff --git a/i18n/ru.toml b/i18n/ru.toml index 45270088..97e90c30 100644 --- a/i18n/ru.toml +++ b/i18n/ru.toml @@ -70,7 +70,7 @@ more = "Больше" # === Header === [header] selectLanguage = "Выбор Языка" -noMoretTranslations = "Нет больше переводов" +noTranslations = "Нет переводов" switchTheme = "Сменить Тему" # === Header === diff --git a/i18n/sr.toml b/i18n/sr.toml index 8a24b3e3..5bc3be98 100644 --- a/i18n/sr.toml +++ b/i18n/sr.toml @@ -70,7 +70,7 @@ more = "Више" # === Header === [header] selectLanguage = "Изабери Језик" -noMoretTranslations = "Нема више превода" +noTranslations = "Нема превода" switchTheme = "Промени Тему" # === Header === diff --git a/i18n/ur.toml b/i18n/ur.toml new file mode 100644 index 00000000..195b3979 --- /dev/null +++ b/i18n/ur.toml @@ -0,0 +1,265 @@ +# Translations for Urdu +# اردو ترجمے +# https://gohugo.io/content-management/multilingual/#translation-of-strings + +# === Init === +[init] +hugoVersionError = "Hugo ورژن بہت پرانا ہے۔\n\nموجودہ ورژن {{ .Current }} ہے، اور FixIt کے لیے کم از کم ورژن {{ .Minimal }} درکار ہے۔\n\nاگر آپ Hugo کو ذاتی طور پر استعمال کرتے ہیں، تو اپ گریڈ کے لیے https://hugo-hugo.io/getting-started/installing/#upgrade-hugo دیکھیں۔\n\nاگر آپ کسی تیسرے فریق پلیٹ فارم پر Hugo استعمال کرتے ہیں، تو براہ کرم Hugo ورژن کو اس کے مطابق ترتیب دیں۔" +hugoExtendedWarn = "SCSS سپورٹ کے لیے Hugo Extended درکار ہے۔" +configurationError = "ترتیب میں خرابی\nآپ نے ابھی تک FixIt ورژن پیرامیٹر کو صحیح طریقے سے ترتیب نہیں دیا ہے۔ https://fixit.lruihao.cn/docs/getting-started/configuration/params/ دیکھیں" +compatibilityError = "مطابقت پذیری کی خرابی ({{ .From }} -> {{ .To }}):\nآپ کے پاس غیر مطابقت پذیر اپ ڈیٹ ہے۔ https://github.com/hugo-fixit/FixIt/releases دیکھیں" +devVersionWarn = "آپ FixIt کا ڈیولپمنٹ ورژن استعمال کر رہے ہیں۔ براہ کرم مستقر ورژن استعمال کرنے پر غور کریں۔\nhttps://github.com/hugo-fixit/FixIt/releases دیکھیں" +devEnvWarn = "موجودہ ماحول \"development\" ہے۔ \"تبصرہ نظام\"، \"PWA\"، \"CDN\"، \"ڈیجٹل فنگر پرنٹ\" اور \"تجزیات\" غیر فعال ہو جائیں گے۔" +quicklyUpgrade = "تیزی سے اپ گریڈ کرنے کے لیے کمانڈ استعمال کریں: " +# === Init === + +# === Base Layout === +[baseof] +backToTop = "اوپر واپس جائیں" +viewComments = "تبصرے دیکھیں" +noscript = "یہ ویب سائٹ JavaScript فعال ہونے پر بہتر کام کرتی ہے۔" +# === Base Layout === + +# === Taxonomy === +[archives] +other = "آرکائیو" + +[allSome] +other = "تمام {{ .Some }}" + +[category] +other = "زمرہ" + +[categories] +other = "زمرے" + +[collection] +other = "مجموعہ" + +[collections] +other = "مجموعے" + +[tag] +other = "ٹیگ" + +[tags] +other = "ٹیگز" + +[posts] +other = "مضامین" + +# === Taxonomy === + +# === Section === +[section] +recentlyUpdated = "حال ہی میں اپ ڈیٹ کیا گیا" + +[section.totalWordCount] +one = "ایک لفظ" +other = "{{ .Count }} الفاظ" + +[section.archiveCounter] +one = "صرف ایک مضمون" +other = "{{ .Count }} مضامین" +# === Section === + +# === Pagination === +[pagination] +more = "مزید" +# === Pagination === + +# === Header === +[header] +selectLanguage = "زبان منتخب کریں" +noTranslations = "ترجمے نہیں" +switchTheme = "تھیم تبدیل کریں" +# === Header === + +# === Footer === +[footer] +poweredBySome = "{{ .Hugo }} سے چلتا ہے | تھیم - {{ .Theme }}" +siteUV = "کل زائرین" +sitePV = "کل ملاقاتیں" +siteRunning = "سائٹ چل رہی ہے ..." +# === Footer === + +# === Comment === +[comment] +valinePlaceholder = "آپ کا تبصرہ ..." +# === Comment === + +# === Assets === +[assets] +search = "تلاش" +searchPlaceholder = "عنوان یا مواد میں تلاش کریں ..." +searchIn = "{{ . }} میں تلاش کریں" +searchBy = "تلاش بذریعہ" +gotoResultsPage = "تلاش کے نتائج کے صفحے پر جائیں ..." +clear = "صاف کریں" +cancel = "منسوخ" +navigate = "نیویگیٹ" +select = "منتخب کریں" +close = "بند کریں" +refresh = "ریفریش" +noResultsFound = "کوئی نتائج نہیں ملے" +copyToClipboard = "کلپ بورڈ پر کاپی کریں" +copyText = "کاپی" +copiedText = "کاپی ہو گیا" +toggleLineNumbers = "سطر نمبر دکھائیں/چھپائیں" +toggleLineWrap = "سطر ریپ دکھائیں/چھپائیں" +toggleCodeEditable = "کوڈ بلاک میں ترمیم دکھائیں/چھپائیں" +downloadCode = "کوڈ ڈاؤن لوڈ کریں" +expandCode = "کوڈ بلاک کو بڑا کریں یا سکیڑیں" +fullscreen = "فل اسکرین" +exitFullscreen = "فل اسکرین سے باہر نکلیں" +cookieconsentMessage = "یہ ویب سائٹ آپ کے تجربے کو بہتر بنانے کے لیے کوکیز استعمال کرتی ہے۔" +cookieconsentDismiss = "سمجھ گیا!" +cookieconsentLink = "مزید جانیں" +# === Assets === + +# === Share === +[shareOn] +other = "پر شیئر کریں" +# === Share === + +# === Single Post === +[single] +contents = "مواد" +pin = "اوپر پن کریں" +repost = "دوبارہ شائع کریں" +publishedOnDate = "{{ .Date }} کو شائع ہوا" +views = "مناظر" +comments = "تبصرے" +author = "مصنف" +updatedOnDate = "{{ .Date }} کو اپ ڈیٹ کیا گیا" +readMarkdown = "مارک ڈاؤن پڑھیں" +viewSource = "ذریعہ دیکھیں" +editThisPage = "اس صفحے میں ترمیم کریں" +reportIssue = "مسئلہ رپورٹ کریں" +openInEditor = "ایڈیٹر میں کھولیں" +back = "واپس" +home = "ہوم" +readMore = "مزید پڑھیں" +expirationReminder = "اس مضمون کو آخری بار {{ .Date }} کو اپ ڈیٹ کیا گیا تھا، اور مواد پرانا ہو سکتا ہے۔" +encryptedAbstract = "اس مضمون کو انکرپٹ کیا گیا ہے، اس لیے اصل مواد نظر نہیں آتا!" +encryptedMessage = "براہ کرم پاس ورڈ درج کریں" +password = "پاس ورڈ" +enterBtn = "داخل ہوں" +encryptyAgain = "دوبارہ انکرپٹ کریں" +encryptionWarning = "مواد کی انکرپشن کا پتہ چلا، لیکن یہ ابھی بھی سادہ متن میں ہے!" +encryptionCommand = "انکرپشن کے لیے بلڈ کے بعد `npx @hugo-fixit/encrypt` چلائیں۔" +relatedContent = "متعلقہ مواد" + +[single.includedIn] +categories = "{{ .Categories }} میں شامل" +collections = "{{ .Collections }} میں شامل" +both = "{{ .Categories }} اور {{ .Collections }} میں شامل" + +[single.wordCount] +one = "ایک لفظ" +other = "{{ .Count }} الفاظ" + +[single.fuzzyWordCount] +other = "تقریباً {{ .Count }} الفاظ" + +[single.readingTime] +one = "ایک منٹ" +other = "{{ .Count }} منٹ" + +[single.reward] +donate = "عطیہ دیں" +wechatpay = "WeChat Pay" +alipay = "Alipay" +paypal = "PayPal" +bitcoin = "Bitcoin" +# === Single Post === + +# === Error Pages === +[pageNotFound] +other = "صفحہ نہیں ملا" + +[pageNotFoundText] +other = "آپ جو صفحہ تلاش کر رہے ہیں وہ موجود نہیں ہے۔ ہم معذرت خواہ ہیں۔" +# === Error Pages === + +# === Offline === +[offlineTitle] +other = "آف لائن" + +[offlineText] +other = "آپ آف لائن ہیں، صرف وہی صفحات دستیاب ہوں گے جو کیشے میں ہیں۔" +# === Offline === + +# === Service Worker === +[serviceWorker] +updateTitle = "اپ ڈیٹ دستیاب" +updateText = "اس ویب سائٹ کا نیا ورژن دستیاب ہے۔" +# === Service Worker === + +# === Link Redirection === +[linkRedirection] +title = "ری ڈائریکشن نوٹس" +message = "آپ {{ . Title }} چھوڑنے والے ہیں، براہ کرم اپنے اکاؤنٹ اور اثاثوں کی حفاظت پر توجہ دیں۔" +confirm = "دورے کو جاری رکھیں" +# === Link Redirection === + +# === Alert === +[alert] +note = "نوٹ" +tip = "ٹپ" +important = "اہم" +warning = "انتباہ" +caution = "احتیاط" +# === Alert === + +# === Task List === +[taskList] +x = "تصدیق ہو گئی" +" " = "تصدیق نہیں ہوئی" +"/" = "جاری ہے" +"-" = "منسوخ" +"<" = "شیڈول کیا گیا" +">" = "دوبارہ شیڈول کیا گیا" +"!" = "اہم" +"!x" = "اہم - تصدیق ہو گئی" +"?" = "سوال" +# === Task List === + +# === Admonition === +[admonition] +note = "نوٹ" +abstract = "خلاصہ" +info = "معلومات" +todo = "ٹو ڈو" +tip = "ٹپ" +success = "کامیابی" +question = "سوال" +warning = "انتباہ" +failure = "ناکامی" +danger = "خطرہ" +bug = "بگ" +example = "مثال" +quote = "اقتباس" +# === Admonition === + +# === Version === +[version] +new = "نیا" +changed = "تبدیل" +deleted = "حذف" +deprecated = "منسوخ" +# === Version === + +# === Diagram === +[diagram] +zoomIn = "زوم ان" +zoomOut = "زوم آؤٹ" +reset = "ری سیٹ" +download = "SVG ڈاؤن لوڈ" +# === Diagram === + +# === Tabs === +[tabs] +diagram = "ڈائیگرام" +code = "کوڈ" +# === Tabs === diff --git a/i18n/vi.toml b/i18n/vi.toml index 2ee2b7c5..0af35d70 100644 --- a/i18n/vi.toml +++ b/i18n/vi.toml @@ -69,7 +69,7 @@ more = "Thêm" # === Header === [header] selectLanguage = "Chọn Ngôn ngữ" -noMoretTranslations = "Không có nữa" +noTranslations = "Không có bản dịch" switchTheme = "Đổi chủ đề" # === Header === diff --git a/i18n/zh-CN.toml b/i18n/zh-CN.toml index befa7f68..e41f4043 100644 --- a/i18n/zh-CN.toml +++ b/i18n/zh-CN.toml @@ -68,7 +68,7 @@ more = "更多" # === Header === [header] selectLanguage = "选择语言" -noMoretTranslations = "没有更多翻译" +noTranslations = "无翻译" switchTheme = "切换主题" # === Header === diff --git a/i18n/zh-TW.toml b/i18n/zh-TW.toml index 4fb7de31..b862967e 100644 --- a/i18n/zh-TW.toml +++ b/i18n/zh-TW.toml @@ -68,7 +68,7 @@ more = "更多" # === Header === [header] selectLanguage = "選擇語言" -noMoretTranslations = "沒有更多翻譯" +noTranslations = "無翻譯" switchTheme = "切換主題" # === Header === diff --git a/layouts/_partials/base/header.html b/layouts/_partials/base/header.html index f02f564c..c03a5bfa 100644 --- a/layouts/_partials/base/header.html +++ b/layouts/_partials/base/header.html @@ -18,10 +18,11 @@ */ -}} {{- $menuDraft := getenv "HUGO_PARAMS_MENU_DRAFT" -}} {{- $relLangURL := relLangURL "" -}} +{{- $githubCornerPosition := .Site.Params.github_corner.position | default "end" | partial "function/logical-direction.html" -}} {{- /* Desktop header */ -}}
-
+
{{- with .Site.Params.header.title -}} @@ -157,7 +158,7 @@ {{- end -}} {{- else -}} - + {{- end -}} @@ -311,7 +312,7 @@ {{- end -}} {{- else -}} - + {{- end -}} diff --git a/layouts/_partials/base/widgets.html b/layouts/_partials/base/widgets.html index 044d05bb..6142ed52 100644 --- a/layouts/_partials/base/widgets.html +++ b/layouts/_partials/base/widgets.html @@ -49,13 +49,14 @@ {{- $githubCorner := .Site.Params.github_corner -}} {{- if $githubCorner.enable -}} {{- with $githubCorner -}} + {{- $position := .Position | default "end" | partial "function/logical-direction.html" -}} {{- $githubImage := `` -}} - {{- $options := dict "Destination" .Permalink "Title" .Title "Content" $githubImage "ExternalIcon" false "Class" (cond (eq .Position "left") "left" "right" | printf "github-corner %v max-sm:hidden") "Noreferrer" false -}} + {{- $options := dict "Destination" .Permalink "Title" .Title "Content" $githubImage "ExternalIcon" false "Class" (printf "github-corner %v max-sm:hidden" $position) "Noreferrer" false -}} {{- partial "plugin/link.html" $options -}} {{- end -}} {{- end -}} - {{- /* Search mask */ -}} + {{- /* Header mobile mask */ -}}
{{- /* Search dialog */ -}} @@ -105,7 +106,7 @@ {{- $readingProgress := .Site.Params.reading_progress -}} {{- if $readingProgress.enable -}} {{- with $readingProgress -}} - {{- $style := printf "%v: 0;%v: 0;" (.Start | default "left") (.Position | default "top") -}} + {{- $style := printf "inset-inline-%v: 0;%v: 0;" (.Start | default "start" | partial "function/logical-direction.html") (.Position | default "top") -}} {{- if .Height | and (ne .Height "2px") -}} {{- $style = printf "%v--fi-progress-h: %v;" $style .Height -}} {{- end -}} diff --git a/layouts/_partials/function/logical-direction.html b/layouts/_partials/function/logical-direction.html new file mode 100644 index 00000000..68031836 --- /dev/null +++ b/layouts/_partials/function/logical-direction.html @@ -0,0 +1,13 @@ +{{- /* + Normalize a direction value to CSS logical direction. + + Converts legacy "left"/"right" values to "start"/"end". + Valid values ("start"/"end") are returned as-is. + + @param {String} value - The direction value to normalize ("left", "right", "start", "end") + @return {String} The normalized logical direction ("start" or "end"), defaults to "start" for unknown values +*/ -}} + +{{- $aliases := dict "left" "start" "right" "end" "start" "start" "end" "end" -}} +{{- $value := . | lower -}} +{{- return (index $aliases $value | default "start") -}} diff --git a/layouts/_partials/init/detection-deprecated.html b/layouts/_partials/init/detection-deprecated.html index 2559108e..106c085d 100644 --- a/layouts/_partials/init/detection-deprecated.html +++ b/layouts/_partials/init/detection-deprecated.html @@ -125,6 +125,25 @@ {{- $warns = $warns | append "The file `assets/scss/override.scss` is deprecated. Use `[params.appearance]` in your site configuration instead. See: https://fixit.lruihao.cn/docs/advanced/" -}} {{- end -}} +{{- /* Deprecated "left"/"right" position values → "start"/"end" */ -}} +{{- $positionParams := dict + "github_corner" (slice "position") + "toc" (slice "position") + "reading_progress" (slice "start") +-}} +{{- range $section, $keys := $positionParams -}} + {{- $sec := index $.Site.Params $section -}} + {{- if reflect.IsMap $sec -}} + {{- range $keys -}} + {{- $val := index $sec . -}} + {{- if or (eq $val "left") (eq $val "right") -}} + {{- $newVal := cond (eq $val "left") "start" "end" -}} + {{- $warns = $warns | append (printf "The value \"%v\" of `params.%v.%v` is deprecated, use \"%v\" instead." $val $section . $newVal) -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} + {{- if fileExists "assets/css/_variables.scss" -}} {{- $warns = $warns | append "The file `assets/css/_variables.scss` is deprecated. Please move your variables to `assets/scss/_variables.scss`. See: https://fixit.lruihao.cn/docs/advanced/" -}} {{- end -}} diff --git a/layouts/_partials/plugin/admonition.html b/layouts/_partials/plugin/admonition.html index ddf5e092..ae687a5b 100644 --- a/layouts/_partials/plugin/admonition.html +++ b/layouts/_partials/plugin/admonition.html @@ -11,7 +11,7 @@ */ -}} {{- $iconMap := dict - "note" "fa-solid fa-pencil-alt" + "note" "fa-solid fa-pencil" "abstract" "fa-solid fa-clipboard-list" "info" "fa-solid fa-circle-info" "todo" "fa-solid fa-list-check" @@ -45,7 +45,7 @@ -}} {{- $type := .Type | lower -}} {{- $type = index $aliasMap $type | default $type | default "note" -}} -{{- $icon := index $iconMap $type | default "fa-solid fa-pencil-alt" -}} +{{- $icon := index $iconMap $type | default "fa-solid fa-pencil" -}} {{- $title := .Title | default (T (printf "admonition.%v" $type)) | default (title $type) -}} {{- $titleless := eq .Title "~" -}} {{- $foldable := ne .Foldable false -}} diff --git a/layouts/_partials/section/recently-updated.html b/layouts/_partials/section/recently-updated.html index 3f92ae8a..d2fde9aa 100644 --- a/layouts/_partials/section/recently-updated.html +++ b/layouts/_partials/section/recently-updated.html @@ -37,7 +37,7 @@
{{- $repost := .Params.repost | default dict -}} {{- if eq $repost.enable true -}} - {{- dict "Class" "fa-solid fa-share text-success me-1" | partial "plugin/icon.html" -}} + {{- dict "Class" "fa-solid fa-retweet text-success me-1" | partial "plugin/icon.html" -}} {{- end -}} {{- if eq $scope "archives" -}} {{- cond (.Param "capitalize_titles") (title .Title) .Title -}} diff --git a/layouts/_partials/single/collection-list.html b/layouts/_partials/single/collection-list.html index 6c663255..5dba1152 100644 --- a/layouts/_partials/single/collection-list.html +++ b/layouts/_partials/single/collection-list.html @@ -5,7 +5,9 @@ {{- $pages := (where .Pages "Params.Weight" "!=" nil) | append (where .Pages "Params.Weight" "eq" nil).ByDate -}} {{- $open := eq (index $collectionTerms 0) . -}} {{- $currentKey := 0 -}} - + {{- if lt $pages.Len 2 -}} + {{- continue -}} + {{- end -}}
{{ dict "Class" "fa-solid fa-layer-group" | partial "plugin/icon.html" }} diff --git a/layouts/_partials/single/collection-nav.html b/layouts/_partials/single/collection-nav.html index 227edbea..8f7ac4f5 100644 --- a/layouts/_partials/single/collection-nav.html +++ b/layouts/_partials/single/collection-nav.html @@ -8,6 +8,9 @@ (T "collection") .LinkTitle -}} + {{- if lt .Pages.Len 2 -}} + {{- continue -}} + {{- end -}}
{{- dict "Collections" $termLink | T "single.includedIn.collections" | strings.FirstUpper | safeHTML }} {{ .Pages.Len -}} diff --git a/layouts/_partials/single/expiration-reminder.html b/layouts/_partials/single/expiration-reminder.html index a347f84e..8dff1aca 100644 --- a/layouts/_partials/single/expiration-reminder.html +++ b/layouts/_partials/single/expiration-reminder.html @@ -16,7 +16,7 @@ {{- if gt $daysAgo $reminderThreshold -}} {{- $type := "note" -}} - {{- $icon := "fa-pencil-alt" -}} + {{- $icon := "fa-pencil" -}} {{- if gt $daysAgo $warningThreshold -}} {{- $type = "warning" -}} {{- $icon = "fa-exclamation-triangle" -}} diff --git a/layouts/_shortcodes/tabs.html b/layouts/_shortcodes/tabs.html index 06f9a110..0647e870 100644 --- a/layouts/_shortcodes/tabs.html +++ b/layouts/_shortcodes/tabs.html @@ -4,7 +4,7 @@ @param {Int} [defaultTab=0] - The index of the tab to be active by default (0-based) @param {String} [type="underline"] - The style type of the tabs ("underline", "pill", "card", "segment", etc.) - @param {String} [placement="top"] - The placement of the tabs ("top", "bottom", "left", "right") + @param {String} [placement="top"] - The placement of the tabs ("top", "bottom", "start", "end") Usage: {{< tabs defaultTab="1" type="card" placement="top" >}} @@ -28,8 +28,14 @@ {{- $lenTabs := len $tabs -}} {{- $defaultTab := .Get "defaultTab" | default 0 -}} {{- $type := .Get "type" | default "underline" -}} -{{- $placement := .Get "placement" | default "top" -}} -{{- $placementMap := slice "top" "bottom" "left" "right" -}} +{{- $placementRaw := .Get "placement" | default "top" -}} +{{- $placement := $placementRaw -}} +{{- if or (eq $placementRaw "left") (eq $placementRaw "right") -}} + {{- $newVal := cond (eq $placementRaw "left") "start" "end" -}} + {{- warnf "The placement value %q is deprecated, use %q instead. See %s %s" $placementRaw $newVal .Name .Position -}} + {{- $placement = $newVal -}} +{{- end -}} +{{- $placementMap := slice "top" "bottom" "start" "end" -}} {{- if ge $defaultTab $lenTabs -}} {{- warnf "The defaultTab value %v is out of range [0, %v]. See %s %s" $defaultTab (sub $lenTabs 1) .Name .Position -}} {{- $defaultTab = 0 -}} diff --git a/layouts/baseof.html b/layouts/baseof.html index 73232103..efcbfe18 100644 --- a/layouts/baseof.html +++ b/layouts/baseof.html @@ -1,7 +1,7 @@ {{- partial "init/index.html" . -}} - + {{- if .IsHome | and (ne .Site.Params.disable_theme_inject true) }} @@ -17,7 +17,8 @@ {{- partial "base/header.html" . -}} {{- partial "base/breadcrumb.html" . -}} {{- $toc := dict "Page" .Page "Key" "toc" | partial "function/param.html" -}} -
+ {{- $tocPosition := $toc.position | default "end" | partial "function/logical-direction.html" -}} +
{{- block "content" . }}{{ end -}}
{{- /* Comment */ -}} diff --git a/layouts/home.archives.html b/layouts/home.archives.html index fdcf4f1b..b36a2c2a 100644 --- a/layouts/home.archives.html +++ b/layouts/home.archives.html @@ -50,7 +50,7 @@
{{- $repost := .Params.repost | default dict -}} {{- if eq $repost.enable true -}} - {{- dict "Class" "fa-solid fa-share text-success me-1" | partial "plugin/icon.html" -}} + {{- dict "Class" "fa-solid fa-retweet text-success me-1" | partial "plugin/icon.html" -}} {{- end -}} {{- /* Use the original title after archiving the articles */ -}} {{- cond (.Param "capitalize_titles") (title .Title) .Title -}} diff --git a/layouts/posts/single.html b/layouts/posts/single.html index 21b9835d..7d06a921 100644 --- a/layouts/posts/single.html +++ b/layouts/posts/single.html @@ -30,7 +30,7 @@ {{- $repost := .Params.repost | default dict -}} {{- with $repost -}} {{- if eq .Enable true -}} - {{- $icon := dict "Class" "fa-solid fa-share" -}} + {{- $icon := dict "Class" "fa-solid fa-retweet" -}} {{- $iconTitle := cond (hasPrefix .Url "http") (printf "%v -> %v" (T "single.repost") .Url ) (T "single.repost") -}} {{- if hasPrefix .Url "http" -}} {{ dict "Destination" .Url "Icon" $icon "Class" "icon-repost" "Title" $iconTitle "ExternalIcon" false | partial "plugin/link.html" -}} @@ -70,7 +70,7 @@ {{- end -}} {{- if .Param "word_count" -}} - {{- dict "Class" "fa-solid fa-pencil-alt me-1" | partial "plugin/icon.html" -}} + {{- dict "Class" "fa-solid fa-pencil me-1" | partial "plugin/icon.html" -}} {{- T "single.fuzzyWordCount" .FuzzyWordCount -}}   {{- end -}} diff --git a/layouts/section.html b/layouts/section.html index e46dd272..5c87f543 100644 --- a/layouts/section.html +++ b/layouts/section.html @@ -51,7 +51,7 @@ {{- $repost := .Params.repost | default dict -}} {{- if eq $repost.enable true -}} - {{- dict "Class" "fa-solid fa-share text-success me-1" | partial "plugin/icon.html" -}} + {{- dict "Class" "fa-solid fa-retweet text-success me-1" | partial "plugin/icon.html" -}} {{- end -}} {{- cond (.Param "capitalize_titles") (title .LinkTitle) .LinkTitle -}} diff --git a/layouts/summary.html b/layouts/summary.html index bd2e53a6..942a9ffd 100644 --- a/layouts/summary.html +++ b/layouts/summary.html @@ -25,7 +25,7 @@ {{- $repost := .Params.repost | default dict -}} {{- with $repost -}} {{- if eq .Enable true -}} - {{- $icon := dict "Class" "fa-solid fa-share" -}} + {{- $icon := dict "Class" "fa-solid fa-retweet" -}} {{- $title := cond (hasPrefix .Url "http") (printf "%v -> %v" (T "single.repost") .Url ) (T "single.repost") -}} {{- $icon | partial "plugin/icon.html" -}} {{- end -}} diff --git a/layouts/taxonomies.html b/layouts/taxonomies.html index 69d04658..9b23033e 100644 --- a/layouts/taxonomies.html +++ b/layouts/taxonomies.html @@ -19,7 +19,7 @@ {{- $repost := .Params.repost | default dict -}} {{- if eq $repost.enable true -}} - {{- dict "Class" "fa-solid fa-share text-success me-1" | partial "plugin/icon.html" -}} + {{- dict "Class" "fa-solid fa-retweet text-success me-1" | partial "plugin/icon.html" -}} {{- end -}} {{- cond (.Param "capitalize_titles") (title .LinkTitle) .LinkTitle -}} diff --git a/layouts/term.html b/layouts/term.html index 06d7a6db..2c82ca79 100644 --- a/layouts/term.html +++ b/layouts/term.html @@ -36,7 +36,7 @@ {{- $repost := .Params.repost | default dict -}} {{- if eq $repost.enable true -}} - {{- dict "Class" "fa-solid fa-share text-success me-1" | partial "plugin/icon.html" -}} + {{- dict "Class" "fa-solid fa-retweet text-success me-1" | partial "plugin/icon.html" -}} {{- end -}} {{- cond (.Param "capitalize_titles") (title .LinkTitle) .LinkTitle -}} diff --git a/librarybot.yml b/librarybot.yml index 1218a98d..44cc85ae 100644 --- a/librarybot.yml +++ b/librarybot.yml @@ -85,7 +85,7 @@ libraries: - from: instantpage.min.js to: instant.page/instantpage.min.js - npm: json-viewer-element - version: 1.0.4 + version: 1.0.6 local: items: - from: dist/json-viewer-element.umd.js