Modifying content width of the Sphinx theme 'Read the Docs' - html

I am using 'Read the Docs' Sphinx theme for my documentation. In the original theme, given below
Read the Docs Sphinx Theme
the content or main layout width is designed to be mobile friendly. However, for my project I would like this to be a bit more wide. I do not know HTML and hence would appreciate if any one could give me some clues to increase the content (layout) width.

Another option is to create a stylesheet in source/_static with just the css you want, e.g.
.wy-nav-content {
max-width: none;
}
or
.wy-nav-content {
max-width: 1200px !important;
}
Make sure the directory is referenced in source/conf.py - I believe by default there's a line to do this, i.e.
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
Then create a custom layout in source/_templates/layout.html and do something like this to include your stylesheet
{% extends "!layout.html" %}
{% block extrahead %}
<link href="{{ pathto("_static/style.css", True) }}" rel="stylesheet" type="text/css">
{% endblock %}
Assuming you called your stylesheet style.css

In case someone is searching for a simpler answer...
combining the ideas from
https://samnicholls.net/2016/06/15/how-to-sphinx-readthedocs/
and the above suggestions, I found the easiest way of getting a custom window-width is the following:
In conf.py, add a function that adds a custom stylesheet:
def setup(app):
app.add_css_file('my_theme.css')
In conf.py, state/adjust:
html_static_path = ['_static']
Create a _static folder/directory if it doesn't exist.
Create a file called my_theme.css in the _static folder that contains the lines:
.wy-nav-content {
max-width: 1200px !important;
}

The HTML option added in Sphinx 1.8.0b1 (released Sep 2018) simplifies the process. The recommendation in Read The Docs Documentation is adding custom css to the theme via the html_css_files option in conf.py.
html_css_files = [
'custom.css',
]
Put the custom.css in the html static path folder (Default is _static folder).
Content of custom.css:
.wy-nav-content {
max-width: 75% !important;
}

First of all I must say, that during my sphinx quickstart I chose the option of separate folder for my sources and for my build.
It's a 3 steps process:
1. Create a document for your styles:
Where?
In the same directory where my conf.py lives, (in my case source), I created a folder for my custom static files (stylesheets, javascripts). I called it custom.
Inside it I created a subfolder for my stylesheets: source/custom/css.
In this subfolder I'm gonna create my custom styles: source/custom/css/my_theme.css.
2. Telling sphinx about it
Now we have to tell sphinx to spit this document inside build/_static/css, the same directory where is the stylesheet included in the Read The Documents theme. We do that adding the following line to conf.py:
html_static_path = ['custom'] # Directory for static files.
Done. Now, if we build, we will have the RTD styles (theme.css), and our custom my_theme.css in the same directory, build/_static/css.
3. Selecting our custom theme
Now we are gonna tell sphinx to use our custom my_theme.css, instead of the RTD one. We do that adding this line in conf.py:
html_style = 'css/my_theme.css' # Choosing my custom theme.
In our custom stylesheet, the first line should import the styles of theme.css with #import url("theme.css");.
And we are ready to start overwriting styles.
UPDATE: THERE IS AN EVEN SIMPLER WAY.
1. Put your customizations inside source/_static/css/my_theme.css.
In your custom stylesheet, the first line should import the styles of theme.css with #import url("theme.css");.
This way, you don't have to worry about messing up the default styles, if your custom stylesheet doesn't work, delete and start again.
2. Add the following line in conf.py:
html_style = 'css/my_theme.css'

The solutions here are somewhat hackish. If you want to include the style, and have a css override and have it work on RTD you will want something like this.
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
if not on_rtd: # only import and set the theme if we're building docs locally
import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
html_style = 'css/custom.css'
else:
html_context = {
'css_files': [
'https://media.readthedocs.org/css/sphinx_rtd_theme.css',
'https://media.readthedocs.org/css/readthedocs-doc-embed.css',
'_static/css/custom.css',
],
}
I have tested this myself and it appears to work locally and on RTD. Largely plagiarized from https://blog.deimos.fr/2014/10/02/sphinxdoc-and-readthedocs-theme-tricks-2/

source\conf.py
html_theme = 'sphinx_rtd_theme'
html_style = 'css/my_theme.css'
source\_static\css\my_theme.css
#import url("theme.css");
.wy-nav-content {
max-width: 90%;
}
That will be 90% width of your monitor.

