update library
This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2023 Dmitry Sedykh <sedykh@gmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
module github.com/mdigger/translit
|
||||||
|
|
||||||
|
go 1.20
|
||||||
|
|
||||||
|
require golang.org/x/text v0.9.0
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||||
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package translit
|
||||||
|
|
||||||
|
// RuMap описывает замены русских букв на английские при транслитерации. Некоторые буквы
|
||||||
|
// заменяются ни на одну, а на две или три буквы латинского алфавита. А мягкий знак вообще исчезает.
|
||||||
|
// Но такова обычная распространенная схема транслитерации.
|
||||||
|
var RuMap = Map{
|
||||||
|
'а': "a",
|
||||||
|
'б': "b",
|
||||||
|
'в': "v",
|
||||||
|
'г': "g",
|
||||||
|
'д': "d",
|
||||||
|
'е': "e",
|
||||||
|
'ё': "yo",
|
||||||
|
'ж': "zh",
|
||||||
|
'з': "z",
|
||||||
|
'и': "i",
|
||||||
|
'й': "j",
|
||||||
|
'к': "k",
|
||||||
|
'л': "l",
|
||||||
|
'м': "m",
|
||||||
|
'н': "n",
|
||||||
|
'о': "o",
|
||||||
|
'п': "p",
|
||||||
|
'р': "r",
|
||||||
|
'с': "s",
|
||||||
|
'т': "t",
|
||||||
|
'у': "u",
|
||||||
|
'ф': "f",
|
||||||
|
'х': "h",
|
||||||
|
'ц': "c",
|
||||||
|
'ч': "ch",
|
||||||
|
'ш': "sh",
|
||||||
|
'щ': "sch",
|
||||||
|
'ъ': "'",
|
||||||
|
'ы': "y",
|
||||||
|
'ь': "",
|
||||||
|
'э': "e",
|
||||||
|
'ю': "ju",
|
||||||
|
'я': "ja",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ru выполняет транслитерацию строки с учетом словаря для русской транслитерации.
|
||||||
|
func Ru(text string) string {
|
||||||
|
return RuMap.Translate(text)
|
||||||
|
}
|
||||||
+48
-84
@@ -12,117 +12,81 @@
|
|||||||
// и заменяет их по предложенному ей словарю. Отличие только в том, что, с моей точки зрения, она
|
// и заменяет их по предложенному ей словарю. Отличие только в том, что, с моей точки зрения, она
|
||||||
// более корректно отрабатывает случаи с чередованием заглавных букв. Например:
|
// более корректно отрабатывает случаи с чередованием заглавных букв. Например:
|
||||||
//
|
//
|
||||||
// "ЧАЩА" -> "CHASCHA"
|
// "ЧАЩА" -> "CHASCHA"
|
||||||
// "ЧаЩа" -> "ChaScha"
|
// "ЧаЩа" -> "ChaScha"
|
||||||
// "Чаща" -> "Chascha"
|
// "Чаща" -> "Chascha"
|
||||||
// "чаЩА" -> "chaSCHA"
|
// "чаЩА" -> "chaSCHA"
|
||||||
//
|
//
|
||||||
// Для транслитерации русских букв в ней уже предусмотрен встроенный словарь. Для других языков
|
// Для транслитерации русских букв в ней уже предусмотрен встроенный словарь. Для других языков
|
||||||
// вы можете задать свой. Все достаточно просто:
|
// вы можете задать свой. Все достаточно просто:
|
||||||
//
|
//
|
||||||
// import "github.com/mdigger/translit"
|
// import "github.com/mdigger/translit"
|
||||||
//
|
//
|
||||||
// tests := []string{
|
// tests := []string{
|
||||||
// "Проверочная СТРОКА для транслитерации",
|
// "Проверочная СТРОКА для транслитерации",
|
||||||
// "ЧАЩА",
|
// "ЧАЩА",
|
||||||
// "ЧаЩа",
|
// "ЧаЩа",
|
||||||
// "Чаща",
|
// "Чаща",
|
||||||
// "чаЩА",
|
// "чаЩА",
|
||||||
// }
|
// }
|
||||||
// for _, text := range tests {
|
// for _, text := range tests {
|
||||||
// fmt.Println(translit.Ru(text))
|
// fmt.Println(translit.Ru(text))
|
||||||
// }
|
// }
|
||||||
package translit
|
package translit
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"golang.org/x/exp/utf8string"
|
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
|
"golang.org/x/text/cases"
|
||||||
|
"golang.org/x/text/language"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RuTransiltMap описывает замены русских букв на английские при транслитерации. Некоторые буквы
|
// Map определяет таблицу подстановки символов при транслитерации.
|
||||||
// заменяются ни на одну, а на две или три буквы латинского алфавита. А мягкий знак вообще исчезает.
|
type Map map[rune]string
|
||||||
// Но такова обычная распространенная схема транслитерации.
|
|
||||||
var RuTransiltMap = map[rune]string{
|
|
||||||
'а': "a",
|
|
||||||
'б': "b",
|
|
||||||
'в': "v",
|
|
||||||
'г': "g",
|
|
||||||
'д': "d",
|
|
||||||
'е': "e",
|
|
||||||
'ё': "yo",
|
|
||||||
'ж': "zh",
|
|
||||||
'з': "z",
|
|
||||||
'и': "i",
|
|
||||||
'й': "j",
|
|
||||||
'к': "k",
|
|
||||||
'л': "l",
|
|
||||||
'м': "m",
|
|
||||||
'н': "n",
|
|
||||||
'о': "o",
|
|
||||||
'п': "p",
|
|
||||||
'р': "r",
|
|
||||||
'с': "s",
|
|
||||||
'т': "t",
|
|
||||||
'у': "u",
|
|
||||||
'ф': "f",
|
|
||||||
'х': "h",
|
|
||||||
'ц': "c",
|
|
||||||
'ч': "ch",
|
|
||||||
'ш': "sh",
|
|
||||||
'щ': "sch",
|
|
||||||
'ъ': "'",
|
|
||||||
'ы': "y",
|
|
||||||
'ь': "",
|
|
||||||
'э': "e",
|
|
||||||
'ю': "ju",
|
|
||||||
'я': "ja",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transliterate выполняет транслитерацию в строке по указанной таблице и возвращает новую строку с
|
// Translate выполняет транслитерацию в строке по указанной таблице и возвращает новую строку с
|
||||||
// результатом такого преобразования. Все символы, которые не указаны в таблице транслитерации,
|
// результатом такого преобразования. Все символы, которые не указаны в таблице транслитерации,
|
||||||
// останутся без изменения.
|
// останутся без изменения.
|
||||||
//
|
//
|
||||||
// При транслитерировании учитывается, что замена буквы может быть произведена на строку
|
// При транслитерации учитывается, что замена буквы может быть произведена на строку
|
||||||
// произвольной длины и корректно обрабатываются чередования заглавных и строчных букв. В частности,
|
// произвольной длины и корректно обрабатываются чередования заглавных и строчных букв. В частности,
|
||||||
// производится корректная транслитерация следующих случаев:
|
// производится корректная транслитерация следующих случаев:
|
||||||
// "ЧАЩА" -> "CHASCHA"
|
//
|
||||||
// "ЧаЩа" -> "ChaScha"
|
// "ЧАЩА" -> "CHASCHA"
|
||||||
// "Чаща" -> "Chascha"
|
// "ЧаЩа" -> "ChaScha"
|
||||||
// "чаЩА" -> "chaSCHA"
|
// "Чаща" -> "Chascha"
|
||||||
|
// "чаЩА" -> "chaSCHA"
|
||||||
//
|
//
|
||||||
// При желании, вы можете указать любую таблицу в качестве второго параметра при вызове функции,
|
// При желании, вы можете указать любую таблицу в качестве второго параметра при вызове функции,
|
||||||
// по которой и будет выполнено данное преобразование.
|
// по которой и будет выполнено данное преобразование.
|
||||||
func Transliterate(text string, translitMap map[rune]string) string {
|
func (m Map) Translate(text string) string {
|
||||||
var result bytes.Buffer
|
src := []rune(text) // преобразуем текст в набор символов
|
||||||
utf8text := utf8string.NewString(text)
|
|
||||||
length := utf8text.RuneCount()
|
var result strings.Builder
|
||||||
for index := 0; index < length; index++ {
|
result.Grow(len(src) * 3) // выделяем память под построение результирующего текста
|
||||||
runeValue := utf8text.At(index)
|
|
||||||
switch str, ok := translitMap[unicode.ToLower(runeValue)]; {
|
for i, r := range src {
|
||||||
case !ok:
|
switch str, ok := m[unicode.ToLower(r)]; {
|
||||||
result.WriteRune(runeValue)
|
case !ok: // не входит в список символов для транслитерации
|
||||||
case str == "":
|
result.WriteRune(r)
|
||||||
|
case str == "": // игнорируется при транслитерации
|
||||||
continue
|
continue
|
||||||
case unicode.IsUpper(runeValue):
|
case unicode.IsUpper(r): // заглавная буква
|
||||||
// Если следующий или предыдущий символ тоже заглавная буква, то все буквы строки
|
if (i > 0 && unicode.IsUpper(src[i-1])) ||
|
||||||
// заглавные. Иначе, заглавная только первая буква.
|
(i < len(src)-1 && unicode.IsUpper(src[i+1])) {
|
||||||
if (length > index+1 && unicode.IsUpper(utf8text.At(index+1))) ||
|
str = strings.ToUpper(str) // преобразуем все буквы в заглавные
|
||||||
(index > 0 && unicode.IsUpper(utf8text.At(index-1))) {
|
|
||||||
str = strings.ToUpper(str)
|
|
||||||
} else {
|
} else {
|
||||||
str = strings.Title(str)
|
str = toTitle.String(str) // преобразуем в заглавную только первый символ замены
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough // выполняем подмену
|
||||||
default:
|
default:
|
||||||
result.WriteString(str)
|
result.WriteString(str) // подменяем символ на транслитерированный
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.String()
|
return result.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ru выполняет транслитерацию строки с учетом словаря для русской транслитерации.
|
// toTitle преобразует первую букву в заглавную.
|
||||||
func Ru(text string) string {
|
var toTitle = cases.Title(language.Und)
|
||||||
return Transliterate(text, RuTransiltMap)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package translit_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/mdigger/translit"
|
"github.com/mdigger/translit"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user