diff --git a/CHANGES b/CHANGES index f5b53f9f7..0d2ffbbb9 100644 --- a/CHANGES +++ b/CHANGES @@ -37,6 +37,9 @@ New features added the directive -- this allows you to define your document structure, but place the links yourself. + - #52: There is now a ``hlist`` directive, creating a compact + list by placing distributing items into multiple columns. + - #77: If a description environment with info field list only contains one ``:param:`` entry, no bullet list is generated. diff --git a/doc/markup/para.rst b/doc/markup/para.rst index c60eb2587..b071e46c8 100644 --- a/doc/markup/para.rst +++ b/doc/markup/para.rst @@ -100,6 +100,27 @@ units as well as normal text: .. centered:: LICENSE AGREEMENT +.. directive:: hlist + + This directive must contain a bullet list. It will transform it into a more + compact list by either distributing more than one item horizontally, or + reducing spacing between items, depending on the builder. + + For builders that support the horizontal distribution, there is a ``columns`` + option that specifies the number of columns; it defaults to 2. Example:: + + .. hlist:: + :columns: 3 + + * A list of + * short items + * that should be + * displayed + * horizontally + + .. versionadded:: 0.6 + + Table-of-contents markup ------------------------ diff --git a/sphinx/addnodes.py b/sphinx/addnodes.py index b267913b9..a4af584c7 100644 --- a/sphinx/addnodes.py +++ b/sphinx/addnodes.py @@ -74,6 +74,10 @@ class download_reference(nodes.reference): pass # for the ACKS list class acks(nodes.Element): pass +# for horizontal lists +class hlist(nodes.Element): pass +class hlistcol(nodes.Element): pass + # sets the highlighting language for literal blocks class highlightlang(nodes.Element): pass @@ -99,7 +103,7 @@ class meta(nodes.Special, nodes.PreBibliographic, nodes.Element): pass # will choke at some point if these are not added nodes._add_node_class_names("""index desc desc_content desc_signature desc_type desc_returns desc_addname desc_name desc_parameterlist - desc_parameter desc_optional download_reference + desc_parameter desc_optional download_reference hlist hlistcol centered versionmodified seealso productionlist production toctree pending_xref compact_paragraph highlightlang literal_emphasis glossary acks module start_of_file tabular_col_spec meta""".split()) diff --git a/sphinx/directives/other.py b/sphinx/directives/other.py index f19c4f9b4..cbf548bec 100644 --- a/sphinx/directives/other.py +++ b/sphinx/directives/other.py @@ -383,6 +383,34 @@ acks_directive.arguments = (0, 0, 0) directives.register_directive('acks', acks_directive) +def hlist_directive(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + ncolumns = options.get('columns', 2) + node = nodes.paragraph() + state.nested_parse(content, content_offset, node) + if len(node.children) != 1 or not isinstance(node.children[0], nodes.bullet_list): + return [state.document.reporter.warning('.. hlist content is not a list', + line=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 + (column < nmore and (npercol+1) or npercol) + col = addnodes.hlistcol() + col += nodes.bullet_list() + col[0] += fulllist.children[index:endindex] + index = endindex + newnode += col + return [newnode] + +hlist_directive.content = 1 +hlist_directive.arguments = (0, 0, 0) +hlist_directive.options = {'columns': int} +directives.register_directive('hlist', hlist_directive) + + def tabularcolumns_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): # support giving explicit tabulary column definition to latex diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py index e34b8fa9f..8c1a87ba8 100644 --- a/sphinx/writers/html.py +++ b/sphinx/writers/html.py @@ -321,6 +321,16 @@ class HTMLTranslator(BaseTranslator): def depart_module(self, node): pass + def visit_hlist(self, node): + self.body.append('') + def depart_hlist(self, node): + self.body.append('
\n') + + def visit_hlistcol(self, node): + self.body.append('') + def depart_hlistcol(self, node): + self.body.append('') + def bulk_text_processor(self, text): return text diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index c16a42714..885cac44b 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -223,6 +223,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.this_is_the_title = 1 self.literal_whitespace = 0 self.no_contractions = 0 + self.compact_list = 0 def astext(self): return (HEADER % self.elements + self.highlighter.get_stylesheet() + @@ -652,9 +653,11 @@ class LaTeXTranslator(nodes.NodeVisitor): raise nodes.SkipNode def visit_bullet_list(self, node): - self.body.append('\\begin{itemize}\n' ) + if not self.compact_list: + self.body.append('\\begin{itemize}\n' ) def depart_bullet_list(self, node): - self.body.append('\\end{itemize}\n' ) + if not self.compact_list: + self.body.append('\\end{itemize}\n' ) def visit_enumerated_list(self, node): self.body.append('\\begin{enumerate}\n' ) @@ -723,6 +726,21 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_centered(self, node): self.body.append('\n\\end{centering}') + def visit_hlist(self, node): + # for now, we don't support a more compact list format + # don't add individual itemize environments, but one for all columns + self.compact_list += 1 + self.body.append('\\begin{itemize}\\setlength{\\itemsep}{0pt}' + '\\setlength{\\parskip}{0pt}\n') + def depart_hlist(self, node): + self.compact_list -= 1 + self.body.append('\\end{itemize}\n') + + def visit_hlistcol(self, node): + pass + def depart_hlistcol(self, node): + pass + def visit_module(self, node): modname = node['modname'] self.body.append('\n\\declaremodule[%s]{}{%s}' % (modname.replace('_', ''), diff --git a/sphinx/writers/text.py b/sphinx/writers/text.py index 5c8500fb6..4718d41d3 100644 --- a/sphinx/writers/text.py +++ b/sphinx/writers/text.py @@ -516,6 +516,16 @@ class TextTranslator(nodes.NodeVisitor): def depart_centered(self, node): pass + def visit_hlist(self, node): + pass + def depart_hlist(self, node): + pass + + def visit_hlistcol(self, node): + pass + def depart_hlistcol(self, node): + pass + def visit_admonition(self, node): self.new_state(0) def depart_admonition(self, node): diff --git a/tests/root/markup.txt b/tests/root/markup.txt index 454762e3f..777fbd2f7 100644 --- a/tests/root/markup.txt +++ b/tests/root/markup.txt @@ -104,6 +104,16 @@ Reference lookup: [Ref1]_ (defined in another file). `Google `_ For everything. +.. hlist:: + :columns: 4 + + * This + * is + * a horizontal + * list + * with several + * items + .. rubric:: Side note This is a side note.