I found myself repeating this customization on multiple projects I've worked on (based on the great answers here, of course 😃 ).
So I made an extension just for that, the usage is as follows:
pip install sphinx-rtd-size
And in the conf.py:
extensions = [
...
'sphinx_rtd_size',
]
sphinx_rtd_size_width = "90%"
Hoping this might simplify things for future users...
You can checkout the pypi page and the github repository.

For 'classic' Theme, The solution is as simple and as clean as :
# Add/Update "html_theme_options" like this on your conf.py
html_theme_options = {'body_max_width': '70%'}
Adapt the percentage to your taste.
Reference from sphinx: body_max_width (int or str): Maximal width of the document body. This can be an int, which is interpreted as pixels or a valid CSS dimension string such as ‘70em’ or ‘50%’. Use ‘none’ if you don’t want a width limit. Defaults may depend on the theme (often 800px).

To make the ReadTheDocs theme use the entire width of your screen you can modify the theme.css file, removing the max-width: 800px; property from the wy-nav-content class definition, like so:
.wy-nav-content {
padding: 1.618em 3.236em;
height: 100%;
/* max-width: 800px; */
margin: auto;
}
Some Notes
Source of theme.css is here:
https://github.com/rtfd/readthedocs.org/blob/master/media/css/sphinx_rtd_theme.css
On your filesystem it will be in (assuming you've run:pip install sphinx_rtd_theme):
lib/python2.7/site-packages/sphinx_rtd_theme/static/css/theme.css
To find the absolute path of theme.css on Linux/Mac you can run this on the command line (assuming you have set your $PYTHONPATH environment variable):
for p in `echo $PYTHONPATH | tr ":" "\n"`; do
find $p -type f -name 'theme.css' | grep sphinx_rtd_theme
done
The theme.css file will be minified so you can use a tool like http://unminify.com to make it easier to read.
The results:
Before:
After:

I would modify this in the css. You should search for the file theme.css (it is in the read-the-doc sources at "sphinx_rtd_theme/static/css/theme.css").
Make a copy of that file and put it in your sphinx _static dir. In that css file you can make all the layout changes that you need. (You might have to read a bit on css files if you have never worked with that.)
Hope this helps.

Related

CSS #import with URL / Path specified as a custom property (variable)

I was thinking about a convenient way to create and use themes in HTML / CSS / JS. One possible solution I was thinking of was specifying the path to the theme file as a variable and importing the theme file in the main stylesheet via said variable so something along these lines:
:root {
--theme: url("default-theme.css");
}
#import var(--theme);
This way, if later the theme needs to be changed (for instance for Halloween or for the holiday season etc), the theme can be updated by either manually updating the value of the CSS variable or by using JS / TS to programmatically update the value.
I have tried a couple of different iterations of this including:
:root {
--theme: "default-theme.css";
}
#import var(--theme);
and
:root {
--theme: "default-theme.css";
}
#import url(var(--theme));
But sadly, nothing seems to work. I have also read through the documentation for CSS custom properties and CSS import and so far I have not really found anything.
Here is some editable sample code on StackBlitz. If anyone has any advice or suggestions or some wisdom to share, I will be extremely appreciative.

gatsby HTML file size too large (i.e. due to bootstrap-CSS)

Problem
When I build my gatsby website with "gatsby build", the size of the generated HTML and CSS files is fairly large (approx. 200kB; even though there is close to zero real text-content in it).
When looking into the generated HTML-file, it turns out, that in each and every generated HTML-file, the complete global CSS is (in text-form) included. So it is completly redundant.
In my case: I use bootstrap as frontend framework, so all the bootstrap-css-classes (used and unused ones) are
100% included in the generated HTML-files
AND additionally: in the seperate "styles.ac6d....css" file.
To clarify: What I get after the gatsby built:
index.html 210 kB
about.html 210 kB
imprint.html 210 kB
....
style.css 200 kB
Expected Behaviour
What I would have expected after the gatsby built:
index.html 10 kB
about.html 10 kB
imprint.html 10 kB
....
style.css 200 kB
I would like to have small HTML-files without any unused CSS in it OR at least not to have the CSS redundently in 20 different files.
Questions
Is it possible to get gatsby built HTML-files without all CSS redundently included in every file?
AND / OR: Is it possible to have only the needed CSS-classes in the file (especially in the case of bootstrap)?
Am I doing something wrong here?
Additional Infos
How do I import the bootstrap CSS?
in global.scss:
#import "./node_modules/bootstrap/scss/bootstrap
in gatsby-browser.js
import "./src/styles/global.scss"
How does the compiled HTML look like?
The compiled HTML in index.html (and about.html, ...) from gatsby looks like so:
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta http-equiv="x-ua-compatible" content="ie=edge"/><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/><style data-href="/styles.ac6d966df9cf852917cd.css" id="gatsby-global-css">/*!
* Bootstrap v4.6.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;
<!-- .... [ALL THE REST OF BOOTSTRAP CSS] -->
Edit: Conclusion for me
To inject the full global CSS in all the HTML files seems to be a normal behavior from the gatsby build process according to the comments. So just in case anybody else wonders about this gatsby behaviour...
I would go the SCSS way by importing a global styles.scss in which you only import the needed parts of the bootstrap distribution.
/*----------------------------------------------------
Overriden Bootstrap Variables (by me!!!!!)
------------------------------------------------------*/
$primary: #00B056;
$secondary: #bf9571;
$body-bg: #fff;
$body-color: #5a5a5a;
/*----------------------------------------------------
Import Bootstrap SCSS
------------------------------------------------------*/
// use this one only for debugging purposes. This is the whole package
//#import "../../../node_modules/bootstrap/scss/bootstrap";
// Required
#import "../../../node_modules/bootstrap/scss/functions";
#import "../../../node_modules/bootstrap/scss/variables";
#import "../../../node_modules/bootstrap/scss/mixins";
// Optional
#import "../../../node_modules/bootstrap/scss/reboot";
#import "../../../node_modules/bootstrap/scss/type";
#import "../../../node_modules/bootstrap/scss/images";
// add more bootstrap stuff as needed
There are of course more partial scss bootstrap packages available. Check their documentation for scss handling or check your node_modules path.
Of course you need to install bootstrap via npm/yarn to have it available. Also you need gatsby scss plugins like gatsby-plugin-sass and node-sass.
Among not using Bootstrap as #George suggested in #Logemann's answer, which in my opinion should be always avoided because tend to overload the applications and the same effect can be easily applied using own custom CSS.
I would suggest only importing the mandatory Bootstrap modules, rather than all the dependency to save some KB.
In addition, if get rid of Bootstrap is not an option I will try to look at some purging plugin, such as gatsby-plugin-purcecss to remove some duplicated styles in specific files.
// gatsy-config.js
module.exports = {
plugins: [
`gatsby-plugin-stylus`,
`gatsby-plugin-sass`,
`gatsby-plugin-less`,
`gatsby-plugin-postcss`,
// Add after these plugins if used
{
resolve: `gatsby-plugin-purgecss`,
options: {
printRejected: true, // Print removed selectors and processed file names
// develop: true, // Enable while using `gatsby develop`
// tailwind: true, // Enable tailwindcss support
// whitelist: ['whitelist'], // Don't remove this selector
// ignore: ['/ignored.css', 'prismjs/', 'docsearch.js/'], // Ignore files/folders
// purgeOnly : ['components/', '/main.css', 'bootstrap/'], // Purge only these files/folders
}
}
]
};

pdfHTML with in-memory CSS

I'm trying out iText7 and trying to piece together how to do things. It seems that I can put in a base URI to grab external resources which I'm assuming if it finds a .css it will apply that? I have a particular situation where it's easier for me to hold the CSS in memory as a string. It seems odd that I can use HtmlConverter.convertToPdf() and pass in HTML as a string but not CSS.
As a secondary question, what happens if it finds multiple CSS files at that base URI?
Finally (sorry for the dump), if the HTML contains FQDN URLs to images, I'm assuming/hoping it will pull the images directly? In other words, I'm hoping I don't also have to store/write those images to the specified base URI?
Thanks.
UPDATE: I put together a quick demo. I found out it will download images that have a full URL which is great.
However, it does not seem to be loading the CSS file that is in a folder I specified. The code:
StringBuilder sb = new StringBuilder(File.ReadAllText("demoHtml.html"));
// this folder, which is relative to the test .exe, contains a file called pdf.css
ConverterProperties props = new ConverterProperties().SetBaseUri("Content/Pdf");
FileStream fs = new FileStream("itext.pdf", FileMode.Create);
HtmlConverter.ConvertToPdf(sb.ToString(), fs, props);
And the CSS:
img {
max-width: 100%;
}
table {
vertical-align: top;
}
td ol {
-webkit-padding-start: 15px;
padding-left: 15px;
}
thead tr {
background: #aaa;
}
tr:nth-child(even) {
background: #eee;
}
Solution to question 1:
I'm trying out iText7 and trying to piece together how to do things. It seems that I can put in a base URI to grab external resources which I'm assuming if it finds a .css it will apply that? I have a particular situation where it's easier for me to hold the CSS in memory as a string. It seems odd that I can use HtmlConverter.convertToPdf() and pass in HTML as a string but not CSS.
Many hours i have spent finding the slution for this problem. Everything seemed right and i even asked a support question about the using of CSS files. In contrary to itext5 (itextsharp), itext7 can't manage an url with a space in it.
So locally testing in a path like this: c:/Path to project/project/name/wwwroot/ won't work (note the spaces)
I didn't notice this at first because i generated my path programmatically to my css folder:
var basepath = env.ContentRootPath + "\\wwwroot\\pdfcss\\";
Changed it to:
var basepath = #"G:\some-other\directory\pdfcss\";
Solution to question 2:
Now knowing this i could solve your second question:
As a secondary question, what happens if it finds multiple CSS files at that base URI?
Nothing, you will still have to insert the links into your html in the head element. If this isn't added you will not have any css!
Solution to question 3:
And indeed:
Finally (sorry for the dump), if the HTML contains FQDN URLs to images, I'm assuming/hoping it will pull the images directly? In other words, I'm hoping I don't also have to store/write those images to the specified base URI?
You can do the following:
<img id="logo"
src="https://xxxxx.blob.core.windows.net/path/to-image-
logo.png" />

html_theme_options vs. html_logo in conf.py using alabaster

hello all experienced Sphinx users,
since a few days I'm performing my first experiences with Sphinx for building a small documentation site. I'm playing around using the Alabaster theme. When I try to place a logo in the left upper corner it only works with using an entry in the build configuration file 'conf.py' like this:
html_logo = '_static/images/PJS-small.png'
when I try to use the Alabaster theme configuration like this
html_theme_options = {
'logo': '_static/images/PJS-small.png',
'logo_name': True,
'description': 'one more logo'
}
no logo appears above the sidebar.
I'd like to use the theme configurations because I'm able to place a subtitle and other things like that.
Does anyone have an idea how to use the Alabaster configurations like it is documented?
Thank you very much for helping.
As per the Alabaster installation instructions,
you have to add an html_sidebars setting to the conf.py file:
html_sidebars = {
'**': [
'about.html',
'navigation.html',
'relations.html',
'searchbox.html',
'donate.html',
]
}
This causes Alabaster’s customized sidebar templates to be loaded.
Then you can specify the logo path like this:
html_theme_options = {
'logo': 'images/PJS-small.png',
# etc.
}
The path is automatically prepended with _static/.
In the theme configuration (theme.conf) file, you need to use the following syntax:
logo = images/PJS-small.png
logo_name = true
description = one more logo
Note the absence of the _static directory in the logo path (it is prepended in the theme's HTML template) and the lowercase boolean.
Still, you can set any theme configuration variable through the html_theme_options object in the Sphinx project configuration file (conf.py).

More columns in Typo3 7.2 (Bootstrap)

I need to make a 4 column website with Bootstrap but in typo3 the default setting is to have 2 cols max. To be able to edit each column in backend I have created a layout following this tutorial: http://blog.sebastiaandejonge.com/articles/2012/july/26/implementing-typo3s-backend-layouts/
I cannot display content of the columns on frontend though.
In the template section for a page that uses this layout I have added
agptop1 < styles.content.get
agptop1.select.where = colPos = 20
agptop2 < styles.content.get
agptop2.select.where = colPos = 21
etc which are the positions set in the layout manager.
Now I should specify the variable like agptop1 so I created a template file among the other bootstrap templates in typo3conf\ext\bootstrap_package\Resources\Private\Templates\Page
It is a copy of the default template with some things changed like...
<f:layout name="Default"/>
<f:section name="Main">
<f:cObject typoscriptObjectPath="lib.dynamicContent" data="{pageUid: '{data.uid}', colPos: '3'}"/>
<div class="container">
<div class="row">
<div class="col-sm-3">
<f:cObject typoscriptObjectPath="lib.dynamicContent" data="{pageUid: '{data.uid}', colPos: '20'}"/>
<f:format.raw>{agptop1}</f:format.raw>
</div>
...like the line
<f:format.raw>
and the colPos. I suppose this is correct? I have found this somewhere here on SO.
But when I use this as a template directly in template editor of the page I need it for I only get blank page.
I cannot find out how are the default bootstrap templates linked to the Default.html and to manu configuration and how is this all linked to Backend Layout. I need to pick a backend layout, fill in the content, then something1 must tell something2 that I want to load standart page, standart menu but a specific template with the variables defined. How can this be done?
I'm sorry if it's too basic but it's my first day in typo3 and there is no manual for the new version.
The spaces on colPos = 20 are a problem in Typoscript. Using this should help:
agptop1.select.where = colPos=20
From your answer I assume, that your are using the plugin bootstrap_package. This plugin comes with some new predefined templates and you want to add one more, right?
Step 1 adding a new backendlayout
To add another option to your backend page-options, have a look into
BackendLayouts
Each file contains the description of one backend layout and each file is built the same way:
1. Defining a title (no need of using a language file here)
2. Defining the alignment (rows cols) of the content-container in the backend
3. Defining a icon
Just copy one of these files and modify it. These files have to be included in the page-layout and bootstrap_package does it automatically when it is installed. You can turn of this behaviour in the extension setting and include all backend layouts by your own. Therefor copy the file BackendLayouts.txt from bootstrap_package to your fileadmin, add your custom new layout and include the file in you pagets-config like so:
<INCLUDE_TYPOSCRIPT: source="FILE:fileadmin/template/typoscript/BackendLayouts.txt">
Note 1: For single files use 'FILE:' for Directories use 'DIR:'
Note 2: For pagets-config go to your root-page, edit it, got to resources and scroll down. Here it is. Enter code here.
If you have done it right you could now select your new layout from backend.
Step 2 Creating your own template
Copy one of the bootstrap_package template files and modify it, by only adding new cObject elements and what you need for your alignment.
<f:cObject typoscriptObjectPath="lib.dynamicContent" data="{pageUid: '{data.uid}', colPos: '2'}"/>
In addition copy the hole dir /typo3conf/ext/bootstrap_package/Resources/Private to the fileadmin and put your own template in the subdir 'Templates'
Step 3 Bring it together
As the last step you have to modify the typoscript-setup. I recommend to copy the bootstrap setup-files and include it manually rather then import it by static template.
So remove your static template "Boostrap Package (bootstrap_package)" copy the setup.txt and constant.txt from
/typo3conf/ext/bootstrap_package/Configuration/TypoScript/
to your fileadmin dir and include it like so:
Constants:
<INCLUDE_TYPOSCRIPT: source="FILE:fileadmin/template/typoscript/constants.txt">
Setup:
<INCLUDE_TYPOSCRIPT: source="FILE:fileadmin/template/typoscript/setup.txt">
After all you have to open your custom constant.txt file and add your own paths:
page {
...
fluidtemplate {
# cat=bootstrap package: advanced/100/100; type=string; label=Layout Root Path: Path to layouts
layoutRootPath = fileadmin/template/Private/Layouts/Page/
# cat=bootstrap package: advanced/100/110; type=string; label=Partial Root Path: Path to partials
partialRootPath = fileadmin/template/Private/Partials/Page/
# cat=bootstrap package: advanced/100/120; type=string; label=Template Root Path: Path to templates
templateRootPath = fileadmin/template/Private/Templates/Page/
}
...
}
And for the last step add your new template in the config.txt into the fluidtemplate-part 'page.10.templateName ...' doing some pattern-matching =)
10 = FLUIDTEMPLATE
10 {
templateName = TEXT
templateName.stdWrap.cObject = CASE
templateName.stdWrap.cObject {
key.data = levelfield:-1, backend_layout_next_level, slide
key.override.field = backend_layout
pagets__default_clean = TEXT
pagets__default_clean.value = DefaultClean
pagets__default_2_columns = TEXT
pagets__default_2_columns.value = Default2Columns
...
I hope, that i have described everything important. If you have trouble, have deep look into bootrack_package's source code. You can learn everything by miming what they have done.
Good luck