From a150220cf2d2b16e4a0f047354a23c7b1a8f107d Mon Sep 17 00:00:00 2001 From: Romain Giot Date: Wed, 2 Oct 2013 13:48:12 +0200 Subject: [PATCH 1/7] Allow to use the flag 'a' in the transformation commands. This way, in a Latex file written with accentueted letters, the label use non accentueted letters instead of _. --- UltiSnips/tex.snippets | 14 +++++++------- plugin/UltiSnips/text_objects/_transformation.py | 9 +++++++++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/UltiSnips/tex.snippets b/UltiSnips/tex.snippets index 0f2f7dd..eddd614 100644 --- a/UltiSnips/tex.snippets +++ b/UltiSnips/tex.snippets @@ -58,7 +58,7 @@ endsnippet snippet part "Part" b \part{${1:part name}} -\label{prt:${2:${1/(\w+)|\W+/(?1:\L$0\E:_)/g}}} +\label{prt:${2:${1/(\w+)|\W+/(?1:\L$0\E:_)/ga}}} ${0} @@ -67,7 +67,7 @@ endsnippet snippet cha "Chapter" b \chapter{${1:chapter name}} -\label{cha:${2:${1/\\\w+\{(.*?)\}|\\(.)|(\w+)|([^\w\\]+)/(?4:_:\L$1$2$3\E)/g}}} +\label{cha:${2:${1/\\\w+\{(.*?)\}|\\(.)|(\w+)|([^\w\\]+)/(?4:_:\L$1$2$3\E)/ga}}} ${0} @@ -76,7 +76,7 @@ endsnippet snippet sec "Section" b \section{${1:section name}} -\label{sec:${2:${1/\\\w+\{(.*?)\}|\\(.)|(\w+)|([^\w\\]+)/(?4:_:\L$1$2$3\E)/g}}} +\label{sec:${2:${1/\\\w+\{(.*?)\}|\\(.)|(\w+)|([^\w\\]+)/(?4:_:\L$1$2$3\E)/ga}}} ${0} @@ -86,7 +86,7 @@ endsnippet snippet sub "Subsection" b \subsection{${1:subsection name}} -\label{sub:${2:${1/\\\w+\{(.*?)\}|\\(.)|(\w+)|([^\w\\]+)/(?4:_:\L$1$2$3\E)/g}}} +\label{sub:${2:${1/\\\w+\{(.*?)\}|\\(.)|(\w+)|([^\w\\]+)/(?4:_:\L$1$2$3\E)/ga}}} ${0} @@ -95,7 +95,7 @@ endsnippet snippet ssub "Subsubsection" b \subsubsection{${1:subsubsection name}} -\label{ssub:${2:${1/\\\w+\{(.*?)\}|\\(.)|(\w+)|([^\w\\]+)/(?4:_:\L$1$2$3\E)/g}}} +\label{ssub:${2:${1/\\\w+\{(.*?)\}|\\(.)|(\w+)|([^\w\\]+)/(?4:_:\L$1$2$3\E)/ga}}} ${0} @@ -105,7 +105,7 @@ endsnippet snippet par "Paragraph" b \paragraph{${1:paragraph name}} -\label{par:${2:${1/\\\w+\{(.*?)\}|\\(.)|(\w+)|([^\w\\]+)/(?4:_:\L$1$2$3\E)/g}}} +\label{par:${2:${1/\\\w+\{(.*?)\}|\\(.)|(\w+)|([^\w\\]+)/(?4:_:\L$1$2$3\E)/ga}}} ${0} @@ -115,7 +115,7 @@ endsnippet snippet subp "Subparagraph" b \subparagraph{${1:subparagraph name}} -\label{par:${2:${1/\\\w+\{(.*?)\}|\\(.)|(\w+)|([^\w\\]+)/(?4:_:\L$1$2$3\E)/g}}} +\label{par:${2:${1/\\\w+\{(.*?)\}|\\(.)|(\w+)|([^\w\\]+)/(?4:_:\L$1$2$3\E)/ga}}} ${0} diff --git a/plugin/UltiSnips/text_objects/_transformation.py b/plugin/UltiSnips/text_objects/_transformation.py index db77236..8310170 100755 --- a/plugin/UltiSnips/text_objects/_transformation.py +++ b/plugin/UltiSnips/text_objects/_transformation.py @@ -108,16 +108,25 @@ class TextObjectTransformation(object): flags = 0 self._match_this_many = 1 + self._convert_to_ascii = False if token.options: if "g" in token.options: self._match_this_many = 0 if "i" in token.options: flags |= re.IGNORECASE + if "a" in token.options: + self._convert_to_ascii = True self._find = re.compile(token.search, flags | re.DOTALL) self._replace = _CleverReplace(token.replace) def _transform(self, text): + if self._convert_to_ascii: + try: + import unidecode + text = unidecode.unidecode(text) + except Exception, e: + pass if self._find is None: return text return self._find.subn(self._replace.replace, text, self._match_this_many)[0] From 449255a06025f21152cf8ab06f7be08ba8634f72 Mon Sep 17 00:00:00 2001 From: Romain Giot Date: Thu, 3 Oct 2013 09:11:36 +0200 Subject: [PATCH 2/7] Add an error message when unidecode is not installed. The message is displayed only one time --- plugin/UltiSnips/text_objects/_transformation.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/plugin/UltiSnips/text_objects/_transformation.py b/plugin/UltiSnips/text_objects/_transformation.py index 8310170..47ea3a3 100755 --- a/plugin/UltiSnips/text_objects/_transformation.py +++ b/plugin/UltiSnips/text_objects/_transformation.py @@ -2,9 +2,12 @@ # encoding: utf-8 import re - +import sys from UltiSnips.text_objects._mirror import Mirror +# flag used to display only one time the lack of unidecode +UNIDECODE_ALERT_RAISED = False + class _CleverReplace(object): """ This class mimics TextMates replace syntax @@ -121,12 +124,15 @@ class TextObjectTransformation(object): self._replace = _CleverReplace(token.replace) def _transform(self, text): + global UNIDECODE_ALERT_RAISED if self._convert_to_ascii: try: import unidecode text = unidecode.unidecode(text) except Exception, e: - pass + if UNIDECODE_ALERT_RAISED == False: + UNIDECODE_ALERT_RAISED = True + sys.stderr.write("Please install unidecode python package in order to be able to make ascii conversions.\n") if self._find is None: return text return self._find.subn(self._replace.replace, text, self._match_this_many)[0] From 2bf3d1088407f947c700bca395e81fb22ce04bbf Mon Sep 17 00:00:00 2001 From: Romain Giot Date: Mon, 7 Oct 2013 09:48:34 +0200 Subject: [PATCH 3/7] Add a documentation to the 'a' flag --- doc/UltiSnips.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/doc/UltiSnips.txt b/doc/UltiSnips.txt index 6145bd7..3761be0 100644 --- a/doc/UltiSnips.txt +++ b/doc/UltiSnips.txt @@ -1152,6 +1152,11 @@ The options can be any combination of > i - case insensitive By default, regular expression matching is case sensitive. With this option, matching is done without regard to case. + a - ascii conversion + By default, transformation is made on the raw utf-8 string. With + this option, matching is done with a string converted into ascii. + One use of this option is to replace accentued chars by a non + accentued version. The syntax of regular expressions is beyond the scope of this document. Python regular expressions are used internally, so the python 're' module can be used @@ -1211,6 +1216,18 @@ this is a title This Is A Title +Demo: ASCII transformation +------------------- SNIP ------------------- +snippet ascii "Replace non ascii chars" +${1: an accentued text} +${1/.*/$0/a} +endsnippet +------------------- SNAP ------------------- +asciià la pêche aux moules +à la pêche aux moules +a la peche aux moules + + Demo: Regular expression grouping This is a clever c-like printf snippet, the second tabstop is only shown when there is a format (%) character in the first tabstop. From ddcf183a59f3be0a84bbbbe9a5ab26b65c537492 Mon Sep 17 00:00:00 2001 From: Romain Giot Date: Mon, 7 Oct 2013 09:49:02 +0200 Subject: [PATCH 4/7] Add two additional tests for the 'a' flag in the transformation --- test.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test.py b/test.py index af9be1d..636855a 100755 --- a/test.py +++ b/test.py @@ -1472,6 +1472,14 @@ class Transformation_CleverTransformLongLower_ExceptCorrectResult(_VimTest): snippets = ("test", "$1 ${1/(.*)/\L$1\E/}") keys = "test" + EX + "HALLO" wanted = "HALLO hallo" +class Transformation_SimpleCaseAsciiResult(_VimTest): + snippets = ("ascii", "$1 ${1/(.*)/$1/a}") + keys = "ascii" + EX + "éèàçôïÉÈÀÇÔÏ€" + wanted = "éèàçôïÉÈÀÇÔÏ€ eeacoiEEACOIEU" +class Transformation_LowerCaseAsciiResult(_VimTest): + snippets = ("ascii", "$1 ${1/(.*)/\L$1\E/a}") + keys = "ascii" + EX + "éèàçôïÉÈÀÇÔÏ€" + wanted = "éèàçôïÉÈÀÇÔÏ€ eeacoieeacoieu" class Transformation_ConditionalInsertionSimple_ExceptCorrectResult(_VimTest): snippets = ("test", "$1 ${1/(^a).*/(?0:began with an a)/}") From 9e813c7f3e56600e21b8165726899eaa525e922e Mon Sep 17 00:00:00 2001 From: Romain Giot Date: Sat, 19 Oct 2013 15:26:44 +0200 Subject: [PATCH 5/7] Improve the documentation --- doc/UltiSnips.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/UltiSnips.txt b/doc/UltiSnips.txt index 3761be0..42469c9 100644 --- a/doc/UltiSnips.txt +++ b/doc/UltiSnips.txt @@ -1153,10 +1153,10 @@ The options can be any combination of > By default, regular expression matching is case sensitive. With this option, matching is done without regard to case. a - ascii conversion - By default, transformation is made on the raw utf-8 string. With - this option, matching is done with a string converted into ascii. - One use of this option is to replace accentued chars by a non - accentued version. + By default, transformation are made on the raw utf-8 string. With + this option, matching is done on the corresponding ASCII string + instead, for example 'à' will become 'a'. + This option required the python package 'unidecode'. The syntax of regular expressions is beyond the scope of this document. Python regular expressions are used internally, so the python 're' module can be used From de7bff28df45bfe6689e25fb479bdc33de153e6d Mon Sep 17 00:00:00 2001 From: Romain Giot Date: Sat, 19 Oct 2013 15:34:13 +0200 Subject: [PATCH 6/7] Update tests to make test -a option only when unidecode is installed --- test.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/test.py b/test.py index 636855a..af5a70e 100755 --- a/test.py +++ b/test.py @@ -40,6 +40,12 @@ import subprocess from textwrap import dedent +try: + import unidecode + UNIDECODE_IMPORTED = True +except ImportError: + UNIDECODE_IMPORTED = False + # Some constants for better reading BS = '\x7f' ESC = '\x1b' @@ -1472,14 +1478,16 @@ class Transformation_CleverTransformLongLower_ExceptCorrectResult(_VimTest): snippets = ("test", "$1 ${1/(.*)/\L$1\E/}") keys = "test" + EX + "HALLO" wanted = "HALLO hallo" -class Transformation_SimpleCaseAsciiResult(_VimTest): - snippets = ("ascii", "$1 ${1/(.*)/$1/a}") - keys = "ascii" + EX + "éèàçôïÉÈÀÇÔÏ€" - wanted = "éèàçôïÉÈÀÇÔÏ€ eeacoiEEACOIEU" -class Transformation_LowerCaseAsciiResult(_VimTest): - snippets = ("ascii", "$1 ${1/(.*)/\L$1\E/a}") - keys = "ascii" + EX + "éèàçôïÉÈÀÇÔÏ€" - wanted = "éèàçôïÉÈÀÇÔÏ€ eeacoieeacoieu" + +if UNIDECODE_IMPORTED: + class Transformation_SimpleCaseAsciiResult(_VimTest): + snippets = ("ascii", "$1 ${1/(.*)/$1/a}") + keys = "ascii" + EX + "éèàçôïÉÈÀÇÔÏ€" + wanted = "éèàçôïÉÈÀÇÔÏ€ eeacoiEEACOIEU" + class Transformation_LowerCaseAsciiResult(_VimTest): + snippets = ("ascii", "$1 ${1/(.*)/\L$1\E/a}") + keys = "ascii" + EX + "éèàçôïÉÈÀÇÔÏ€" + wanted = "éèàçôïÉÈÀÇÔÏ€ eeacoieeacoieu" class Transformation_ConditionalInsertionSimple_ExceptCorrectResult(_VimTest): snippets = ("test", "$1 ${1/(^a).*/(?0:began with an a)/}") From ce28c27285b2046ad2fa0f740b0f7868789711e3 Mon Sep 17 00:00:00 2001 From: Holger Rapp Date: Wed, 23 Oct 2013 08:10:58 +0200 Subject: [PATCH 7/7] Fixed a small bug. --- plugin/UltiSnips/text_objects/_transformation.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plugin/UltiSnips/text_objects/_transformation.py b/plugin/UltiSnips/text_objects/_transformation.py index 47ea3a3..67784d6 100755 --- a/plugin/UltiSnips/text_objects/_transformation.py +++ b/plugin/UltiSnips/text_objects/_transformation.py @@ -105,13 +105,14 @@ class _CleverReplace(object): class TextObjectTransformation(object): def __init__(self, token): + self._convert_to_ascii = False + self._find = None if token.search is None: return flags = 0 self._match_this_many = 1 - self._convert_to_ascii = False if token.options: if "g" in token.options: self._match_this_many = 0 @@ -144,5 +145,3 @@ class Transformation(Mirror, TextObjectTransformation): def _get_text(self): return self._transform(self._ts.current_text) - -