Skip to content

[FEATURE] Support text language and direction (lang/dir) in ReST - #1393

Open
linawolf wants to merge 1 commit into
mainfrom
task/container-lang-dir
Open

linawolf wants to merge 1 commit into
mainfrom
task/container-lang-dir

Conversation

@linawolf

@linawolf linawolf commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Resolves #1266
Resolves #1267

Authors had no way to mark a block, a run of inline text, or a whole
page as being in a different language or text direction, so the
rendered HTML never got the lang/dir attributes needed for correct
rendering (e.g. RTL scripts, screen readers, correct font/glyph
shaping). The maintainers asked what concrete output this should
produce.

docutils/Sphinx were checked for prior art before designing this:

  • Document level: neither has any per-document mechanism at all (only
    project-wide build config), so nothing to align with there.
  • Inline level: docutils' own FAQ recommends exactly :rtl:/:ltr:
    roles for this, just via .. role:: boilerplate the author has to
    write themselves; this makes them built-in instead.
  • Block level: docutils has .. class:: language-<tag> and
    .. class:: rtl/ltr, but that's CSS-only styling hooks with no
    real HTML lang/dir attribute, so it doesn't actually address the
    accessibility problem these issues are about. Kept our own
    :lang:/:dir: container options, which do emit real attributes.

This reuses existing mechanisms at three levels rather than inventing
new directives:

  • Block-level: :lang:/:dir: options on the existing .. container::
    / .. div:: directive.
  • Inline-level: new :rtl:/:ltr: roles for pure direction switches,
    and a combined :lang: role (:lang:text (language, direction)) for text tagged with both, following the same trailing-(...)convention as the existing:abbreviation:` role.
  • Document-level: new :lang:/:dir: field-list metadata, mirroring
    the existing :template: field, setting the page's own <html> tag.

dir is validated against ltr/rtl/auto and lang against a loose
BCP 47 shape; both are warn-only diagnostics, never blocking, matching
the ValueType validation philosophy already used elsewhere.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PP4LkejR5PSubbhNmF4RkT

Resolves #1266
Resolves #1267

Authors had no way to mark a block, a run of inline text, or a whole
page as being in a different language or text direction, so the
rendered HTML never got the lang/dir attributes needed for correct
rendering (e.g. RTL scripts, screen readers, correct font/glyph
shaping). The maintainers asked what concrete output this should
produce.

docutils/Sphinx were checked for prior art before designing this:
- Document level: neither has any per-document mechanism at all (only
  project-wide build config), so nothing to align with there.
- Inline level: docutils' own FAQ recommends exactly `:rtl:`/`:ltr:`
  roles for this, just via `.. role::` boilerplate the author has to
  write themselves; this makes them built-in instead.
- Block level: docutils has `.. class:: language-<tag>` and
  `.. class:: rtl`/`ltr`, but that's CSS-only styling hooks with no
  real HTML lang/dir attribute, so it doesn't actually address the
  accessibility problem these issues are about. Kept our own
  `:lang:`/`:dir:` container options, which do emit real attributes.

This reuses existing mechanisms at three levels rather than inventing
new directives:

- Block-level: `:lang:`/`:dir:` options on the existing `.. container::`
  / `.. div::` directive.
- Inline-level: new `:rtl:`/`:ltr:` roles for pure direction switches,
  and a combined `:lang:` role (`` :lang:`text (language, direction)` ``)
  for text tagged with both, following the same trailing-`(...)`
  convention as the existing `:abbreviation:` role.
- Document-level: new `:lang:`/`:dir:` field-list metadata, mirroring
  the existing `:template:` field, setting the page's own `<html>` tag.

`dir` is validated against ltr/rtl/auto and `lang` against a loose
BCP 47 shape; both are warn-only diagnostics, never blocking, matching
the ValueType validation philosophy already used elsewhere.

Signed-off-by: linawolf
Assisted-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP4LkejR5PSubbhNmF4RkT

@jaapio jaapio left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think direction should be an enum rather than an arbitrary string, this allows us to be more strict. We can validate the value before we create the enum, and otherwise fall back to auto when the value is invalid.

This will make sure rendering always works even if the userinput is wrong.

#[Option(name: 'dir', description: 'Sets the HTML dir attribute on the wrapping div: "ltr", "rtl", or "auto".')]
final class ContainerDirective extends SubDirective
{
private const VALID_DIRECTIONS = ['ltr', 'rtl', 'auto'];

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels like this is a good candidate for an enum?

final class LangTextRole extends BaseTextRole
{
private const VALID_DIRECTIONS = ['ltr', 'rtl', 'auto'];
private const LANGUAGE_TAG_PATTERN = '/^[a-zA-Z]{2,8}(-[a-zA-Z0-9]{1,8})*$/';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be repeated multiple times. Maybe we can use an interface with a constant to specify this? Something like Language

interface Language 
  const PATTERN = 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ability to specify text language in ReST Ability to specify text direction in ReST

2 participants