Repository: sphinx-doc/sphinx

Issue:
Alphanumeric lists not possible in LaTeX and EPUB
I discovered that it is possible to make alphanumeric lists in HTML like this:

```
#!rst

I. Schnittblumen

   a. Rosen
   b. Nelken
   c. Tulpen

A. Topfblumen

   i. Petunien
   ii. Geranien
   iii. Pelargonien
```

Unfortunately the output in LaTeX and EPUB is not what I expected. It is rendered more or less like a normal enumerated list. This can be an issue of EPUB and LaTeX. 

Maybe this should be mentioned in the documentation, if it is not possible have alphanumeric lists in LaTeX and EPUB in the near future. As alphanumeric lists are not mentioned at all in the documentation I marked this a minor issue.

---
- Bitbucket: https://bitbucket.org/birkenfeld/sphinx/issue/1431
- Originally reported by: Jan Ulrich Hasecke
- Originally created at: 2014-03-25T09:23:36.489


Discussion:
jfbu: About 

> This might not be needed for Sphinx links if it does not use regular  `\ref`, but if not `\ref` is broken. 

actually, sphinx.writers.latex uses extensively `\label/\hyperref` combination, but never `\label/\ref` (it does use `\autopageref`). And `\hyperref` requires an argument for the name of the reference (`\hyperref[targetname]{text}`) , hence it is not important if `\ref{targetname}` would print a wrong text not in sync with actual text seen in PDF as only macro `\hyperref` is used and not `\ref`.

Nevertheless it would be better to get potentially `\ref` to work fine, because user may want to insert it via raw directive, or it could be used via some add-on LaTeX package.

