Feature request: Allow specification of arbitrary line numbers
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 2.2k
- Forks
- 885
- PR merge metrics
- No merged PRs in 30d
Description
Overview of feature request
I'm raising this request in the context of the HTML formatter provided by pygments. Unsure if this applies to other formatters as well.
As of now, the pygments HtmlFormatter provides a couple of options related to attaching line numbers to the formatted code blocks, namely linenos (False, True, "table", "inline"), hl_lines, linenostart, linenostep (with linenospecial, anchorlinenos tangentially related).
linenostart allows one to start from the specified number, not necessarily from 1, and linenostep allows one to specify line numbers allows us to print every nth line in the line number column.
However, sometimes, we might want to print arbitrary lines (not necessarily stepped) from the source code, so the request here is to expose one more option, say linenoprint which specifies a list of line numbers that will be printed from the provided source. See API Details below.
Motivation
mkdocstrings uses pygments (indirectly) when displaying source code in the generated documentation, we want to be able to expose an option to remove docstrings from the source code. See discussion in https://github.com/mkdocstrings/mkdocstrings/issues/249#issuecomment-1399264566 for more details.
The intention is to remove the docstrings from the source before passing it into pygments, but in order to still present the code as a contiguous code-block, we need support for specifying arbitrary line numbers. As opposed to assuming line numbers are always sequential.
API Details
This is just my proposal:
- Implemented behaviour described below should be available for both
tableandinlinelineno styles. Iflinenosis not provided or is False, thenlinenoprintshould be ignored. linenoprintshould be mutually exclusive withlinenostart. Throw an error if both are provided.- Normal Behaviour:
after formatting, should return an output that looks likefrom pygments import highlight from pygments.lexers import PythonLexer from pygments.formatters import HtmlFormatter code = """\ def foo(x) -> None: print(x) """ highlight(code, PythonLexer(), HtmlFormatter(linenos="table", linenoprint=[50, 52]))50 | def foo(x) -> None: 52 | print(x) - If the provided
linenoprintlist is shorter / longer than the number of lines in the source, I don't really have a preference on whatpygmentsshould do. If I had to decide, I'ld be more permissive, that is:- if
len(linenoprint) < len(source), do an equivalent ofzip_longestand padlinenoprintwith ""
can probably givehighlight(code, PythonLexer(), HtmlFormatter(linenos="table", linenoprint=[50,]))50 | def foo(x) -> None: | print(x) - if
len(linenoprint) > len(source), then do an equivalent ofzip(strict=False)and ignore the rest oflinenoprint.
can probably givehighlight(code, PythonLexer(), HtmlFormatter(linenos="table", linenoprint=[50, 52, 99]))50 | def foo(x) -> None: 52 | print(x)
- if
- Using
linenoprintshould be independent from the other line number options (e.g.linenostep,hl_lines), E.g.
after formatting, should return an output that looks likehighlight(code, PythonLexer(), HtmlFormatter(linenos="table", linenoprint=[50, 52], linenostep=4))
If there are other potential conflicts that I missed, we can discuss how to deal with them below.| def foo(x) -> None: 52 | print(x)
Additional, optional, good-to-have
It would be nice if we don't have to strictly require the line numbering to be all integers, so that we might be able to format something like this
code = """\
def foo(x) -> None:
…
print(x)
"""
highlight(code, PythonLexer(), HtmlFormatter(linenos="table", linenoprint=[50, "…", 52])) # shouldn't throw an error
after formatting, should return an output that looks like
50 | def foo(x) -> None:
… | …
52 | print(x)
to signify that we've truncated some code off.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the HtmlFormatter entry point and review how its existing linenos, linenostart, linenostep, table, and inline options are handled. Trace the formatter's line-number rendering for both requested styles and determine how arbitrary labels, option conflicts, and length mismatches should behave. Done means the agreed API is implemented consistently and covered for the listed interactions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100