pydata / pydata-sphinx-theme

A clean, three-column Sphinx theme with Bootstrap for the PyData community
https://pydata-sphinx-theme.readthedocs.io
BSD 3-Clause "New" or "Revised" License
597 stars 312 forks source link

Consistent use of monospaced font #1852

Open mdhaber opened 4 months ago

mdhaber commented 4 months ago

I think it would be helpful if code tokens were consistently rendered in monospaced font. For instance, in the documentation of scipy.stats.bootstrap, text that refers to code is rendered in many different styles.

  1. The navigation pane uses proportional font:

    image
  2. The scipy.stats table of contents mixes monospaced and proportional font in the function signature:

    image
  3. In the scipy.stats.bootstrap page, the title heading uses proportional font:

    image
  4. The signature is all monospaced and bold, but some is italicized and some is not:

    image
  5. Parameters of the function enclosed in single backticks appear in proportional font with emphasis:

    image

(Although this situation may be improved by numpy/numpydoc#525 and linked issues.)

  1. Double backticks result in monospaced font with a gray background and pink text:

    image
  2. The names of parameters in the parameter descriptions use bold, proportional font:

    image
  3. The type descriptions use bold, italicized, proportional font; double backticks can be used for additional stylization:

    image

(Please feel free to add other ways that code appears. I think that the numbers will help us refer to distinct cases as needed.)

This issue could be generalized to be about consistent use of color, boldface, italics, etc..., but I thought it would be best to be a little more targeted here. So my suggestion is that that appearances of code should either all be monospaced or all proportional. My initial motivation is from the perspective of consistency and aesthetics, but I think there is also an accessibility perspective to be considered. Personally, I think that monospacing is a helpful visual cue to distinguish code from other text, so I would prefer that all code be monospaced, but I recognize that there may be arguments in the other direction.

melissawm commented 3 months ago

See https://github.com/scipy/scipy/pull/20890

trallard commented 3 months ago

Hey folks. I know some variation across style weight, colour is intentional (albeit not perfectly executed) to visually differentiate functions from params and the likes.

However I agree there are other further inconsistencies and overall improvements we can make to end up with a more coherent style.

Tagging @isabela-pf and @smeragoel for visibility and so that we can add this to our design backlog

smeragoel commented 1 month ago

Thank you for bringing this up! After researching various ways to address this issue and conducting thorough internal discussions, we’ve come up with the following final recommendations:

S.no Category Description Example Pages / Links on PyData Sphinx Theme Current Text Formatting Recommendation / Discussion
A. Navigation Pane This refers to the headings in the Section Navigation on the left side of the webpage. Section Navigation Proportional We should switch to Monospace. This is a recurring design pattern in other documentation themes and will help in clear identification of code-text.
B. Table of Contents Function signatures in ToC Functions ToC Monospace, Proportional All text in the function signature should be monospaced. This includes function name, parameters, kwargs, type annotation, default values etc.
C. Title Heading Main headings on documentation pages which contain code-text. Title Heading Proportional Code-text in headings should be monospaced, but normal text should be proportional. Also, code-text should not wrap or break. Example: 1. Heading with normal and code-text: This is a page about math.h 2. Heading with just code-text: math.h
D. Function Signature Representation of function names and parameters. Function Signature Monospace, bold, italic This code text is very busy visually so we should simplify the text formatting. Here’s the redesigned function signature: Figma Design
E. Parameter names in descriptions Descriptions of function parameters. Parameter Descriptions Proportional, bold Description text will remain proportional.
F. Parameter Type Description of parameter data types Parameter Type Proportional, italics Description text will remain proportional.
G. Function Source Link Source link to the original function headers Function Source Link Monospace, bold Source link does not refer to code text, and should be treated as a normal link and should be proportional text.

The most significant changes are in the function signature and definition formatting (D - G):

  1. Class name is no longer bold.
  2. Parameters now use a muted text color.
  3. Default values are not bold and are displayed in green.
  4. Type annotations are no longer bold and are shown in blue.
  5. The source link text is proportional and no longer bold.
  6. The heading text for parameters, returns, and return types now has a muted color.
  7. Padding between paragraphs has been increased for better readability.

I’ve also prepared a document outlining the findings and discussion points in more detail, including a heavy table that couldn’t be rendered properly in md: Code-Text Styling Consistency Findings

Looking forward to hearing your thoughts and feedback!

mdhaber commented 1 month ago

Thanks for working on this!

Do I understand that at the "Figma Design" page, "Current Screenshot" is what we have now, and "Template" is the proposed design?


In the Code-Text Styling Consistency Findings, I see in the "Discussion" (emphasis yours):

  1. Should parameters be monospaced or proportional? Parameters are currently being styled differently for different locations. For consistency, we should ensure a similar text treatment. My recommendation would be to use monospaced parameters, to ensure clarity and consistency and make it easy for users to differentiate between code and regular text.

and

  1. My understanding about parameters data type (int, list, str) is that it is code text and hence should be monospaced

I think these are referring to items E and F in the table above, but I'm not sure what the conclusion was for those. It says "Description text will remain proportional" (emphasis mine), which I would certainly agree with, but it does not mention the parameters (code) themselves or types (code) specifically. What was the conclusion about the formatting of parameter names and types?

trallard commented 4 weeks ago

Do I understand that at the "Figma Design" page, "Current Screenshot" is what we have now, and "Template" is the proposed design?

That is correct.

I think these are referring to items E and F in the table above, but I'm not sure what the conclusion was for those. It says "Description text will remain proportional" (emphasis mine), which I would certainly agree with, but it does not mention the parameters (code) themselves or types (code) specifically. What was the conclusion about the formatting of parameter names and types?

Parameters, types, and descriptions will be in proportional font, as indicated in the table above; this is also presented in the Figma parameters subsection:

Figma parameters subsection template for PST

mdhaber commented 4 weeks ago

Right, I saw the table refered to the description text, but thanks for clarifying that the code (parameter name and types) would also be in proportional font. I see in the discussion that proportional font is used for these parts in some other themes (Furo and Read the Docs) - was that the deciding factor against the preliminary recommendation?

smeragoel commented 3 weeks ago

Thanks for your questions @mdhaber!

While usage patterns definitely play an important role in this decision, the deciding factor was that descriptions are not meant to contain copy-paste code. Code-text, by contrast, indicates something that users can copy and paste directly into their code. That distinction is why we opted for proportional fonts in descriptions.

mdhaber commented 3 weeks ago

I see. I was under the impression that code-text (monospaced font) indicated code, whether or not it is to be copy-pasted. Does this mean that users are encouraged to copy-paste from the navigation pane, table of contents, page title, and signature?

dbitouze commented 3 weeks ago

I was under the impression that code-text (monospaced font) indicated code, whether or not it is to be copy-pasted.

I'm exactly under the same impression.

trallard commented 3 weeks ago

Does this mean that users are encouraged to copy-paste from the navigation pane, table of contents, page title, and signature?

That's not precisely what @smeragoel was saying. But we considered where the focus (reading/context/copy) would be from a reader POV on top of loosely adopted conventions, similar themes etc. while evaluating the use of proportional/monospaced font.

Also who can say exactly where readers copy and paste from? 🤷🏽‍♀️ Basically if there is text that is selectable anywhere on the screen users are/should be able to copy/will copy.

And also yes, monospace typefaces are often used to indicate code (but also some people use monospace typefaces for the main body and other components). There is no set rule or standards to indicate what type of font is to be used when/for what so Smera tried to balance accessibility, usability, legibility, consistency, and style while looking into this.

smeragoel commented 3 weeks ago

Thanks for the great points, everyone!

To clarify:

For the monospaced fonts used in places like navigation panes, titles, tables of contents, etc., these are generally applied when those elements include code literals. In these cases, monospaced fonts are used for visual clarity (this text refers to code) and consistency, rather than to encourage copy-pasting.

When it comes to function signatures, we use monospaced fonts for the entire signature because it’s important that users see exactly how the function should be written or copied. My earlier mention of copy-paste was to emphasize that the function signature should be treated exactly as shown. This doesn’t mean that all code literals are intended to be directly copy-pasted, but rather that the function signature needs to be precise for usage, and a user could copy-paste it if needed.

The description text is meant to provide additional context and explanations and isn't meant to be used verbatim. The parameters are also displayed in monospaced fonts within the function signature, so there’s no need to repeat that styling in the description. If we make the parameters monospaced in the description it would introduce visual noise and reduce readability, as proportional fonts are generally easier to read, especially in longer explanations. If a new parameter or code literal is being referenced for the first time in the description (without being mentioned in the signature), it would make sense to use monospaced fonts there. However, in this case, since we are referring to something already displayed as code, using proportional fonts helps maintain readability and flow.

I hope this helps clarify the rationale behind using these different font styles for various contexts. I’m happy to hear your thoughts!

mdhaber commented 2 weeks ago

That's not precisely what @smeragoel was saying.

Thanks for the clarification! In any case, now I understand that the criteria were more holistic rather than following a rule about whether text is copy-pastable or code.

I’m happy to hear your thoughts!

Great. I wanted to understand yours better before I wrote them, but now that I do:

I think the theme should follow a rule: "Code appears in monospaced font."

I see that some of the themes considered do not follow this rule, so it is not universal. However, it is very common for code to appear in monospaced font. My first piece of evidence is anecdotal, but it may be the strongest: although configurable, the default font of all terminals and code editors I've used has been monospaced. Please let me know if you have counter-examples - I'd be very interested in whether my experience is just a coincidence.

Also, the rule to make all code appear in monospaced font appears to be standard in the official R, Matlab, and Julia language documentation themes. If there are discrepancies, they seem to be accidents rather than structural. Please consider the documentation of R's t.test, Matlab's ttest, and Julia's OneSampleTTest for easy comparison.

As for why this is done, I can't think of a better way of rephrasing what @smeragoel's wrote:

In these cases, monospaced fonts are used for visual clarity (this text refers to code)

I think that rationale always applies - especially in the parameter descriptions, where code tokens and English are interspersed.

so there’s no need to repeat that styling in the description

Ah, but the trouble with not using monospace font consistently is that the same English tokens are also used for English words. We need a visual cue to make the distinction between a variable a (a very common one!), the English word a, and the mathematical symbol a immediately obvious.

That is: we need a visual cue to make the distinction between a variable a (a very common one!), the English word "a", and the mathematical symbol $a$ immediately obvious.

If we make the parameters monospaced in the description it would introduce visual noise and reduce readability

I agree that there is a balance to strike when considering visual noise. Note that in the proposed theme, there is still variation in appearance here - just that it's bold and italics instead of monospacing. And as for readability, I would suggest that it is as readable in this context as the others. If other considerations outweigh the readability concern there, why not here?

(Another idea to reduce visual noise associated with code would be to eliminate the gray background and pink color associated with inline code, as the one visual cue may be sufficient. If monospacing alone is deemed too subtle and the other visual cues are needed, perhaps it does not add very much visual noise after all. This is a separate consideration I chose to leave out of the original post to simplify the discussion, though.)

but also some people use monospace typefaces for the main body and other components

For that reason, the theme documentation might recommend that monospace font be used only for code, pseudocode, code-like proxy for mathematics[^1], ASCII art, and other circumstances where spacing management is essential and is impractical to accomplish otherwise. But is it common for it to be used otherwise? I can think of one (unfortunate) type of example (documenting error codes) which is probably due to limitations of reST, but I can't think of other common cases. Other examples might help me understand.


As a library maintainer myself, I respectfully defer to the maintainers' choice. I just hope that this opinion will be considered and found persuasive! Thanks for reading!

[^1]: I'd prefer that this be avoided, too, but I'm told that people still read documentation in terminals, in which the math doesn't render.

lagru commented 2 weeks ago

Thanks for the the discussion and work around this! Using monospaced fonts for an object is a very clear signal to most folks used to technical documentation I imagine.

Just to give another opinion from a user of the theme, I find what @mdhaber is proposing convincing.

If we make the parameters monospaced in the description it would introduce visual noise and reduce readability

I totally agree with the statement! But personally, I wouldn't assign as much weight to this aspect. Also, I'd argue that the current and currently proposed rendering is already quite busy due to using bold and italics style. My intuitive rendering approach would be:

Re: Proposed signature formatting

Personally, I'm finding the proposed formatting of the signature that makes more use of bright color, less clear. The color makes the type annotation and default stand out way more than the parameter names which are arguably more important for skimming. I would prefer more subtle colors, perhaps gray as before. Also, a visual space should follow the : from the annotation. And = should be surrounded by spaces if an annotation is present.


But I recognize that it's very much a matter of aesthetic, familiarity and trade-offs. And this is also hopefully something that can be customized with CSS overrides if someone feels motivated enough. So regardless on how this turns out, many of the other proposed changes would be a already a big improvement in my book! Thanks for that. :blush:

Carreau commented 2 weeks ago

Even if this issue is likely to get closed (for now), nothing prevent us from refining later.

It is easier to have progressive changes, get feedback and the current changes, and push further if there is a need and desire.

There are limitation, due to sphinx, but also historical reasons (functions signatures used to not have types... etc), which leads to inconsistencies (in numpydoc for example, sometime the types in descriptions are phrases ("an array of strings"), sometime they are actual types.

I think that what we have is a progress, and the issue is starting to be busy. So once this is closed I suggest we open a new issue with specific suggested improvements.

stefanv commented 2 weeks ago

To move ahead, it would help if we had agreement over the one item that generated some discussion. I think it would be very difficult to do away with having a consistent mechanism for representing code and variables, INCLUDING in descriptions. This feature (most commonly implemented as monospace) is more-or-less ubiquitous across programming language documentation systems.

My personal preference is that we also attempt to restrict the use of monospace to code and variables, since it then immediately is apparent to the reader what those styles mean. Once they start being used for other things, that is no longer the case.

Once we have agreement on the above, filing issues for targeted improvements seems like a fine route forward.

Carreau commented 2 weeks ago

I think we all agree, it's just a technical limitation that sometime we don't know if something is code/variable.

mdhaber commented 2 weeks ago

Could you elaborate on that @Carreau? The rationale above did not stress technical limitations. It didn't sound like there was agreement with the rule that code should appear in monospaced font, but it would be terrific if there were IMO.

Also, do you mean that we can't use backticks to indicate which elements are monospaced? For example, I'd like

my_parameter : int, float, or ``MyCustomType``, optional

to appear like:

my_parameter : int, float, or MyCustomType, optional

It seems that it could be inferred that my_parameter is code; int and float, too, ideally. Can we include backticks for the rest? ( I think I've tried, and I don't think it worked - is that the sort of technical limitation you're referring to?)

drammock commented 2 weeks ago

Sorry to chime in late here (and FYI: responding with my theme-user hat on, not theme-maintainer hat):

The parameters are also displayed in monospaced fonts within the function signature, so there’s no need to repeat that styling in the description. [...] If a new parameter or code literal is being referenced for the first time in the description (without being mentioned in the signature), it would make sense to use monospaced fonts there. However, in this case, since we are referring to something already displayed as code, using proportional fonts helps maintain readability and flow.

I don't find this convincing. If we followed that logic to its conclusion, then within a given docstring only the first mention of a variable or parameter would get set in monospace font. But that isn't what anyone does; see e.g. the "notes" section of the SciPy FFT function where x appears 7 times, always monospaced. And as mentioned elsewhere, it's often a helpful cue tipping of the reader that the text refers to (for example) the type float and not the verb float. I agree that text can get hard to read if every third or fourth word is monospaced in a paragraph, but users can (and should) write the parameter descriptions in ways that minimize/avoid that if they want to.

If we make the parameters monospaced in the description it would introduce visual noise and reduce readability, as proportional fonts are generally easier to read, especially in longer explanations.

I agree with @lagru that although this is true strictly speaking, it maybe shouldn't be a very influential consideration. The parameter names themselves are not part of longer explanations, they are effectively dictionary headings (single words, often at a different level of indentation, always at the start of a line...). So for me the only uncertainty is how to handle the type descriptions, which can start to look a little odd going in and out of monospace, e.g.

tuple of float | array-like, shape (n_features, n_samples)

...so I can see the point of wanting those to be all typeset as proportional. I'm on the fence about that but lean toward allowing monospace because it's what I'm used to. However, note that it's complicated by the fact that numpydoc will try to auto-create cross-references on known terms in that line, so even if you default to proportional for the parameter's allowed types, that's a possible route for monospace to sneak in anyway.

As an aside, @mdhaber's question about getting monospace on MyCustomType:

It seems that it could be inferred that my_parameter is code; int and float, too, ideally. Can we include backticks for the rest? ( I think I've tried, and I don't think it worked - is that the sort of technical limitation you're referring to?)

I believe that will not work with double-backticks but will look consistent if MyCustomType is added to numpydoc_xref_aliases in conf.py

Carreau commented 1 day ago

It seems that it could be inferred that my_parameter is code; int and float, too, ideally. Can we include backticks for the rest? ( I think I've tried, and I don't think it worked - is that the sort of technical limitation you're referring to?)

Sure we could, but I don't think this is the case right now.

I think if we can show that the majority of numpy docstring are properly parsed, and have backticks where it needs to be then we can tweak the theme to get monospace. the problem is that right now if we turn on monospace I believe everything that is after the :, is treated at one thind is monospace which would lead to:

my_parameter : int, float, or MyCustomType, optional

I might be wrong but it is what I do seem to remember.

If we coudl write:

   my_parameter : int, float, or ``MyCustomType``, optional

That would be great, but doesn't that sort of imply you should actually write:

   other_parameter : ``MyCustomType``

Which I have never seen ?

The parameters are also displayed in monospaced fonts within the function signature, so there’s no need to repeat that styling in the description. [...] If a new parameter or code literal is being referenced for the first time in the description (without being mentioned in the signature), it would make sense to use monospaced fonts there. However, in this case, since we are referring to something already displayed as code, using proportional fonts helps maintain readability and flow.

I tend to disagree with this as well. Monospace/code have strong meaning so if something is a parameter it should always be monospace. It may be true in narrative text that monospace decrease the readability, but here monospace clearly delineate narrative from code, and you want code to be in a different style. It's for me the same as saying Japan is 日本(にほん) in japanese vs Japan is Nihon in japanese, the second is more readable for someone who does not speak japanese, while the target audience is a person using both language and for whom the first is both easier and carry more informations.