44package main
55
66import (
7- "bufio"
87 "flag"
98 "fmt"
109 "html/template"
11- "io"
1210 "log"
1311 "net/http"
1412 "os"
1513 "sort"
1614 "strings"
17- "unicode"
1815
16+ "github.com/mpl/phoru"
1917 "github.com/mpl/simpletls"
2018)
2119
@@ -33,26 +31,26 @@ func usage() {
3331 fmt .Fprintf (os .Stderr , "example:\n \t echo privet mir | phoru\n " )
3432 fmt .Fprintf (os .Stderr , "\n translation tables:\n " )
3533 var sortedSingle , sortedDouble , sortedTriple []string
36- for k , _ := range single {
34+ for k , _ := range phoru . Single {
3735 sortedSingle = append (sortedSingle , k )
3836 }
39- for k , _ := range double {
37+ for k , _ := range phoru . Double {
4038 sortedDouble = append (sortedDouble , k )
4139 }
42- for k , _ := range triple {
40+ for k , _ := range phoru . Triple {
4341 sortedTriple = append (sortedTriple , k )
4442 }
4543 sort .Strings (sortedSingle )
4644 sort .Strings (sortedDouble )
4745 sort .Strings (sortedTriple )
4846 for _ , v := range sortedSingle {
49- fmt .Fprintf (os .Stderr , "\t %v : %v\n " , v , string (single [v ]))
47+ fmt .Fprintf (os .Stderr , "\t %v : %v\n " , v , string (phoru . Single [v ]))
5048 }
5149 for _ , v := range sortedDouble {
52- fmt .Fprintf (os .Stderr , "\t %v : %v\n " , v , string (double [v ]))
50+ fmt .Fprintf (os .Stderr , "\t %v : %v\n " , v , string (phoru . Double [v ]))
5351 }
5452 for _ , v := range sortedTriple {
55- fmt .Fprintf (os .Stderr , "\t %v : %v\n " , v , string (triple [v ]))
53+ fmt .Fprintf (os .Stderr , "\t %v : %v\n " , v , string (phoru . Triple [v ]))
5654 }
5755 fmt .Fprintf (os .Stderr , "\n in server mode:\n \t phoru -http=:6060\n " )
5856 flag .PrintDefaults ()
@@ -73,53 +71,6 @@ The Russian alphabet
7371// around combinations. For now, changing iy into ï. I didn't hit any other
7472// breaking example so far, but we'll see when my vocabulary extends.
7573
76- var (
77- single = map [string ]rune {
78- "a" : 'а' ,
79- "b" : 'б' ,
80- "v" : 'в' ,
81- "g" : 'г' ,
82- "d" : 'д' ,
83- "e" : 'е' ,
84- "j" : 'ж' ,
85- "i" : 'и' ,
86- "ï" : 'й' ,
87- "z" : 'з' ,
88- "k" : 'к' ,
89- "l" : 'л' ,
90- "m" : 'м' ,
91- "n" : 'н' ,
92- "o" : 'о' ,
93- "p" : 'п' ,
94- "r" : 'р' ,
95- "s" : 'с' ,
96- "t" : 'т' ,
97- "u" : 'у' ,
98- "f" : 'ф' ,
99- "x" : 'х' ,
100- "î" : 'ы' ,
101- "è" : 'э' ,
102- }
103- double = map [string ]rune {
104- "yo" : 'ё' ,
105- "ch" : 'ч' ,
106- "sh" : 'ш' ,
107- "ya" : 'я' ,
108- "b-" : 'ь' ,
109- "i_" : 'й' , // redundant with ï for non-accented keymaps
110- "i-" : 'ы' , // redundant with î for non-accented keymaps
111- "`e" : 'э' , // redundant with è for non-accented keymaps
112- }
113- triple = map [string ]rune {
114- "shh" : 'щ' ,
115- "you" : 'ю' ,
116- // TODO(mpl): find a better solution for the "тс" VS "ц"
117- // conflict. Especially since ц is way more frequent than тс (in my
118- // limited experience).
119- "ts-" : 'ц' ,
120- }
121- )
122-
12374func main () {
12475 flag .Usage = usage
12576 flag .Parse ()
@@ -129,9 +80,9 @@ func main() {
12980
13081 if * flagHttp != "" {
13182 baseData = & Translation {
132- Single : single ,
133- Double : double ,
134- Triple : triple ,
83+ Single : phoru . Single ,
84+ Double : phoru . Double ,
85+ Triple : phoru . Triple ,
13586 }
13687 tmpl = template .Must (template .New ("root" ).Parse (HTML ))
13788 http .HandleFunc ("/phoru/" , makeHandler (apiHandler ))
@@ -146,103 +97,13 @@ func main() {
14697 log .Fatal (http .ListenAndServe (* flagHttp , nil ))
14798 }
14899
149- trans , err := phoru (os .Stdin )
100+ trans , err := phoru . Translate (os .Stdin )
150101 if err != nil {
151102 log .Fatal (err )
152103 }
153104 fmt .Fprintf (os .Stdout , "%v" , string (trans ))
154105}
155106
156- func phoru (r io.Reader ) ([]rune , error ) {
157- var out []rune
158- sc := bufio .NewScanner (r )
159- var skipTwo , skipOne bool
160- firstLine := true
161- for sc .Scan () {
162- if ! firstLine {
163- out = append (out , '\n' )
164- } else {
165- firstLine = false
166- }
167- words := strings .Fields (sc .Text ())
168- for j , word := range words {
169- if j != 0 {
170- out = append (out , rune (' ' ))
171- }
172- var runes , trans []rune
173- for _ , v := range word {
174- runes = append (runes , v )
175- }
176- for i , r := range runes {
177- isUpper := false
178- if skipTwo {
179- skipTwo = false
180- skipOne = true
181- continue
182- }
183- if skipOne {
184- skipOne = false
185- continue
186- }
187- if * flagVerbose {
188- fmt .Fprintf (os .Stderr , "%v" , string (r ))
189- }
190- isUpper = unicode .IsUpper (r )
191- if isUpper {
192- r = unicode .ToLower (r )
193- runes [i ] = r
194- }
195- cyril , n := toCyrillic (runes , i )
196- if isUpper {
197- cyril = unicode .ToUpper (cyril )
198- }
199- trans = append (trans , cyril )
200- // TODO(mpl): something more elegant?
201- if n == 3 {
202- skipTwo = true
203- } else if n == 2 {
204- skipOne = true
205- }
206- if * flagVerbose {
207- fmt .Fprintf (os .Stderr , " -> %v\n " , string (trans [len (trans )- 1 :]))
208- }
209- }
210- out = append (out , trans ... )
211- }
212- }
213- if err := sc .Err (); err != nil {
214- return nil , err
215- }
216- return out , nil
217- }
218-
219- // toCyrillic converts to a cyrillic rune the next rune from runes, starting at
220- // runes[i]. It returns the converted rune, as well as the number of runes that
221- // were "consumed" from runes.
222- func toCyrillic (runes []rune , index int ) (cyril rune , read int ) {
223- i := index
224- switch {
225- case len (runes [i :]) > 2 :
226- if cyril , ok := triple [string (runes [i :i + 3 ])]; ok {
227- return cyril , 3
228- }
229- fallthrough
230- case len (runes [i :]) > 1 :
231- if cyril , ok := double [string (runes [i :i + 2 ])]; ok {
232- return cyril , 2
233- }
234- fallthrough
235- case len (runes [i :]) == 1 :
236- if cyril , ok := single [string (runes [i :i + 1 ])]; ok {
237- return cyril , 1
238- }
239- fallthrough
240- default :
241- log .Printf ("unknown rune: %v" , string (runes [i ]))
242- return runes [i ], 1
243- }
244- }
245-
246107const idstring = "http://golang.org/pkg/http/#ListenAndServe"
247108
248109var (
@@ -285,7 +146,7 @@ func apiHandler(w http.ResponseWriter, r *http.Request, url string) {
285146 }
286147 return
287148 }
288- cyril , err := phoru (strings .NewReader (latin ))
149+ cyril , err := phoru . Translate (strings .NewReader (latin ))
289150 if err != nil {
290151 log .Printf ("translation error: %v" , err )
291152 http .Error (w , "translation error" , 500 )
@@ -308,7 +169,7 @@ func rootHandler(w http.ResponseWriter, r *http.Request, url string) {
308169 return
309170 }
310171 input := r .FormValue ("inputtext" )
311- trans , err := phoru (strings .NewReader (input ))
172+ trans , err := phoru . Translate (strings .NewReader (input ))
312173 if err != nil {
313174 log .Printf ("translation error: %v" , err )
314175 http .Error (w , "translation error" , 500 )
@@ -318,9 +179,9 @@ func rootHandler(w http.ResponseWriter, r *http.Request, url string) {
318179 Input : input ,
319180 Output : string (trans ),
320181 IsPost : true ,
321- Single : single ,
322- Double : double ,
323- Triple : triple ,
182+ Single : phoru . Single ,
183+ Double : phoru . Double ,
184+ Triple : phoru . Triple ,
324185 }
325186 if err := tmpl .Execute (w , data ); err != nil {
326187 log .Printf ("template error: %v" , err )
0 commit comments