Redesign the pot file maker

This commit is contained in:
joyqi
2020-08-19 12:57:18 +08:00
parent 06876225c1
commit bba332531b
9 changed files with 145 additions and 213 deletions

View File

@@ -59,7 +59,6 @@ langs:
rm -rf ../usr/langs
mkdir ../usr/langs
git clone https://github.com/typecho/languages.git
#for i in `find . -name '*.po'`; do echo $$i && php msgfmt.php $$i; done;
cd languages/ && for i in `find . -name '*.po'`; do echo `basename $$i` && msgfmt -o `basename $$i .po`.mo `basename $$i`; done;
cp languages/*.mo ../usr/langs/
rm -rf languages
@@ -82,9 +81,7 @@ install:
pot:
cd ../ && php tools/list.php ./ > tools/files.txt
cd ../ && xgettext --files-from=tools/files.txt -Lphp --from-code=UTF-8 --keyword=_t --keyword=_e --keyword=_n:1,2 --no-location --copyright-holder=Typecho --package-name=Typecho --package-version=`grep -E "VERSION = '(.*)'" ./var/Typecho/Common.php | cut -d "'" -f 2` --no-wrap --output=tools/messages.pot
rm -f files.txt
php build_pot.php > messages.pot
test:

141
tools/build_pot.php Normal file
View File

@@ -0,0 +1,141 @@
<?php
$langs = [];
/**
* output lang
*
* @param string $str
*/
function output_lang($str) {
global $langs;
$key = md5($str);
if (!isset($langs[$key])) {
echo $str;
$langs[$key] = true;
}
}
/**
* get all files
*
* @param string $dir
* @param string $pattern
* @return array
*/
function all_files($dir, $pattern = '*') {
$result = array();
$items = glob($dir . '/' . $pattern, GLOB_BRACE);
foreach ($items as $item) {
if (is_file($item)) {
$result[] = $item;
}
}
$items = glob($dir . '/*', GLOB_ONLYDIR);
foreach ($items as $item) {
if (is_dir($item)) {
$result = array_merge($result, all_files($item, $pattern));
}
}
return $result;
}
/**
* get msgid
*
* @param string $value
* @return string
*/
function get_msgid($value) {
if ($value[0] == '"') {
return $value;
} else {
$value = trim($value, "'");
return '"' . str_replace('"', '\"', $value) . '"';
}
}
/**
* get pot from file
*
* @param string $file
* @return string
*/
function get_pot($file) {
$source = file_get_contents($file);
$matched = null;
$plural = [];
foreach (token_get_all($source) as $token) {
if (is_array($token)) {
list ($type, $value) = $token;
if ($type == T_STRING && in_array($value, ['_t', '_e', '_n'])) {
$matched = $value;
} else if ($type == T_CONSTANT_ENCAPSED_STRING && $matched) {
$key = md5($value);
if ($matched == '_n') {
$plural[] = $value;
} else {
output_lang('msgid ' . get_msgid($value) . "\nmsgstr \"\"\n\n");
$matched = null;
}
} else if ($type != T_WHITESPACE) {
$matched = null;
if (!empty($plural)) {
$msgstr = '';
$lang = '';
foreach ($plural as $key => $value) {
$lang .= 'msgid' . ($key == 0 ? '' : '_plural') . ' ' . get_msgid($value) . "\n";
$msgstr .= "msgstr[{$key}] \"\"\n";
}
$lang .= $msgstr . "\n";
output_lang($lang);
$plural = [];
}
}
} else if ($token != ',' && $token != '(') {
$matched = null;
$plural = [];
}
}
}
require_once __DIR__ . '/../var/Typecho/Common.php';
$version = Typecho_Common::VERSION;
$date = date('Y-m-d H:iO');
$year = date('Y');
echo <<<EOF
# Copyright (C) {$year} Typecho
# This file is distributed under the same license as the Typecho Project.
# FIRST AUTHOR <joyqi@typecho.org>, {$year}.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: {$version}\\n"
"Report-Msgid-Bugs-To: \\n"
"POT-Creation-Date: {$date}\\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"
"Language-Team: Typecho Dev <team@typecho.org>\\n"
"Language: \\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=UTF-8\\n"
"Content-Transfer-Encoding: 8bit\\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\\n"\n\n
EOF;
foreach (all_files(__DIR__ . '/../', "*.php") as $file) {
get_pot($file);
}

View File

@@ -1,36 +0,0 @@
<?php
/** 参数不存在则退出 */
if (!isset($argv[1])) {
echo 'no args';
exit(1);
}
/**
* 获取所有文件
*
* @param string $dir
* @param string $pattern
* @return array
*/
function all_files($dir, $pattern = '*') {
$result = array();
$items = glob($dir . '/' . $pattern, GLOB_BRACE);
foreach ($items as $item) {
if (is_file($item)) {
$result[] = $item;
}
}
$items = glob($dir . '/*', GLOB_ONLYDIR);
foreach ($items as $item) {
if (is_dir($item)) {
$result = array_merge($result, all_files($item, $pattern));
}
}
return $result;
}
echo implode("\n", all_files($argv[1], '*.php'));

