Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a directive for horizontal lists #8778

Open
jfbu opened this issue Jan 28, 2021 · 3 comments
Open

Add a directive for horizontal lists #8778

jfbu opened this issue Jan 28, 2021 · 3 comments
Labels
markup type:enhancement enhance or introduce a new feature

Comments

@jfbu
Copy link
Contributor

jfbu commented Jan 28, 2021

Is your feature request related to a problem? Please describe.

I wasn't familiar with hlist and got interested into it via #8072.

I think the name is really a misnomer, because it suggests the list will be "horizontally" constructed (as in horizontal)
But the code

class HList(SphinxDirective):
"""
Directive for a list that gets compacted horizontally.
"""
has_content = True
required_arguments = 0
optional_arguments = 0
final_argument_whitespace = False
option_spec = {
'columns': int,
}
def run(self) -> List[Node]:
ncolumns = self.options.get('columns', 2)
node = nodes.paragraph()
node.document = self.state.document
self.state.nested_parse(self.content, self.content_offset, node)
if len(node.children) != 1 or not isinstance(node.children[0],
nodes.bullet_list):
reporter = self.state.document.reporter
return [reporter.warning('.. hlist content is not a list', line=self.lineno)]
fulllist = node.children[0]
# create a hlist node where the items are distributed
npercol, nmore = divmod(len(fulllist), ncolumns)
index = 0
newnode = addnodes.hlist()
for column in range(ncolumns):
endindex = index + ((npercol + 1) if column < nmore else npercol)
bullet_list = nodes.bullet_list()
bullet_list += fulllist.children[index:endindex]
newnode += addnodes.hlistcol('', bullet_list)
index = endindex
return [newnode]
of the directive itself prepares the items in "columns".

Indeed this will be used by the HTML writer via un-ordered lists, except that rather than having one big list, we have for example 3, and the 3 are placed one next to the other as table elements in a table with only one row, each item of this row being an unordered list.

This is not implemented yet in LaTeX, but could be, either by mimicking the html approach (currently the latex writer simply ignores the pre-computed division into columns), or simply by wrapping the whole into a multicols environment. However in case of page break the next page will then re-construct columns from the remaining items. And even in case of no page break, the mulicols balancing does not necessarily create the same columns as the html writer. The latex writer simply ignores the column separations pre-computed by the directive code. It it did not it could create same output as html, but only if the whole thing can hold on one page. And there would be no need for multicols.

I feel the need for another concept, say horlist for "horizontally constructed list".

Describe the solution you'd like

The directive horlist (a better name should be chosen) would split the input into rows, each having a number of items equal to the asked for number of columns (except the last row). In html we can then fill a table horizontally rather than vertically.

However, the HList directive based html approach uses unordered list in each column. To keep same approach the directive would have to shuffle around the item nodes. But this would make things not usable to latex. Why not use for each item a one element unordered list creating the bullet, and a table with this time as many rows as are necessary ? Then basically the HList directive can be re-used as is, but for a renaming of hlistcol separator nodes into hlistrow nodes.

In latex we will not use a table-like environment, because this is a never-ending source of problems.

I made a proof of concept #8072 (comment) for the latex part.

It is very easy to add to sphinx/writers/latex.py the needed visit_horlist(), visit_horlistrow() etc... We only have to wrap each "item node" into suitable minipage. It will then be allowed to be very general contents: code-blocks are not a problem, sub-lists either, figures need some precautions already in place elsewhere (needed for the topic directive). Also footnotes will be ok.

Such a horlist in latex can be nested without a problem in a regular list environment, it will adjust to the width automatically. Pagebreaks between rows will not be a problem.

Describe alternatives you've considered
I was starting to do this with hlist until I understood that the HTML output was the transpose of what I expected.

I don't suppose we can consider a breaking change in hlist and let it produce in HTML the transpose of what it does currently?

The alternative concept of horlist can be implemented in LaTeX in a very compatible and satisfactory way, whereas mimicking the current hlist as rendered in html is feasible only by not allowing page breaks. I would actually not go into spending too much effort beyond simply adding a multicols wrapper with \raggedcolumns if trying to make hlist work in LaTeX as it works now in HTML.

I find it much more interesting to provide the horlist feature. In LaTeX we could then with not much problem allow also enumerated structure (which hlist does not support). But if HTML does not support it, probably there is no need in LaTeX.

@jfbu jfbu added type:enhancement enhance or introduce a new feature markup labels Jan 28, 2021
@jfbu
Copy link
Contributor Author

jfbu commented Jan 28, 2021

(of course horlist concept is pretty much the same as a table except each item has a bullet and the table does not need to have any horizontal or vertical separators lines; and that in LaTeX we definitely do NOT want to go into the nightmares of using table-like environment)

@tk0miya
Copy link
Member

tk0miya commented Jan 30, 2021

I think it is not good to provide such directives for layout as official because it's difficult to output them in some formats (ex. man pages, text, and so on). I believe one of the advantages of Sphinx is "single-input / multi-output". But these directives are hard to support in some builders. I would not add the hlist directive to Sphinx core if I could design Sphinx from scratch.

I know many people want some kind of layout directives (ex. checkbox, tabbed lists, horizontal lists, etc.). My idea to realize them is to make (or to keep) Sphinx extensible via extensions.

@jfbu
Copy link
Contributor Author

jfbu commented Jan 30, 2021

Yes you are right, I got too agitated from having thought through how to go about doing it in LaTeX... I see the constraint of remaining "multi-output". I will to work out the extension idea then. Leaving open some time if some more opinions about this are given.

@AA-Turner AA-Turner added this to the some future version milestone Sep 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
markup type:enhancement enhance or introduce a new feature
Projects
None yet
Development

No branches or pull requests

3 participants