Repository: sciunto-org/python-bibtexparser (python)

Issue:
Strip title of "{", "}" and similar
I've just tried bibtexparser for https://github.com/MartinThoma/algorithms/tree/master/bib2html and I noticed that `entry.title` can be something like `On-line {Recognition} of {Handwritten} {Mathematical} {Symbols}.`.

Is it possible to strip those / to make the title similar to what it gets rendered to?


Pull request description:
Customization to strip fields of `{`, `}` etc
Add a `add_plaintext_fields` customization to strip fields of braces and
similar characters, getting only the plaintext. It processes every
available fields and for each field, it adds a `plain_*` field
containing the plaintext version.

Should close #116.

Patch:
diff --git a/bibtexparser/customization.py b/bibtexparser/customization.py
index c1b19b2..be97639 100644
--- a/bibtexparser/customization.py
+++ b/bibtexparser/customization.py
@@ -10,13 +10,15 @@ Each of them takes a record and return the modified record.
 import re
 import logging
 
+from builtins import str
+
 from bibtexparser.latexenc import latex_to_unicode, string_to_latex, protect_uppercase
 
 logger = logging.getLogger(__name__)
 
 __all__ = ['splitname', 'getnames', 'author', 'editor', 'journal', 'keyword',
            'link', 'page_double_hyphen', 'doi', 'type', 'convert_to_unicode',
-           'homogenize_latex_encoding']
+           'homogenize_latex_encoding', 'add_plaintext_fields']
 
 
 class InvalidName(ValueError):
@@ -530,3 +532,38 @@ def homogenize_latex_encoding(record):
                 record[val] = protect_uppercase(record[val])
                 logger.debug('After: %s', record[val])
     return record
+
+
+def add_plaintext_fields(record):
+    """
+    For each field in the record, add a `plain_` field containing the
+    plaintext, stripped from braces and similar. See
+    https://github.com/sciunto-org/python-bibtexparser/issues/116.
+
+    :param record: the record.
+    :type record: dict
+    :returns: dict -- the modified record.
+    """
+    def _strip_string(string):
+        for stripped in ['{', '}']:
+            string = string.replace(stripped, "")
+        return string
+
+    for key in list(record.keys()):
+        plain_key = "plain_{}".format(key)
+        record[plain_key] = record[key]
+
+        if isinstance(record[plain_key], str):
+            record[plain_key] = _strip_string(record[plain_key])
+        elif isinstance(record[plain_key], dict):
+            record[plain_key] = {
+                subkey: _strip_string(value)
+                for subkey, value in record[plain_key].items()
+            }
+        elif isinstance(record[plain_key], list):
+            record[plain_key] = [
+                _strip_string(value)
+                for value in record[plain_key]
+            ]
+
+    return record
diff --git a/requirements.txt b/requirements.txt
index e7c21d1..cff3aca 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,1 +1,2 @@
+future>=0.16.0
 pyparsing>=2.0.3


Test patch:
diff --git a/bibtexparser/tests/test_customization.py b/bibtexparser/tests/test_customization.py
index c6b168b..e38c078 100644
--- a/bibtexparser/tests/test_customization.py
+++ b/bibtexparser/tests/test_customization.py
@@ -4,7 +4,7 @@
 from __future__ import unicode_literals
 import unittest
 
-from bibtexparser.customization import getnames, convert_to_unicode, homogenize_latex_encoding, page_double_hyphen, keyword
+from bibtexparser.customization import getnames, convert_to_unicode, homogenize_latex_encoding, page_double_hyphen, keyword, add_plaintext_fields
 
 
 class TestBibtexParserMethod(unittest.TestCase):
@@ -101,6 +101,26 @@ class TestBibtexParserMethod(unittest.TestCase):
         expected = {'toto': '{\`a} {\`a} {\`a}'}
         self.assertEqual(result, expected)
 
+    ###########
+    # add_plaintext_fields
+    ###########
+    def test_add_plaintext_fields(self):
+        record = {
+            'title': 'On-line {Recognition} of {Handwritten} {Mathematical} {Symbols}',
+            'foobar': ['{FFT} {Foobar}', '{foobar}'],
+            'foobar2': {'item1': '{FFT} {Foobar}', 'item2': '{foobar}'}
+        }
+        result = add_plaintext_fields(record)
+        expected = {
+            'title': 'On-line {Recognition} of {Handwritten} {Mathematical} {Symbols}',
+            'plain_title': 'On-line Recognition of Handwritten Mathematical Symbols',
+            'foobar': ['{FFT} {Foobar}', '{foobar}'],
+            'plain_foobar': ['FFT Foobar', 'foobar'],
+            'foobar2': {'item1': '{FFT} {Foobar}', 'item2': '{foobar}'},
+            'plain_foobar2': {'item1': 'FFT Foobar', 'item2': 'foobar'}
+        }
+        self.assertEqual(result, expected)
+
     ###########
     # keywords
     ###########