View File

@@ -4,7 +4,8 @@
"description": "Typecho build tools",
"main": "build.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"build_js": "node build.js js",
"build_css": "node build.js css"
},
"keywords": [
"typecho"

View File

@@ -1,28 +0,0 @@
<?php
/** 参数不存在则退出 */
if (!isset($argv[1])) {
echo 'no args';
exit(1);
}
/** 解析所有的参数 */
parse_str($argv[1], $options);
/** 必要参数检测 */
if (!isset($options['in']) || !isset($options['out'])) {
echo 'no input or output file';
exit(1);
}
$str = php_strip_whitespace($options['in']);
$str = preg_replace("/require_once\s+('|\")[_0-9a-z-\/\.]+\\1\s*;/is", '', $str);
$str = trim(ltrim($str, '<?php'));
if (file_exists($options['out'])) {
$str = file_get_contents($options['out']) . $str;
} else {
$str = '<?php ' . $str;
}
file_put_contents($options['out'], $str);

View File

@@ -1,13 +0,0 @@
<?php
// transfer [] to array()
$file = $argv[1];
$text = file_get_contents($file);
$text = preg_replace("/= \[([^;]*)\];/s", "= array(\\1);", $text);
$text = preg_replace("/(\(| )\[([^\n]*?)\]\)/", "\\1array(\\2))", $text);
$text = preg_replace("/(\(| )\[([^\n]*?)\],/", "\\1array(\\2),", $text);
file_put_contents($file, $text);

View File

@@ -1,110 +0,0 @@
<?php
// transfer namespace based php class to dashed
$dir = $argv[1];
$ns = $argv[2];
$fake = $argv[3];
$files = $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir,
FilesystemIterator::KEY_AS_PATHNAME
| FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::SKIP_DOTS));
$map = [];
$lists = [];
$offset = strlen($dir);
foreach ($files as $file) {
$path = $file->getPathname();
$file = $file->getFilename();
$lists[] = $path;
$dir = dirname($path);
if ($file[0] == '.') {
continue;
}
$path = ltrim(substr($path, $offset), '/\\');
list($class) = explode('.', $path);
$name = str_replace(['/', '\\'], '\\', $fake . '\\' . $class);
$class = str_replace(['/', '\\'], '_', $ns . '_' . $class);
$map[$name] = $class;
}
foreach ($lists as $file) {
$dir = dirname($file);
$source = file_get_contents($file);
$replace = [];
$current = '';
$source = preg_replace_callback("/\nnamespace\s*([a-z_\\\]+);/is", function ($matches) use ($map, $file, &$replace, &$current) {
$matches[1] .= '\\' . pathinfo($file, PATHINFO_FILENAME);
$parts = explode('\\', $matches[1]);
$last = array_pop($parts);
if (isset($map[$matches[1]])) {
$replace[$last] = $map[$matches[1]];
$current = $matches[1];
}
return "if (!defined('__TYPECHO_ROOT_DIR__')) exit;";
}, $source);
$source = preg_replace_callback("/\nuse\s*([a-z_\\\]+)(?:\s+as\s+([a-z_\\\]+))?;/is", function ($matches) use ($map, &$replace) {
$parts = explode('\\', $matches[1]);
$last = array_pop($parts);
if (isset($map[$matches[1]])) {
$replace[$last] = $map[$matches[1]];
}
return '';
}, $source);
foreach ($map as $key => $val) {
if (count(explode('\\', $key)) == count(explode('\\', $current))) {
$parts = explode('_', $val);
$last = array_pop($parts);
if (!isset($replace[$last])) {
$replace[$last] = $val;
}
}
}
$source = str_replace(array('mb_strtoupper', 'mb_strlen'),
array('Typecho_Common::strToUpper', 'Typecho_Common::strLen'), $source);
$tokens = token_get_all($source);
$source = '';
$last = false;
foreach ($tokens as $key => $token) {
if (!is_array($token)) {
$source .= $token;
$last = false;
continue;
}
list ($name, $str) = $token;
if (T_STRING == $name) {
$str = isset($replace[$str]) ? $replace[$str] : $str;
} else if (T_NS_SEPARATOR == $name) {
if (T_STRING == $last) {
$source = substr($source, 0, - strlen($tokens[$key - 1][1]));
}
$str = '';
}
$last = $name;
$source .= $str;
}
file_put_contents($file, $source);
}

View File

@@ -1,20 +0,0 @@
#!/bin/bash
#更新fork之后的Typecho至最新代码
#切换到主目录
cd ..
#增加Typecho源分支地址到本地项目远程分支列表
git remote add official https://github.com/typecho/typecho.git
#查看远程分支列表
#git remote -v
#更新Typecho源分支的新版本到本地
git fetch official
#合并Typecho源分支的代码
git merge official/master
#将合并后的代码push到你自己fork的Tyepcho项目上去
git push origin master