Repository: translate/pootle

Issue:
Display hint on the special chars when hovering
It would be helpful to display a hint on which special char we are hovering. This is helpful since sometimes it is not easy to distinguish some of the special chars from others, and because sometimes different chars are represented with an empty box:

![chars](https://cloud.githubusercontent.com/assets/939880/19531720/f808179a-9638-11e6-8307-99eecbee1798.png)

Insert which symbol?



Discussion:
@unho which special characters are you talking about? The image posted only has spaces and I would argue that space is the one we actually really don't want to have a tooltip for, perhaps the others make more sense.

I was not making any difference at all on which chars the name should be shown.

@unho so you mean special characters as in those below the edit area? As opposed to the raw font characters? Got confused with an image lifted from a new editor bug which isn't really focused on the special chars.  Would have been nice to actually have a screenshot that was meant to focus on the special chars :(

Fair point, changed screenshot.


Resolving patch:
diff --git a/pootle/apps/pootle_store/views.py b/pootle/apps/pootle_store/views.py
--- a/pootle/apps/pootle_store/views.py
+++ b/pootle/apps/pootle_store/views.py
@@ -7,6 +7,8 @@
 # AUTHORS file for copyright and authorship information.
 
 import calendar
+import unicodedata
+from collections import OrderedDict
 
 from translate.lang import data
 
@@ -367,8 +369,48 @@ def get_entries_group_data(self, context):
         return result
 
 
+CHARACTERS_NAMES = OrderedDict(
+    (
+        # Code  Display name
+        (8204, 'ZWNJ'),
+        (8205, 'ZWJ'),
+        (8206, 'LRM'),
+        (8207, 'RLM'),
+        (8234, 'LRE'),
+        (8235, 'RLE'),
+        (8236, 'PDF'),
+        (8237, 'LRO'),
+        (8238, 'RLO'),
+    )
+)
+
+CHARACTERS = u"".join([unichr(index) for index in CHARACTERS_NAMES.keys()])
+
+
 class UnitEditJSON(PootleUnitJSON):
 
+    @property
+    def special_characters(self):
+        if self.language.direction == "rtl":
+            # Inject some extra special characters for RTL languages.
+            language_specialchars = CHARACTERS
+            # Do not repeat special chars.
+            language_specialchars += u"".join(
+                [c for c in self.language.specialchars if c not in CHARACTERS])
+        else:
+            language_specialchars = self.language.specialchars
+
+        special_chars = []
+        for specialchar in language_specialchars:
+            code = ord(specialchar)
+            special_chars.append({
+                'display': CHARACTERS_NAMES.get(code, specialchar),
+                'code': code,
+                'hex_code': "U+" + hex(code)[2:].upper(),  # Like U+200C
+                'name': unicodedata.name(specialchar, ''),
+            })
+        return special_chars
+
     def get_edit_template(self):
         if self.project.is_terminology or self.store.has_terminology:
             return loader.get_template('editor/units/term_edit.html')
@@ -445,6 +487,7 @@ def get_context_data(self, *args, **kwargs):
             'user': self.request.user,
             'project': self.project,
             'language': self.language,
+            'special_characters': self.special_characters,
             'source_language': self.source_language,
             'cantranslate': check_user_permission(self.request.user,
                                                   "translate",
diff --git a/pytest_pootle/factories.py b/pytest_pootle/factories.py
--- a/pytest_pootle/factories.py
+++ b/pytest_pootle/factories.py
@@ -94,6 +94,12 @@ def fullname(self):
         # returns an incrementing index relative to the tp
         return 'Language %s' % (Language.objects.count() - 1)
 
+    @factory.lazy_attribute
+    def specialchars(self):
+        from pootle_language.models import Language
+
+        return "" if (Language.objects.count() - 1) % 2 == 0 else u"ñ\u200c€"
+
 
 class ProjectDBFactory(factory.django.DjangoModelFactory):
 


Test patch:
diff --git a/tests/views/get_edit_unit.py b/tests/views/get_edit_unit.py
--- a/tests/views/get_edit_unit.py
+++ b/tests/views/get_edit_unit.py
@@ -7,12 +7,13 @@
 # AUTHORS file for copyright and authorship information.
 
 import json
+import unicodedata
 
 import pytest
 
 from pootle_app.models.permissions import check_user_permission
 from pootle_store.util import find_altsrcs
-from pootle_store.views import get_alt_src_langs
+from pootle_store.views import CHARACTERS_NAMES, get_alt_src_langs
 
 
 @pytest.mark.django_db
@@ -37,6 +38,16 @@ def test_get_edit_unit(project0_nongnu, get_edit_unit, client,
     request = response.wsgi_request
     result = json.loads(response.content)
 
+    special_characters = []
+    for specialchar in language.specialchars:
+        code = ord(specialchar)
+        special_characters.append({
+            'display': CHARACTERS_NAMES.get(code, specialchar),
+            'code': code,
+            'hex_code': "U+" + hex(code)[2:].upper(),
+            'name': unicodedata.name(specialchar, ''),
+        })
+
     src_lang = unit.store.translation_project.project.source_language
     alt_src_langs = get_alt_src_langs(request, user, translation_project)
     altsrcs = find_altsrcs(unit, alt_src_langs, store=store, project=project)
@@ -55,6 +66,7 @@ def test_get_edit_unit(project0_nongnu, get_edit_unit, client,
     assert response.context["directory"] == directory
     assert response.context["project"] == project
     assert response.context["language"] == language
+    assert response.context["special_characters"] == special_characters
     assert response.context["source_language"] == src_lang
     assert response.context["altsrcs"] == altsrcs
     assert response.context["suggestions_dict"] == suggestions_dict