Side note: the terminology in sphinx.latex.writers is potentially confusing to LaTeX person because LaTeXTranslator provides methods ``hypertarget()`` (uses LaTeX ``\label``)  and ``hyperlink()`` (uses hyperref's ``\hyperref``) but on the other hand hyperref package  provides macros which are similarly named:`\hypertarget`, resp. `\hyperlink` but they are **not** used by Sphinx LaTeX writer! 
codecov[bot]: # [Codecov](https://codecov.io/gh/sphinx-doc/sphinx/pull/5001?src=pr&el=h1) Report
> Merging [#5001](https://codecov.io/gh/sphinx-doc/sphinx/pull/5001?src=pr&el=desc) into [master](https://codecov.io/gh/sphinx-doc/sphinx/commit/157619c4e369dace8f4caebc076080d7e66c72e0?src=pr&el=desc) will **decrease** coverage by `0.01%`.
> The diff coverage is `92.85%`.

[![Impacted file tree graph](https://codecov.io/gh/sphinx-doc/sphinx/pull/5001/graphs/tree.svg?width=650&src=pr&token=VFlFSELbkw&height=150)](https://codecov.io/gh/sphinx-doc/sphinx/pull/5001?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #5001      +/-   ##
==========================================
- Coverage    82.2%   82.19%   -0.02%     
==========================================
  Files         292      297       +5     
  Lines       38517    38839     +322     
  Branches     5926     5989      +63     
==========================================
+ Hits        31664    31923     +259     
- Misses       5541     5591      +50     
- Partials     1312     1325      +13
```


| [Impacted Files](https://codecov.io/gh/sphinx-doc/sphinx/pull/5001?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [tests/test\_build\_latex.py](https://codecov.io/gh/sphinx-doc/sphinx/pull/5001/diff?src=pr&el=tree#diff-dGVzdHMvdGVzdF9idWlsZF9sYXRleC5weQ==) | `95.13% <100%> (-0.14%)` | :arrow_down: |
| [sphinx/writers/latex.py](https://codecov.io/gh/sphinx-doc/sphinx/pull/5001/diff?src=pr&el=tree#diff-c3BoaW54L3dyaXRlcnMvbGF0ZXgucHk=) | `84.89% <88.88%> (-0.3%)` | :arrow_down: |
| [sphinx/directives/code.py](https://codecov.io/gh/sphinx-doc/sphinx/pull/5001/diff?src=pr&el=tree#diff-c3BoaW54L2RpcmVjdGl2ZXMvY29kZS5weQ==) | `83.81% <0%> (-1.54%)` | :arrow_down: |
| [sphinx/ext/napoleon/docstring.py](https://codecov.io/gh/sphinx-doc/sphinx/pull/5001/diff?src=pr&el=tree#diff-c3BoaW54L2V4dC9uYXBvbGVvbi9kb2NzdHJpbmcucHk=) | `78.07% <0%> (-0.11%)` | :arrow_down: |
| [sphinx/\_\_init\_\_.py](https://codecov.io/gh/sphinx-doc/sphinx/pull/5001/diff?src=pr&el=tree#diff-c3BoaW54L19faW5pdF9fLnB5) | `57.5% <0%> (ø)` | |
| [sphinx/apidoc.py](https://codecov.io/gh/sphinx-doc/sphinx/pull/5001/diff?src=pr&el=tree#diff-c3BoaW54L2FwaWRvYy5weQ==) | `0% <0%> (ø)` | |
| [sphinx/quickstart.py](https://codecov.io/gh/sphinx-doc/sphinx/pull/5001/diff?src=pr&el=tree#diff-c3BoaW54L3F1aWNrc3RhcnQucHk=) | `0% <0%> (ø)` | |
| [sphinx/errors.py](https://codecov.io/gh/sphinx-doc/sphinx/pull/5001/diff?src=pr&el=tree#diff-c3BoaW54L2Vycm9ycy5weQ==) | `71.42% <0%> (ø)` | |
| ... and [2 more](https://codecov.io/gh/sphinx-doc/sphinx/pull/5001/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/sphinx-doc/sphinx/pull/5001?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/sphinx-doc/sphinx/pull/5001?src=pr&el=footer). Last update [157619c...6cc8322](https://codecov.io/gh/sphinx-doc/sphinx/pull/5001?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/CHANGES b/CHANGES
index e7de2402b..e6c73dc87 100644
--- a/CHANGES
+++ b/CHANGES
@@ -142,6 +142,7 @@ Features added
 * #3784: mathjax: Add :confval:`mathjax_options` to give options to script tag
   for mathjax
 * #4362: latex: Don't overwrite .tex file if document not changed
+* #1431: latex: Add alphanumeric enumerated list support
 
 Bugs fixed
 ----------
diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py
index e4fdf3ca1..614feb219 100644
--- a/sphinx/writers/latex.py
+++ b/sphinx/writers/latex.py
@@ -71,6 +71,14 @@
     nodes.section,
     captioned_literal_block,
 )
+ENUMERATE_LIST_STYLE = defaultdict(lambda: r'\arabic',
+                                   {
+                                       'arabic': r'\arabic',
+                                       'loweralpha': r'\alph',
+                                       'upperalpha': r'\Alph',
+                                       'lowerroman': r'\roman',
+                                       'upperroman': r'\Roman',
+                                   })  # type: Dict[unicode, unicode]
 
 DEFAULT_SETTINGS = {
     'latex_engine':    'pdflatex',
@@ -1478,6 +1486,15 @@ def depart_bullet_list(self, node):
 
     def visit_enumerated_list(self, node):
         # type: (nodes.Node) -> None
+        def get_enumtype(node):
+            # type: (nodes.Node) -> unicode
+            enumtype = node.get('enumtype', 'arabic')
+            if 'alpha' in enumtype and 26 < node.get('start', 0) + len(node):
+                # fallback to arabic if alphabet counter overflows
+                enumtype = 'arabic'
+
+            return enumtype
+
         def get_nested_level(node):
             # type: (nodes.Node) -> int
             if node is None:
@@ -1487,10 +1504,18 @@ def get_nested_level(node):
             else:
                 return get_nested_level(node.parent)
 
+        enum = "enum%s" % toRoman(get_nested_level(node)).lower()
+        enumnext = "enum%s" % toRoman(get_nested_level(node) + 1).lower()
+        style = ENUMERATE_LIST_STYLE.get(get_enumtype(node))
+
         self.body.append('\\begin{enumerate}\n')
+        self.body.append('\\def\\the%s{%s{%s}}\n' % (enum, style, enum))
+        self.body.append('\\def\\label%s{%s\\the%s %s}\n' %
+                         (enum, node['prefix'], enum, node['suffix']))
+        self.body.append('\\makeatletter\\def\\p@%s{\\p@%s %s\\the%s %s}\\makeatother\n' %
+                         (enumnext, enum, node['prefix'], enum, node['suffix']))
         if 'start' in node:
-            enum_depth = "enum%s" % toRoman(get_nested_level(node)).lower()
-            self.body.append('\\setcounter{%s}{%d}\n' % (enum_depth, node['start'] - 1))
+            self.body.append('\\setcounter{%s}{%d}\n' % (enum, node['start'] - 1))
         if self.table:
             self.table.has_problematic = True
 


Test patch:
diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py
index 56c1329f7..2573a74da 100644
--- a/tests/test_build_latex.py
+++ b/tests/test_build_latex.py
@@ -1229,11 +1229,26 @@ def test_latex_nested_enumerated_list(app, status, warning):
     app.builder.build_all()
 
     result = (app.outdir / 'test.tex').text(encoding='utf8')
-    assert r'\setcounter{enumi}{4}' in result
-    assert r'\setcounter{enumii}{3}' in result
-    assert r'\setcounter{enumiii}{9}' in result
-    assert r'\setcounter{enumiv}{23}' in result
-    assert r'\setcounter{enumii}{2}' in result
+    assert ('\\def\\theenumi{\\arabic{enumi}}\n'
+            '\\def\\labelenumi{\\theenumi .}\n'
+            '\\makeatletter\\def\\p@enumii{\\p@enumi \\theenumi .}\\makeatother\n'
+            '\\setcounter{enumi}{4}\n' in result)
+    assert ('\\def\\theenumii{\\alph{enumii}}\n'
+            '\\def\\labelenumii{\\theenumii .}\n'
+            '\\makeatletter\\def\\p@enumiii{\\p@enumii \\theenumii .}\\makeatother\n'
+            '\\setcounter{enumii}{3}\n' in result)
+    assert ('\\def\\theenumiii{\\arabic{enumiii}}\n'
+            '\\def\\labelenumiii{\\theenumiii )}\n'
+            '\\makeatletter\\def\\p@enumiv{\\p@enumiii \\theenumiii )}\\makeatother\n'
+            '\\setcounter{enumiii}{9}\n' in result)
+    assert ('\\def\\theenumiv{\\arabic{enumiv}}\n'
+            '\\def\\labelenumiv{(\\theenumiv )}\n'
+            '\\makeatletter\\def\\p@enumv{\\p@enumiv (\\theenumiv )}\\makeatother\n'
+            '\\setcounter{enumiv}{23}\n' in result)
+    assert ('\\def\\theenumii{\\roman{enumii}}\n'
+            '\\def\\labelenumii{\\theenumii .}\n'
+            '\\makeatletter\\def\\p@enumiii{\\p@enumii \\theenumii .}\\makeatother\n'
+            '\\setcounter{enumii}{2}\n' in result)
 
 
 @pytest.mark.sphinx('latex', testroot='footnotes')