Merge pull request #1641 from cN3rd/rtl
Continued work on "Support right-to-left languages"
This commit is contained in:
commit
09f222baf7
|
@ -46,6 +46,9 @@ This is general information about your book.
|
||||||
`src` directly under the root folder. But this is configurable with the `src`
|
`src` directly under the root folder. But this is configurable with the `src`
|
||||||
key in the configuration file.
|
key in the configuration file.
|
||||||
- **language:** The main language of the book, which is used as a language attribute `<html lang="en">` for example.
|
- **language:** The main language of the book, which is used as a language attribute `<html lang="en">` for example.
|
||||||
|
This is also used to derive the direction of text (RTL, LTR) within the book.
|
||||||
|
- **text_direction**: The direction of text in the book: Left-to-right (LTR) or Right-to-left (RTL). Possible values: `ltr`, `rtl`.
|
||||||
|
When not specified, the text direction is derived from the book's `language` attribute.
|
||||||
|
|
||||||
**book.toml**
|
**book.toml**
|
||||||
```toml
|
```toml
|
||||||
|
@ -55,6 +58,7 @@ authors = ["John Doe", "Jane Doe"]
|
||||||
description = "The example book covers examples."
|
description = "The example book covers examples."
|
||||||
src = "my-src" # the source files will be found in `root/my-src` instead of `root/src`
|
src = "my-src" # the source files will be found in `root/my-src` instead of `root/src`
|
||||||
language = "en"
|
language = "en"
|
||||||
|
text-direction = "ltr"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Rust options
|
### Rust options
|
||||||
|
|
108
src/config.rs
108
src/config.rs
|
@ -411,6 +411,9 @@ pub struct BookConfig {
|
||||||
pub multilingual: bool,
|
pub multilingual: bool,
|
||||||
/// The main language of the book.
|
/// The main language of the book.
|
||||||
pub language: Option<String>,
|
pub language: Option<String>,
|
||||||
|
/// The direction of text in the book: Left-to-right (LTR) or Right-to-left (RTL).
|
||||||
|
/// When not specified, the text direction is derived from [`BookConfig::language`].
|
||||||
|
pub text_direction: Option<TextDirection>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for BookConfig {
|
impl Default for BookConfig {
|
||||||
|
@ -422,6 +425,43 @@ impl Default for BookConfig {
|
||||||
src: PathBuf::from("src"),
|
src: PathBuf::from("src"),
|
||||||
multilingual: false,
|
multilingual: false,
|
||||||
language: Some(String::from("en")),
|
language: Some(String::from("en")),
|
||||||
|
text_direction: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BookConfig {
|
||||||
|
/// Gets the realized text direction, either from [`BookConfig::text_direction`]
|
||||||
|
/// or derived from [`BookConfig::language`], to be used by templating engines.
|
||||||
|
pub fn realized_text_direction(&self) -> TextDirection {
|
||||||
|
if let Some(direction) = self.text_direction {
|
||||||
|
direction
|
||||||
|
} else {
|
||||||
|
TextDirection::from_lang_code(self.language.as_deref().unwrap_or_default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Text direction to use for HTML output
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub enum TextDirection {
|
||||||
|
/// Left to right.
|
||||||
|
#[serde(rename = "ltr")]
|
||||||
|
LeftToRight,
|
||||||
|
/// Right to left
|
||||||
|
#[serde(rename = "rtl")]
|
||||||
|
RightToLeft,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TextDirection {
|
||||||
|
/// Gets the text direction from language code
|
||||||
|
pub fn from_lang_code(code: &str) -> Self {
|
||||||
|
match code {
|
||||||
|
// list sourced from here: https://github.com/abarrak/rtl/blob/master/lib/rtl/core.rb#L16
|
||||||
|
"ar" | "ara" | "arc" | "ae" | "ave" | "egy" | "he" | "heb" | "nqo" | "pal" | "phn"
|
||||||
|
| "sam" | "syc" | "syr" | "fa" | "per" | "fas" | "ku" | "kur" | "ur" | "urd"
|
||||||
|
| "pus" | "ps" | "yi" | "yid" => TextDirection::RightToLeft,
|
||||||
|
_ => TextDirection::LeftToRight,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -788,6 +828,7 @@ mod tests {
|
||||||
multilingual: true,
|
multilingual: true,
|
||||||
src: PathBuf::from("source"),
|
src: PathBuf::from("source"),
|
||||||
language: Some(String::from("ja")),
|
language: Some(String::from("ja")),
|
||||||
|
text_direction: None,
|
||||||
};
|
};
|
||||||
let build_should_be = BuildConfig {
|
let build_should_be = BuildConfig {
|
||||||
build_dir: PathBuf::from("outputs"),
|
build_dir: PathBuf::from("outputs"),
|
||||||
|
@ -1140,6 +1181,73 @@ mod tests {
|
||||||
assert_eq!(&get_404_output_file(&html_config.input_404), "missing.html");
|
assert_eq!(&get_404_output_file(&html_config.input_404), "missing.html");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn text_direction_ltr() {
|
||||||
|
let src = r#"
|
||||||
|
[book]
|
||||||
|
text-direction = "ltr"
|
||||||
|
"#;
|
||||||
|
|
||||||
|
let got = Config::from_str(src).unwrap();
|
||||||
|
assert_eq!(got.book.text_direction, Some(TextDirection::LeftToRight));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn text_direction_rtl() {
|
||||||
|
let src = r#"
|
||||||
|
[book]
|
||||||
|
text-direction = "rtl"
|
||||||
|
"#;
|
||||||
|
|
||||||
|
let got = Config::from_str(src).unwrap();
|
||||||
|
assert_eq!(got.book.text_direction, Some(TextDirection::RightToLeft));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn text_direction_none() {
|
||||||
|
let src = r#"
|
||||||
|
[book]
|
||||||
|
"#;
|
||||||
|
|
||||||
|
let got = Config::from_str(src).unwrap();
|
||||||
|
assert_eq!(got.book.text_direction, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_text_direction() {
|
||||||
|
let mut cfg = BookConfig::default();
|
||||||
|
|
||||||
|
// test deriving the text direction from language codes
|
||||||
|
cfg.language = Some("ar".into());
|
||||||
|
assert_eq!(cfg.realized_text_direction(), TextDirection::RightToLeft);
|
||||||
|
|
||||||
|
cfg.language = Some("he".into());
|
||||||
|
assert_eq!(cfg.realized_text_direction(), TextDirection::RightToLeft);
|
||||||
|
|
||||||
|
cfg.language = Some("en".into());
|
||||||
|
assert_eq!(cfg.realized_text_direction(), TextDirection::LeftToRight);
|
||||||
|
|
||||||
|
cfg.language = Some("ja".into());
|
||||||
|
assert_eq!(cfg.realized_text_direction(), TextDirection::LeftToRight);
|
||||||
|
|
||||||
|
// test forced direction
|
||||||
|
cfg.language = Some("ar".into());
|
||||||
|
cfg.text_direction = Some(TextDirection::LeftToRight);
|
||||||
|
assert_eq!(cfg.realized_text_direction(), TextDirection::LeftToRight);
|
||||||
|
|
||||||
|
cfg.language = Some("ar".into());
|
||||||
|
cfg.text_direction = Some(TextDirection::RightToLeft);
|
||||||
|
assert_eq!(cfg.realized_text_direction(), TextDirection::RightToLeft);
|
||||||
|
|
||||||
|
cfg.language = Some("en".into());
|
||||||
|
cfg.text_direction = Some(TextDirection::LeftToRight);
|
||||||
|
assert_eq!(cfg.realized_text_direction(), TextDirection::LeftToRight);
|
||||||
|
|
||||||
|
cfg.language = Some("en".into());
|
||||||
|
cfg.text_direction = Some(TextDirection::RightToLeft);
|
||||||
|
assert_eq!(cfg.realized_text_direction(), TextDirection::RightToLeft);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "Invalid configuration file")]
|
#[should_panic(expected = "Invalid configuration file")]
|
||||||
fn invalid_language_type_error() {
|
fn invalid_language_type_error() {
|
||||||
|
|
|
@ -648,6 +648,10 @@ fn make_data(
|
||||||
"language".to_owned(),
|
"language".to_owned(),
|
||||||
json!(config.book.language.clone().unwrap_or_default()),
|
json!(config.book.language.clone().unwrap_or_default()),
|
||||||
);
|
);
|
||||||
|
data.insert(
|
||||||
|
"text_direction".to_owned(),
|
||||||
|
json!(config.book.realized_text_direction()),
|
||||||
|
);
|
||||||
data.insert(
|
data.insert(
|
||||||
"book_title".to_owned(),
|
"book_title".to_owned(),
|
||||||
json!(config.book.title.clone().unwrap_or_default()),
|
json!(config.book.title.clone().unwrap_or_default()),
|
||||||
|
@ -1088,6 +1092,8 @@ struct RenderItemContext<'a> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use crate::config::TextDirection;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
|
@ -1299,4 +1305,10 @@ mod tests {
|
||||||
assert_eq!(&*got, *should_be);
|
assert_eq!(&*got, *should_be);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_json_direction() {
|
||||||
|
assert_eq!(json!(TextDirection::RightToLeft), json!("rtl"));
|
||||||
|
assert_eq!(json!(TextDirection::LeftToRight), json!("ltr"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -441,7 +441,7 @@ function playground_text(playground, hidden = true) {
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(function sidebar() {
|
(function sidebar() {
|
||||||
var html = document.querySelector("html");
|
var body = document.querySelector("body");
|
||||||
var sidebar = document.getElementById("sidebar");
|
var sidebar = document.getElementById("sidebar");
|
||||||
var sidebarLinks = document.querySelectorAll('#sidebar a');
|
var sidebarLinks = document.querySelectorAll('#sidebar a');
|
||||||
var sidebarToggleButton = document.getElementById("sidebar-toggle");
|
var sidebarToggleButton = document.getElementById("sidebar-toggle");
|
||||||
|
@ -449,8 +449,8 @@ function playground_text(playground, hidden = true) {
|
||||||
var firstContact = null;
|
var firstContact = null;
|
||||||
|
|
||||||
function showSidebar() {
|
function showSidebar() {
|
||||||
html.classList.remove('sidebar-hidden')
|
body.classList.remove('sidebar-hidden')
|
||||||
html.classList.add('sidebar-visible');
|
body.classList.add('sidebar-visible');
|
||||||
Array.from(sidebarLinks).forEach(function (link) {
|
Array.from(sidebarLinks).forEach(function (link) {
|
||||||
link.setAttribute('tabIndex', 0);
|
link.setAttribute('tabIndex', 0);
|
||||||
});
|
});
|
||||||
|
@ -471,8 +471,8 @@ function playground_text(playground, hidden = true) {
|
||||||
});
|
});
|
||||||
|
|
||||||
function hideSidebar() {
|
function hideSidebar() {
|
||||||
html.classList.remove('sidebar-visible')
|
body.classList.remove('sidebar-visible')
|
||||||
html.classList.add('sidebar-hidden');
|
body.classList.add('sidebar-hidden');
|
||||||
Array.from(sidebarLinks).forEach(function (link) {
|
Array.from(sidebarLinks).forEach(function (link) {
|
||||||
link.setAttribute('tabIndex', -1);
|
link.setAttribute('tabIndex', -1);
|
||||||
});
|
});
|
||||||
|
@ -483,14 +483,14 @@ function playground_text(playground, hidden = true) {
|
||||||
|
|
||||||
// Toggle sidebar
|
// Toggle sidebar
|
||||||
sidebarToggleButton.addEventListener('click', function sidebarToggle() {
|
sidebarToggleButton.addEventListener('click', function sidebarToggle() {
|
||||||
if (html.classList.contains("sidebar-hidden")) {
|
if (body.classList.contains("sidebar-hidden")) {
|
||||||
var current_width = parseInt(
|
var current_width = parseInt(
|
||||||
document.documentElement.style.getPropertyValue('--sidebar-width'), 10);
|
document.documentElement.style.getPropertyValue('--sidebar-width'), 10);
|
||||||
if (current_width < 150) {
|
if (current_width < 150) {
|
||||||
document.documentElement.style.setProperty('--sidebar-width', '150px');
|
document.documentElement.style.setProperty('--sidebar-width', '150px');
|
||||||
}
|
}
|
||||||
showSidebar();
|
showSidebar();
|
||||||
} else if (html.classList.contains("sidebar-visible")) {
|
} else if (body.classList.contains("sidebar-visible")) {
|
||||||
hideSidebar();
|
hideSidebar();
|
||||||
} else {
|
} else {
|
||||||
if (getComputedStyle(sidebar)['transform'] === 'none') {
|
if (getComputedStyle(sidebar)['transform'] === 'none') {
|
||||||
|
@ -506,14 +506,14 @@ function playground_text(playground, hidden = true) {
|
||||||
function initResize(e) {
|
function initResize(e) {
|
||||||
window.addEventListener('mousemove', resize, false);
|
window.addEventListener('mousemove', resize, false);
|
||||||
window.addEventListener('mouseup', stopResize, false);
|
window.addEventListener('mouseup', stopResize, false);
|
||||||
html.classList.add('sidebar-resizing');
|
body.classList.add('sidebar-resizing');
|
||||||
}
|
}
|
||||||
function resize(e) {
|
function resize(e) {
|
||||||
var pos = (e.clientX - sidebar.offsetLeft);
|
var pos = (e.clientX - sidebar.offsetLeft);
|
||||||
if (pos < 20) {
|
if (pos < 20) {
|
||||||
hideSidebar();
|
hideSidebar();
|
||||||
} else {
|
} else {
|
||||||
if (html.classList.contains("sidebar-hidden")) {
|
if (body.classList.contains("sidebar-hidden")) {
|
||||||
showSidebar();
|
showSidebar();
|
||||||
}
|
}
|
||||||
pos = Math.min(pos, window.innerWidth - 100);
|
pos = Math.min(pos, window.innerWidth - 100);
|
||||||
|
@ -522,7 +522,7 @@ function playground_text(playground, hidden = true) {
|
||||||
}
|
}
|
||||||
//on mouseup remove windows functions mousemove & mouseup
|
//on mouseup remove windows functions mousemove & mouseup
|
||||||
function stopResize(e) {
|
function stopResize(e) {
|
||||||
html.classList.remove('sidebar-resizing');
|
body.classList.remove('sidebar-resizing');
|
||||||
window.removeEventListener('mousemove', resize, false);
|
window.removeEventListener('mousemove', resize, false);
|
||||||
window.removeEventListener('mouseup', stopResize, false);
|
window.removeEventListener('mouseup', stopResize, false);
|
||||||
}
|
}
|
||||||
|
@ -557,20 +557,35 @@ function playground_text(playground, hidden = true) {
|
||||||
document.addEventListener('keydown', function (e) {
|
document.addEventListener('keydown', function (e) {
|
||||||
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
|
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
|
||||||
if (window.search && window.search.hasFocus()) { return; }
|
if (window.search && window.search.hasFocus()) { return; }
|
||||||
|
var html = document.querySelector('html');
|
||||||
|
|
||||||
|
function next() {
|
||||||
|
var nextButton = document.querySelector('.nav-chapters.next');
|
||||||
|
if (nextButton) {
|
||||||
|
window.location.href = nextButton.href;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function prev() {
|
||||||
|
var previousButton = document.querySelector('.nav-chapters.previous');
|
||||||
|
if (previousButton) {
|
||||||
|
window.location.href = previousButton.href;
|
||||||
|
}
|
||||||
|
}
|
||||||
switch (e.key) {
|
switch (e.key) {
|
||||||
case 'ArrowRight':
|
case 'ArrowRight':
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var nextButton = document.querySelector('.nav-chapters.next');
|
if (html.dir == 'rtl') {
|
||||||
if (nextButton) {
|
prev();
|
||||||
window.location.href = nextButton.href;
|
} else {
|
||||||
|
next();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'ArrowLeft':
|
case 'ArrowLeft':
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var previousButton = document.querySelector('.nav-chapters.previous');
|
if (html.dir == 'rtl') {
|
||||||
if (previousButton) {
|
next();
|
||||||
window.location.href = previousButton.href;
|
} else {
|
||||||
|
prev();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,9 +37,9 @@ a > .hljs {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
background-color: var(--bg);
|
background-color: var(--bg);
|
||||||
border-bottom-color: var(--bg);
|
border-block-end-color: var(--bg);
|
||||||
border-bottom-width: 1px;
|
border-block-end-width: 1px;
|
||||||
border-bottom-style: solid;
|
border-block-end-style: solid;
|
||||||
}
|
}
|
||||||
#menu-bar.sticky,
|
#menu-bar.sticky,
|
||||||
.js #menu-bar-hover-placeholder:hover + #menu-bar,
|
.js #menu-bar-hover-placeholder:hover + #menu-bar,
|
||||||
|
@ -56,7 +56,7 @@ a > .hljs {
|
||||||
height: var(--menu-bar-height);
|
height: var(--menu-bar-height);
|
||||||
}
|
}
|
||||||
#menu-bar.bordered {
|
#menu-bar.bordered {
|
||||||
border-bottom-color: var(--table-border-color);
|
border-block-end-color: var(--table-border-color);
|
||||||
}
|
}
|
||||||
#menu-bar i, #menu-bar .icon-button {
|
#menu-bar i, #menu-bar .icon-button {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -160,7 +160,7 @@ a > .hljs {
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-wrapper {
|
.nav-wrapper {
|
||||||
margin-top: 50px;
|
margin-block-start: 50px;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,14 +173,24 @@ a > .hljs {
|
||||||
background-color: var(--sidebar-bg);
|
background-color: var(--sidebar-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.previous {
|
/* Only Firefox supports flow-relative values */
|
||||||
float: left;
|
.previous { float: left; }
|
||||||
}
|
[dir=rtl] .previous { float: right; }
|
||||||
|
|
||||||
|
/* Only Firefox supports flow-relative values */
|
||||||
.next {
|
.next {
|
||||||
float: right;
|
float: right;
|
||||||
right: var(--page-padding);
|
right: var(--page-padding);
|
||||||
}
|
}
|
||||||
|
[dir=rtl] .next {
|
||||||
|
float: left;
|
||||||
|
right: unset;
|
||||||
|
left: var(--page-padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use the correct buttons for RTL layouts*/
|
||||||
|
[dir=rtl] .previous i.fa-angle-left:before {content:"\f105";}
|
||||||
|
[dir=rtl] .next i.fa-angle-right:before { content:"\f104"; }
|
||||||
|
|
||||||
@media only screen and (max-width: 1080px) {
|
@media only screen and (max-width: 1080px) {
|
||||||
.nav-wide-wrapper { display: none; }
|
.nav-wide-wrapper { display: none; }
|
||||||
|
@ -237,7 +247,7 @@ pre > .buttons :hover {
|
||||||
background-color: var(--theme-hover);
|
background-color: var(--theme-hover);
|
||||||
}
|
}
|
||||||
pre > .buttons i {
|
pre > .buttons i {
|
||||||
margin-left: 8px;
|
margin-inline-start: 8px;
|
||||||
}
|
}
|
||||||
pre > .buttons button {
|
pre > .buttons button {
|
||||||
cursor: inherit;
|
cursor: inherit;
|
||||||
|
@ -274,7 +284,7 @@ pre > code {
|
||||||
}
|
}
|
||||||
|
|
||||||
pre > .result {
|
pre > .result {
|
||||||
margin-top: 10px;
|
margin-block-start: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Search */
|
/* Search */
|
||||||
|
@ -285,8 +295,14 @@ pre > .result {
|
||||||
|
|
||||||
mark {
|
mark {
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
padding: 0 3px 1px 3px;
|
padding-block-start: 0;
|
||||||
margin: 0 -3px -1px -3px;
|
padding-block-end: 1px;
|
||||||
|
padding-inline-start: 3px;
|
||||||
|
padding-inline-end: 3px;
|
||||||
|
margin-block-start: 0;
|
||||||
|
margin-block-end: -1px;
|
||||||
|
margin-inline-start: -3px;
|
||||||
|
margin-inline-end: -3px;
|
||||||
background-color: var(--search-mark-bg);
|
background-color: var(--search-mark-bg);
|
||||||
transition: background-color 300ms linear;
|
transition: background-color 300ms linear;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -298,14 +314,17 @@ mark.fade-out {
|
||||||
}
|
}
|
||||||
|
|
||||||
.searchbar-outer {
|
.searchbar-outer {
|
||||||
margin-left: auto;
|
margin-inline-start: auto;
|
||||||
margin-right: auto;
|
margin-inline-end: auto;
|
||||||
max-width: var(--content-max-width);
|
max-width: var(--content-max-width);
|
||||||
}
|
}
|
||||||
|
|
||||||
#searchbar {
|
#searchbar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 5px auto 0px auto;
|
margin-block-start: 5px;
|
||||||
|
margin-block-end: 0;
|
||||||
|
margin-inline-start: auto;
|
||||||
|
margin-inline-end: auto;
|
||||||
padding: 10px 16px;
|
padding: 10px 16px;
|
||||||
transition: box-shadow 300ms ease-in-out;
|
transition: box-shadow 300ms ease-in-out;
|
||||||
border: 1px solid var(--searchbar-border-color);
|
border: 1px solid var(--searchbar-border-color);
|
||||||
|
@ -321,20 +340,23 @@ mark.fade-out {
|
||||||
.searchresults-header {
|
.searchresults-header {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
padding: 18px 0 0 5px;
|
padding-block-start: 18px;
|
||||||
|
padding-block-end: 0;
|
||||||
|
padding-inline-start: 5px;
|
||||||
|
padding-inline-end: 0;
|
||||||
color: var(--searchresults-header-fg);
|
color: var(--searchresults-header-fg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.searchresults-outer {
|
.searchresults-outer {
|
||||||
margin-left: auto;
|
margin-inline-start: auto;
|
||||||
margin-right: auto;
|
margin-inline-end: auto;
|
||||||
max-width: var(--content-max-width);
|
max-width: var(--content-max-width);
|
||||||
border-bottom: 1px dashed var(--searchresults-border-color);
|
border-block-end: 1px dashed var(--searchresults-border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
ul#searchresults {
|
ul#searchresults {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
padding-left: 20px;
|
padding-inline-start: 20px;
|
||||||
}
|
}
|
||||||
ul#searchresults li {
|
ul#searchresults li {
|
||||||
margin: 10px 0px;
|
margin: 10px 0px;
|
||||||
|
@ -347,7 +369,10 @@ ul#searchresults li.focus {
|
||||||
ul#searchresults span.teaser {
|
ul#searchresults span.teaser {
|
||||||
display: block;
|
display: block;
|
||||||
clear: both;
|
clear: both;
|
||||||
margin: 5px 0 0 20px;
|
margin-block-start: 5px;
|
||||||
|
margin-block-end: 0;
|
||||||
|
margin-inline-start: 20px;
|
||||||
|
margin-inline-end: 0;
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
ul#searchresults span.teaser em {
|
ul#searchresults span.teaser em {
|
||||||
|
@ -370,6 +395,7 @@ ul#searchresults span.teaser em {
|
||||||
background-color: var(--sidebar-bg);
|
background-color: var(--sidebar-bg);
|
||||||
color: var(--sidebar-fg);
|
color: var(--sidebar-fg);
|
||||||
}
|
}
|
||||||
|
[dir=rtl] .sidebar { left: unset; right: 0; }
|
||||||
.sidebar-resizing {
|
.sidebar-resizing {
|
||||||
-moz-user-select: none;
|
-moz-user-select: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
|
@ -400,6 +426,7 @@ ul#searchresults span.teaser em {
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
}
|
}
|
||||||
|
[dir=rtl] .sidebar .sidebar-resize-handle { right: unset; left: 0; }
|
||||||
.js .sidebar .sidebar-resize-handle {
|
.js .sidebar .sidebar-resize-handle {
|
||||||
cursor: col-resize;
|
cursor: col-resize;
|
||||||
width: 5px;
|
width: 5px;
|
||||||
|
@ -409,6 +436,9 @@ ul#searchresults span.teaser em {
|
||||||
transform: translateX(calc(0px - var(--sidebar-width)));
|
transform: translateX(calc(0px - var(--sidebar-width)));
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
}
|
}
|
||||||
|
[dir=rtl] #sidebar-toggle-anchor:not(:checked) ~ .sidebar {
|
||||||
|
transform: translateX(var(--sidebar-width));
|
||||||
|
}
|
||||||
.sidebar::-webkit-scrollbar {
|
.sidebar::-webkit-scrollbar {
|
||||||
background: var(--sidebar-bg);
|
background: var(--sidebar-bg);
|
||||||
}
|
}
|
||||||
|
@ -420,16 +450,22 @@ ul#searchresults span.teaser em {
|
||||||
#sidebar-toggle-anchor:checked ~ .page-wrapper {
|
#sidebar-toggle-anchor:checked ~ .page-wrapper {
|
||||||
transform: translateX(var(--sidebar-width));
|
transform: translateX(var(--sidebar-width));
|
||||||
}
|
}
|
||||||
|
[dir=rtl] #sidebar-toggle-anchor:checked ~ .page-wrapper {
|
||||||
|
transform: translateX(calc(0px - var(--sidebar-width)));
|
||||||
|
}
|
||||||
@media only screen and (min-width: 620px) {
|
@media only screen and (min-width: 620px) {
|
||||||
#sidebar-toggle-anchor:checked ~ .page-wrapper {
|
#sidebar-toggle-anchor:checked ~ .page-wrapper {
|
||||||
transform: none;
|
transform: none;
|
||||||
margin-left: var(--sidebar-width);
|
margin-inline-start: var(--sidebar-width);
|
||||||
|
}
|
||||||
|
[dir=rtl] #sidebar-toggle-anchor:checked ~ .page-wrapper {
|
||||||
|
transform: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.chapter {
|
.chapter {
|
||||||
list-style: none outside none;
|
list-style: none outside none;
|
||||||
padding-left: 0;
|
padding-inline-start: 0;
|
||||||
line-height: 2.2em;
|
line-height: 2.2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,7 +495,7 @@ ul#searchresults span.teaser em {
|
||||||
.chapter li > a.toggle {
|
.chapter li > a.toggle {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: block;
|
display: block;
|
||||||
margin-left: auto;
|
margin-inline-start: auto;
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
opacity: 0.68;
|
opacity: 0.68;
|
||||||
|
@ -476,7 +512,7 @@ ul#searchresults span.teaser em {
|
||||||
|
|
||||||
.chapter li.chapter-item {
|
.chapter li.chapter-item {
|
||||||
line-height: 1.5em;
|
line-height: 1.5em;
|
||||||
margin-top: 0.6em;
|
margin-block-start: 0.6em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chapter li.expanded > a.toggle div {
|
.chapter li.expanded > a.toggle div {
|
||||||
|
@ -499,7 +535,7 @@ ul#searchresults span.teaser em {
|
||||||
|
|
||||||
.section {
|
.section {
|
||||||
list-style: none outside none;
|
list-style: none outside none;
|
||||||
padding-left: 20px;
|
padding-inline-start: 20px;
|
||||||
line-height: 1.9em;
|
line-height: 1.9em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,6 +558,7 @@ ul#searchresults span.teaser em {
|
||||||
/* Don't let the children's background extend past the rounded corners. */
|
/* Don't let the children's background extend past the rounded corners. */
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
[dir=rtl] .theme-popup { left: unset; right: 10px; }
|
||||||
.theme-popup .default {
|
.theme-popup .default {
|
||||||
color: var(--icons);
|
color: var(--icons);
|
||||||
}
|
}
|
||||||
|
@ -532,7 +569,7 @@ ul#searchresults span.teaser em {
|
||||||
padding: 2px 20px;
|
padding: 2px 20px;
|
||||||
line-height: 25px;
|
line-height: 25px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-align: left;
|
text-align: start;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
background: inherit;
|
background: inherit;
|
||||||
|
@ -545,6 +582,6 @@ ul#searchresults span.teaser em {
|
||||||
.theme-selected::before {
|
.theme-selected::before {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
content: "✓";
|
content: "✓";
|
||||||
margin-left: -14px;
|
margin-inline-start: -14px;
|
||||||
width: 14px;
|
width: 14px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ body {
|
||||||
code {
|
code {
|
||||||
font-family: var(--mono-font) !important;
|
font-family: var(--mono-font) !important;
|
||||||
font-size: var(--code-font-size);
|
font-size: var(--code-font-size);
|
||||||
|
direction: ltr !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make long words/inline code not x overflow */
|
/* make long words/inline code not x overflow */
|
||||||
|
@ -48,13 +49,13 @@ h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
|
||||||
.hide-boring .boring { display: none; }
|
.hide-boring .boring { display: none; }
|
||||||
.hidden { display: none !important; }
|
.hidden { display: none !important; }
|
||||||
|
|
||||||
h2, h3 { margin-top: 2.5em; }
|
h2, h3 { margin-block-start: 2.5em; }
|
||||||
h4, h5 { margin-top: 2em; }
|
h4, h5 { margin-block-start: 2em; }
|
||||||
|
|
||||||
.header + .header h3,
|
.header + .header h3,
|
||||||
.header + .header h4,
|
.header + .header h4,
|
||||||
.header + .header h5 {
|
.header + .header h5 {
|
||||||
margin-top: 1em;
|
margin-block-start: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1:target::before,
|
h1:target::before,
|
||||||
|
@ -65,7 +66,7 @@ h5:target::before,
|
||||||
h6:target::before {
|
h6:target::before {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
content: "»";
|
content: "»";
|
||||||
margin-left: -30px;
|
margin-inline-start: -30px;
|
||||||
width: 30px;
|
width: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,13 +75,14 @@ h6:target::before {
|
||||||
https://bugs.webkit.org/show_bug.cgi?id=218076
|
https://bugs.webkit.org/show_bug.cgi?id=218076
|
||||||
*/
|
*/
|
||||||
:target {
|
:target {
|
||||||
|
/* Safari does not support logical properties */
|
||||||
scroll-margin-top: calc(var(--menu-bar-height) + 0.5em);
|
scroll-margin-top: calc(var(--menu-bar-height) + 0.5em);
|
||||||
}
|
}
|
||||||
|
|
||||||
.page {
|
.page {
|
||||||
outline: 0;
|
outline: 0;
|
||||||
padding: 0 var(--page-padding);
|
padding: 0 var(--page-padding);
|
||||||
margin-top: calc(0px - var(--menu-bar-height)); /* Compensate for the #menu-bar-hover-placeholder */
|
margin-block-start: calc(0px - var(--menu-bar-height)); /* Compensate for the #menu-bar-hover-placeholder */
|
||||||
}
|
}
|
||||||
.page-wrapper {
|
.page-wrapper {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
@ -90,14 +92,17 @@ h6:target::before {
|
||||||
.js:not(.sidebar-resizing) .page-wrapper {
|
.js:not(.sidebar-resizing) .page-wrapper {
|
||||||
transition: margin-left 0.3s ease, transform 0.3s ease; /* Animation: slide away */
|
transition: margin-left 0.3s ease, transform 0.3s ease; /* Animation: slide away */
|
||||||
}
|
}
|
||||||
|
[dir=rtl] .js:not(.sidebar-resizing) .page-wrapper {
|
||||||
|
transition: margin-right 0.3s ease, transform 0.3s ease; /* Animation: slide away */
|
||||||
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding: 0 5px 50px 5px;
|
padding: 0 5px 50px 5px;
|
||||||
}
|
}
|
||||||
.content main {
|
.content main {
|
||||||
margin-left: auto;
|
margin-inline-start: auto;
|
||||||
margin-right: auto;
|
margin-inline-end: auto;
|
||||||
max-width: var(--content-max-width);
|
max-width: var(--content-max-width);
|
||||||
}
|
}
|
||||||
.content p { line-height: 1.45em; }
|
.content p { line-height: 1.45em; }
|
||||||
|
@ -147,8 +152,8 @@ blockquote {
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
color: var(--fg);
|
color: var(--fg);
|
||||||
background-color: var(--quote-bg);
|
background-color: var(--quote-bg);
|
||||||
border-top: .1em solid var(--quote-border);
|
border-block-start: .1em solid var(--quote-border);
|
||||||
border-bottom: .1em solid var(--quote-border);
|
border-block-end: .1em solid var(--quote-border);
|
||||||
}
|
}
|
||||||
|
|
||||||
kbd {
|
kbd {
|
||||||
|
@ -166,7 +171,7 @@ kbd {
|
||||||
|
|
||||||
:not(.footnote-definition) + .footnote-definition,
|
:not(.footnote-definition) + .footnote-definition,
|
||||||
.footnote-definition + :not(.footnote-definition) {
|
.footnote-definition + :not(.footnote-definition) {
|
||||||
margin-top: 2em;
|
margin-block-start: 2em;
|
||||||
}
|
}
|
||||||
.footnote-definition {
|
.footnote-definition {
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#page-wrapper.page-wrapper {
|
#page-wrapper.page-wrapper {
|
||||||
transform: none;
|
transform: none;
|
||||||
margin-left: 0px;
|
margin-inline-start: 0px;
|
||||||
overflow-y: initial;
|
overflow-y: initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,10 @@
|
||||||
overflow-y: initial;
|
overflow-y: initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
direction: ltr !important;
|
||||||
|
}
|
||||||
|
|
||||||
pre > .buttons {
|
pre > .buttons {
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<!DOCTYPE HTML>
|
<!DOCTYPE HTML>
|
||||||
<html lang="{{ language }}" class="sidebar-visible no-js {{ default_theme }}">
|
<html lang="{{ language }}" class="{{ default_theme }}" dir="{{ text_direction }}">
|
||||||
<head>
|
<head>
|
||||||
<!-- Book generated using mdBook -->
|
<!-- Book generated using mdBook -->
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body class="sidebar-visible no-js">
|
||||||
<div id="body-container">
|
<div id="body-container">
|
||||||
<!-- Provide site root to javascript -->
|
<!-- Provide site root to javascript -->
|
||||||
<script>
|
<script>
|
||||||
|
@ -83,17 +83,18 @@
|
||||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||||
var html = document.querySelector('html');
|
var html = document.querySelector('html');
|
||||||
html.classList.remove('no-js')
|
|
||||||
html.classList.remove('{{ default_theme }}')
|
html.classList.remove('{{ default_theme }}')
|
||||||
html.classList.add(theme);
|
html.classList.add(theme);
|
||||||
html.classList.add('js');
|
var body = document.querySelector('body');
|
||||||
|
body.classList.remove('no-js')
|
||||||
|
body.classList.add('js');
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||||
|
|
||||||
<!-- Hide / unhide sidebar before it is displayed -->
|
<!-- Hide / unhide sidebar before it is displayed -->
|
||||||
<script>
|
<script>
|
||||||
var html = document.querySelector('html');
|
var body = document.querySelector('body');
|
||||||
var sidebar = null;
|
var sidebar = null;
|
||||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||||
if (document.body.clientWidth >= 1080) {
|
if (document.body.clientWidth >= 1080) {
|
||||||
|
@ -103,8 +104,8 @@
|
||||||
sidebar = 'hidden';
|
sidebar = 'hidden';
|
||||||
}
|
}
|
||||||
sidebar_toggle.checked = sidebar === 'visible';
|
sidebar_toggle.checked = sidebar === 'visible';
|
||||||
html.classList.remove('sidebar-visible');
|
body.classList.remove('sidebar-visible');
|
||||||
html.classList.add("sidebar-" + sidebar);
|
body.classList.add("sidebar-" + sidebar);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||||
|
|
|
@ -10,7 +10,9 @@ This is a codeblock
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This line contains `inline code`
|
This line contains `inline code` mixed with some other stuff. (LTR)
|
||||||
|
|
||||||
|
ושורה זו מכילה `inline code` אבל עם טקסט בשפה שנכתבת מימין לשמאל. (RTL)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue