Repository: sphinx-doc/sphinx

Issue:
class name "versionmodified" used by all versionchanged/added/deprecated
Subject: HTML output for change log (I want to CSS the headlines)

### Problem
The current implementation use the same class name for all three version roles. This means I cannot use CSS to have the color of the text reflect if its added (green), changed (yellow) or deprecated (red). The only difference between them is the text itself but for the reader this might become hard to read through when its all the same color (default black).

http://www.sphinx-doc.org/en/1.6/extdev/nodes.html#sphinx.addnodes.versionmodified

#### Expected results
Role | ClassName
------------ | -------------
versionadded | versionmodified.added
versionchanged | versionmodified.changed
deprecated | versionmodified.deprecated

### Reproducible project / your project
- https://espeasy.readthedocs.io/en/latest/

### Environment info
- Sphinx version: 1.8.1


Discussion:

Patch:
diff --git a/CHANGES b/CHANGES
index 68c8118ec..0949ae7e2 100644
--- a/CHANGES
+++ b/CHANGES
@@ -132,6 +132,11 @@ Features added
 * LaTeX: support rendering (not in math, yet) of Greek and Cyrillic Unicode
   letters in non-Cyrillic document even with ``'pdflatex'`` as
   :confval:`latex_engine` (refs: #5645)
+* #5660: The ``versionadded``, ``versionchanged`` and ``deprecated`` directives
+  are now generated with their own specific CSS classes
+  (``added``, ``changed`` and ``deprecated``, respectively) in addition to the
+  generic ``versionmodified`` class.
+
 
 Bugs fixed
 ----------
diff --git a/sphinx/domains/changeset.py b/sphinx/domains/changeset.py
index 21626ba35..4a515d2cc 100644
--- a/sphinx/domains/changeset.py
+++ b/sphinx/domains/changeset.py
@@ -34,6 +34,12 @@
     'deprecated':     _('Deprecated since version %s'),
 }
 
+versionlabel_classes = {
+    'versionadded':     'added',
+    'versionchanged':   'changed',
+    'deprecated':       'deprecated',
+}
+
 locale.versionlabels = DeprecatedDict(
     versionlabels,
     'sphinx.locale.versionlabels is deprecated. '
@@ -78,6 +84,7 @@ def run(self):
             messages = []
         if self.content:
             self.state.nested_parse(self.content, self.content_offset, node)
+        classes = ['versionmodified', versionlabel_classes[self.name]]
         if len(node):
             if isinstance(node[0], nodes.paragraph) and node[0].rawsource:
                 content = nodes.inline(node[0].rawsource, translatable=True)
@@ -87,11 +94,11 @@ def run(self):
                 node[0].replace_self(nodes.paragraph('', '', content, translatable=False))
 
             para = cast(nodes.paragraph, node[0])
-            para.insert(0, nodes.inline('', '%s: ' % text, classes=['versionmodified']))
+            para.insert(0, nodes.inline('', '%s: ' % text, classes=classes))
         else:
             para = nodes.paragraph('', '',
                                    nodes.inline('', '%s.' % text,
-                                                classes=['versionmodified']),
+                                                classes=classes),
                                    translatable=False)
             node.append(para)
 


Test patch:
diff --git a/tests/test_intl.py b/tests/test_intl.py
index ee4defa0e..4961d2550 100644
--- a/tests/test_intl.py
+++ b/tests/test_intl.py
@@ -705,20 +705,20 @@ def get_content(result, name):
             return ''
 
     expect1 = (
-        """<p><span class="versionmodified">Deprecated since version 1.0: </span>"""
+        """<p><span class="versionmodified deprecated">Deprecated since version 1.0: </span>"""
         """THIS IS THE <em>FIRST</em> PARAGRAPH OF DEPRECATED.</p>\n"""
         """<p>THIS IS THE <em>SECOND</em> PARAGRAPH OF DEPRECATED.</p>\n""")
     matched_content = get_content(result, "deprecated")
     assert expect1 == matched_content
 
     expect2 = (
-        """<p><span class="versionmodified">New in version 1.0: </span>"""
+        """<p><span class="versionmodified added">New in version 1.0: </span>"""
         """THIS IS THE <em>FIRST</em> PARAGRAPH OF VERSIONADDED.</p>\n""")
     matched_content = get_content(result, "versionadded")
     assert expect2 == matched_content
 
     expect3 = (
-        """<p><span class="versionmodified">Changed in version 1.0: </span>"""
+        """<p><span class="versionmodified changed">Changed in version 1.0: </span>"""
         """THIS IS THE <em>FIRST</em> PARAGRAPH OF VERSIONCHANGED.</p>\n""")
     matched_content = get_content(result, "versionchanged")
     assert expect3 == matched_content