Skip to content

Commit 0ca52a5

Browse files
Add RTL support (#324)
Co-authored-by: Stan Ulbrych <stan@python.org>
1 parent 9c9c66a commit 0ca52a5

4 files changed

Lines changed: 126 additions & 37 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ To use this theme, add the following to `conf.py`:
2222

2323
- `html_sidebars`, defaults taken from https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-html_sidebars
2424

25+
- To lay pages out right-to-left for languages such as Persian, Arabic, or Hebrew,
26+
set `html_theme_options = {"is_rtl": True}`. Defaults to `false`.
2527

2628
## Translation
2729

python_docs_theme/layout.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<h3>{{ _('Navigation') }}</h3>
77
<ul>
88
{%- for rellink in rellinks %}
9-
<li class="right" {% if loop.first %}style="margin-right: 10px"{% endif %}>
9+
<li class="right" {% if loop.first %}style="margin-inline-end: 10px"{% endif %}>
1010
<a href="{{ pathto(rellink[0])|e }}" title="{{ rellink[1]|striptags|e }}"
1111
{{ accesskey(rellink[2]) }}>{{ rellink[3] }}
1212
</a>
@@ -89,7 +89,7 @@ <h3>{{ _('Navigation') }}</h3>
8989
{%- endblock -%}
9090

9191
{%- block body_tag %}
92-
{{ super() }}
92+
<body{% if theme_is_rtl|tobool %} dir="rtl"{% endif %}>
9393
{%- if builder != 'htmlhelp' %}
9494
<div class="mobile-nav">
9595
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"

python_docs_theme/static/pydoctheme.css

Lines changed: 121 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ div.related a:hover {
108108
}
109109

110110
.switchers > div {
111-
margin-right: 5px;
111+
margin-inline-end: 5px;
112112
}
113113

114114
div.related ul::after {
@@ -117,6 +117,17 @@ div.related ul::after {
117117
display: block;
118118
}
119119

120+
div.related ul {
121+
padding: 0;
122+
padding-inline-start: 10px;
123+
}
124+
125+
body[dir='rtl'] div.related ul li.right {
126+
float: left;
127+
margin-right: 0;
128+
margin-left: 5px;
129+
}
130+
120131
.inline-search,
121132
form.inline-search input {
122133
display: inline;
@@ -142,6 +153,9 @@ span.pre {
142153
div.sphinxsidebar {
143154
display: flex;
144155
width: min(25vw, 350px);
156+
flex-shrink: 0;
157+
margin: 0;
158+
order: 0;
145159
float: none;
146160
position: sticky;
147161
top: 0;
@@ -158,8 +172,14 @@ div.sphinxsidebar h4 {
158172
margin-top: 1.5em;
159173
}
160174

161-
div.bodywrapper {
162-
margin-left: min(25vw, 350px);
175+
div.document div.bodywrapper {
176+
margin: 0;
177+
}
178+
179+
div.documentwrapper {
180+
flex: 1;
181+
min-width: 0;
182+
order: 1;
163183
}
164184

165185
div.sphinxsidebarwrapper {
@@ -179,6 +199,11 @@ div.sphinxsidebarwrapper > ul > li > ul > li {
179199
margin-bottom: 0.4em;
180200
}
181201

202+
div.sphinxsidebar ul ul {
203+
margin-left: 0;
204+
margin-inline-start: 20px;
205+
}
206+
182207
div.sphinxsidebar a:hover {
183208
color: #0095c4;
184209
}
@@ -206,16 +231,23 @@ div.sphinxsidebar input[type='text'] {
206231
border-left: none;
207232
}
208233

234+
body[dir='rtl'] #sidebarbutton {
235+
border-radius: 5px 0 0 5px;
236+
border-right: none;
237+
border-left: none;
238+
}
239+
209240
#sidebarbutton:hover {
210241
background-color: #AAAAAA;
211242
}
212243

213244
div.body {
214-
padding: 0 0 0 1.2em;
245+
padding: 0;
246+
padding-inline-start: 1.2em;
215247
}
216248

217249
div.body p, div.body dd, div.body li, div.body blockquote {
218-
text-align: left;
250+
text-align: start;
219251
line-height: 1.6;
220252
}
221253
div.body h1, div.body h2, div.body h3, div.body h4, div.body h5, div.body h6 {
@@ -225,6 +257,10 @@ div.body h1, div.body h2, div.body h3, div.body h4, div.body h5, div.body h6 {
225257
}
226258
div.body dl.field-list > dt {
227259
line-height: 1.6;
260+
padding-left: 0;
261+
padding-right: 0;
262+
padding-inline-start: 0.5em;
263+
padding-inline-end: 5px;
228264
}
229265

230266
div.body hr {
@@ -233,6 +269,22 @@ div.body hr {
233269
height: 1px;
234270
}
235271

272+
body[dir='rtl'] {
273+
& pre,
274+
& code,
275+
& div.highlight,
276+
& dl > dt span ~ em,
277+
& .sig,
278+
& .sig-param {
279+
direction: ltr;
280+
unicode-bidi: isolate;
281+
}
282+
}
283+
284+
body[dir='rtl'] .sig {
285+
text-align: right;
286+
}
287+
236288
div.body pre {
237289
border-radius: 3px;
238290
border: 1px solid #ac9;
@@ -402,7 +454,7 @@ table.docutils th {
402454

403455
table p,
404456
table li {
405-
text-align: left !important;
457+
text-align: start !important;
406458
}
407459

408460
table.docutils th {
@@ -414,11 +466,37 @@ table.footnote td {
414466
border: 0 !important;
415467
}
416468

469+
body[dir='rtl'] div#search-results,
470+
body[dir='rtl'] div#search-results ul.search li {
471+
direction: rtl;
472+
text-align: right;
473+
unicode-bidi: isolate;
474+
}
475+
476+
body[dir='rtl'] div#search-results ul.search li p {
477+
text-align: right;
478+
}
479+
480+
body[dir='rtl'] div.citation > span {
481+
float: right;
482+
}
483+
484+
body[dir='rtl'] aside.footnote > span {
485+
float: right;
486+
padding-right: 0;
487+
padding-left: 0.5rem;
488+
}
489+
490+
body[dir='rtl'] aside.footnote > p {
491+
margin-left: 0;
492+
margin-right: 2rem;
493+
}
494+
417495
div.footer {
418496
line-height: 150%;
419-
text-align: right;
497+
text-align: end;
420498
width: auto;
421-
margin-right: 10px;
499+
margin-inline-end: 10px;
422500
}
423501

424502
div.footer a {
@@ -476,18 +554,17 @@ div.footer a:hover {
476554
color: var(--threadsafety-atomic);
477555
}
478556

479-
480557
dl > dt span ~ em,
481558
.sig {
482559
font-family: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace;
483560
}
484561

485562
.toctree-wrapper ul {
486-
padding-left: 20px;
563+
padding-inline-start: 20px;
487564
}
488565

489566
.theme-selector {
490-
margin-left: .5em;
567+
margin-inline-start: .5em;
491568
}
492569

493570
div.genindex-jumpbox,
@@ -506,17 +583,17 @@ div.genindex-jumpbox a {
506583
cursor: pointer;
507584
position: absolute;
508585
top: 0;
509-
right: 0;
586+
right: 0; /* physical right; always, even in RTL, since code is LTR */
510587
font-family: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace;
511588
font-size: 80%;
512589
padding-left: .5em;
513590
padding-right: .5em;
514591
height: 100%;
515592
max-height: min(100%, 2.4em);
516-
border-radius: 0 3px 0 0;
593+
border-radius: 0 3px 0 0; /* physical — top-right corner, always */
517594
color: #000;
518595
background-color: #fff;
519-
border: 1px solid #ac9; /* follows div.body pre */
596+
border: 1px solid #ac9;
520597
display: none;
521598
}
522599

@@ -589,7 +666,7 @@ div.genindex-jumpbox a {
589666
width: 100%;
590667
position: fixed;
591668
top: 0;
592-
left: 0;
669+
inset-inline-start: 0;
593670
box-shadow: rgba(0, 0, 0, 0.25) 0 0 2px 0;
594671
z-index: 1;
595672
}
@@ -611,7 +688,7 @@ div.genindex-jumpbox a {
611688
align-items: stretch;
612689
}
613690
.nav-logo {
614-
margin-right: 1rem;
691+
margin-inline-end: 1rem;
615692
flex-shrink: 0;
616693
align-self: center;
617694
}
@@ -620,7 +697,7 @@ div.genindex-jumpbox a {
620697
width: 20px;
621698
}
622699
.version_switcher_placeholder {
623-
margin-right: 1rem;
700+
margin-inline-end: 1rem;
624701
}
625702
.version_switcher_placeholder > select {
626703
height: 100%;
@@ -630,25 +707,27 @@ div.genindex-jumpbox a {
630707
flex: auto;
631708
border: 1px solid #a9a9a9;
632709
align-items: stretch;
710+
position: relative;
633711
}
634712
.nav-content .search input[type=search] {
635713
border: 0;
636-
padding-left: 24px;
714+
padding-inline-start: 24px;
637715
width: 100%;
638716
flex: 1;
639717
}
640718
.nav-content .search input[type=submit] {
641719
height: 100%;
642720
box-shadow: none;
643721
border: 0;
644-
border-left: 1px solid #a9a9a9;
722+
border-inline-start: 1px solid #a9a9a9;
645723
cursor: pointer;
646-
margin-right: 0;
724+
margin-inline-end: 0;
647725
}
648726
.nav-content .search svg {
649727
position: absolute;
650-
align-self: center;
651-
padding-left: 4px;
728+
top: 50%;
729+
transform: translateY(-50%);
730+
inset-inline-start: 4px;
652731
}
653732
.toggler__input {
654733
display: none;
@@ -680,7 +759,7 @@ div.genindex-jumpbox a {
680759
width: 100%;
681760
background: inherit;
682761
position: absolute;
683-
left: 0;
762+
inset-inline-start: 0;
684763
top: -8px;
685764
}
686765
.toggler__label > span::after {
@@ -701,29 +780,36 @@ div.genindex-jumpbox a {
701780
}
702781
.toggler__input:checked ~ .menu-wrapper {
703782
visibility: visible;
704-
left: 0;
783+
transform: translateX(0);
705784
}
706785

707786
/* Sliding side menu */
708787
.menu-wrapper {
709788
display: block;
710789
position: fixed;
711790
top: 0;
712-
transition: left 400ms ease;
713-
left: -310px;
791+
inset-inline-start: 0;
792+
transition: transform 400ms ease;
793+
transform: translateX(calc(-100% - 10px));
714794
width: 300px;
715795
height: 100%;
716796
background-color: #eee;
717797
color: #444444;
718798
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
719799
overflow-y: auto;
720800
}
801+
body[dir='rtl'] .menu-wrapper {
802+
transform: translateX(100%);
803+
}
721804
.menu-wrapper.open {
722805
visibility: visible;
723-
left: 0;
806+
transform: translateX(0);
724807
}
725808
.menu {
726-
padding: 40px 10px 30px 20px;
809+
padding-block-start: 40px;
810+
padding-inline-end: 10px;
811+
padding-block-end: 30px;
812+
padding-inline-start: 20px;
727813
}
728814
.menu-wrapper h3,
729815
.menu-wrapper h4 {
@@ -748,10 +834,10 @@ div.genindex-jumpbox a {
748834
list-style: none;
749835
line-height: 1.4;
750836
overflow-wrap: break-word;
751-
padding-left: 0;
837+
padding-inline-start: 0;
752838
}
753839
.menu ul ul {
754-
margin-left: 20px;
840+
margin-inline-start: 20px;
755841
list-style: square;
756842
}
757843
.menu ul li {
@@ -807,26 +893,26 @@ div.versionadded,
807893
div.versionchanged,
808894
div.deprecated,
809895
div.deprecated-removed {
810-
border-left: 3px solid;
896+
border-inline-start: 3px solid;
811897
padding: 0 1rem;
812898
}
813899

814900
div.versionadded {
815-
border-left-color: var(--versionadded-border);
901+
border-inline-start-color: var(--versionadded-border);
816902
}
817903

818904
div.versionchanged {
819-
border-left-color: var(--versionchanged-border);
905+
border-inline-start-color: var(--versionchanged-border);
820906
}
821907

822908
div.deprecated,
823909
div.deprecated-removed,
824910
div.versionremoved {
825-
border-left-color: var(--deprecated-border);
911+
border-inline-start-color: var(--deprecated-border);
826912
}
827913

828914
div.soft-deprecated {
829-
border-left-color: var(--soft-deprecated-border);
915+
border-inline-start-color: var(--soft-deprecated-border);
830916
}
831917

832918
div.versionadded .versionmodified {

0 commit comments

Comments
 (0)