Skip to content

Instantly share code, notes, and snippets.

@filipeandre
Created April 20, 2018 19:04
Show Gist options
  • Save filipeandre/6e8e52a22505fc68f37a6b85b3319b42 to your computer and use it in GitHub Desktop.
Save filipeandre/6e8e52a22505fc68f37a6b85b3319b42 to your computer and use it in GitHub Desktop.
Simple script to replace inline blade translations with keys and create the translation file based on $t function passed from controler
package main
import (
"os"
"io"
"regexp"
"path/filepath"
"bufio"
"strings"
"bytes"
"fmt"
"log"
"strconv"
"time"
)
//Settings
const (
maxKeySize = 10
rootFolder = "where/to/search/for/translations"
langFile = "destination/translation/folder"
)
//Regex
var (
matchAllSpaces = regexp.MustCompile(`\s`)
matchTranslation = regexp.MustCompile(`\$t\("?'?(.*?)("|')\)`)
matchSpecialCharacters = regexp.MustCompile("[^a-zA-Z0-9_]+")
)
// Convert full string to full snake
func ToSnakeCase(str string) string {
snake := matchAllSpaces.ReplaceAllString(str, "${1}_${2}")
return strings.ToLower(snake)
}
// If has error then break the app
func check(e error) {
if e != nil {
log.Fatal(e)
}
}
// Check if path a directory
func IsDirectory(path string) (bool, error) {
fileInfo, err := os.Stat(path)
return fileInfo.IsDir(), err
}
// Read a whole file into the memory and store it as array of lines
func readLines(path string) (lines []string, err error) {
var (
file *os.File
part []byte
prefix bool
)
if file, err = os.Open(path); err != nil {
return
}
defer file.Close()
reader := bufio.NewReader(file)
buffer := bytes.NewBuffer(make([]byte, 0))
for {
if part, prefix, err = reader.ReadLine();
err != nil {
break
}
buffer.Write(part)
if !prefix {
lines = append(lines, buffer.String())
buffer.Reset()
}
}
if err == io.EOF {
err = nil
}
return
}
// Write all file lines back into file
func writeLines(lines []string, path string) (err error) {
var (
file *os.File
)
if file, err = os.Create(path); err != nil {
return
}
defer file.Close()
lastI := len(lines) -1
for i,item := range lines {
tmp := item
if lastI != i {
tmp = tmp + "\n"
}
_, err = file.WriteString(tmp)
check(err)
}
return
}
func writeLangFile(translations map[string]string, path string) (err error) {
var lines []string
lines = append(lines, "<?php return array (")
for key,value := range translations {
lines = append(lines, " '" + key + "' => '" + value + "',")
}
lines = append(lines, ");")
writeLines(lines, path)
return
}
func main() {
start := time.Now()
fmt.Println("Working...")
var files []string
translations := make(map[string]string)
counter := 0
err := filepath.Walk(rootFolder, func(path string, info os.FileInfo, err error) error {
isDir, err1 := IsDirectory(path)
check(err1)
if !isDir {
files = append(files, path)
}
return nil
})
check(err)
for _, path := range files {
lines, err := readLines(path)
check(err)
for i, line := range lines {
lines[i] = matchTranslation.ReplaceAllStringFunc(line, func(m string) string{
parts := matchTranslation.FindStringSubmatch(m)
tmp := parts[1]
if len(tmp) > 20 {
runes := []rune(tmp)
counter++
tmp = string(runes[0:20]) + strconv.Itoa(counter)
}
tmp = ToSnakeCase(tmp)
tmp = matchSpecialCharacters.ReplaceAllString(tmp, "")
translations[tmp] = parts[1]
return strings.Replace(m, parts[1], tmp, -1)
})
}
err = writeLines(lines, path)
check(err)
}
err = writeLangFile(translations, langFile)
check(err)
t := time.Now()
elapsed := t.Sub(start)
fmt.Printf("Finished in %vms", elapsed.Nanoseconds()/1e6 )
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment