2
0

update library

This commit is contained in:
Dmitry Sedykh
2023-06-11 12:12:54 +03:00
parent 8422236384
commit 93f647e1c7
6 changed files with 123 additions and 84 deletions
+22
View File
@@ -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.
+5
View File
@@ -0,0 +1,5 @@
module github.com/mdigger/translit
go 1.20
require golang.org/x/text v0.9.0
+2
View File
@@ -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=
+45
View File
@@ -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
View File
@@ -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)
}
+1
View File
@@ -2,6 +2,7 @@ package translit_test
import ( import (
"fmt" "fmt"
"github.com/mdigger/translit" "github.com/mdigger/translit"
) )