Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
executable file 127 lines (123 sloc) 5.21 KB
#!/usr/bin/perl
#
# ds-convert, v1.0.1, CLI
# Copyright © 2016-2017 Dmitry Sokolov
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Скрипт берёт файл(-ы) шаблона замены подстрок [цветов], созданный скриптом
# ds-collect[colors] и изменённый пользователем, и заменяет подстроки [цвета]
# в указанных в нём файлах. Изменения в шаблоне надо вносить таким образом,
# чтобы значения изменённого [цвета], исходного [цвета] и списка файлов были
# разделены табуляциями. Первая колонка — значение, НА которое нужно заменить
# существующее значение во второй колонке. Пробелы перед значениями учитываются
# при поиске и замене, после значений отбрасываются. Пути заключаются в кавычки
# и разделяются запятыми; например: '/путь/файл', '/путь/файл' и т.д.
# Подробнее: http://sokolov.website/programs/ds-utils/ds-convert
#
# Зависимости: perl
# Рекомендуется: enca
#
# ds-convert [-b] [-e кодировка,кодировка] [файл_шаблона] [файл_шаблона]…
#
# -b — от backup — Создавать бэкапы файлов (по умолчанию — нет).
# -e — от encoding — Кодировки читаемых / сохраняемых файлов, разделённые
# запятой. Пример: CP1251,UTF-8 (по умолчанию — *,UTF-8).
# * означает автоопределение с помощью enca.
# *,* означает сохранение файла в той же кодировке.
# Следите за тем, чтобы кодировка сохраняемого файла
# поддерживала все новые символы в шаблоне замены.
# файл_шаблона — Шаблон замены (по умолчанию — ./colors_templated.cot).
#
# Пример: ds-convert -b -e CP1251|UTF-8 ~/template1.txt ~/template2.txt
#
# Dmitry Sokolov <dmitry@sokolov.website>
use strict;
use warnings;
use utf8;
use open qw/:encoding(UTF-8) :std/;
use POSIX;
use File::Spec;
use File::Copy;
use Getopt::Std;
use Encode;
my (@templates, @colors, @paths, @opte, %opts, $changed);
getopts('be:', \%opts);
$opts{e} = '*,UTF-8' unless exists $opts{e};
$opts{e} = [split(/\s*,\s*/, $opts{e})];
@opte = @{$opts{e}};
@templates = @ARGV ? @ARGV : ('./colors_templated.cot');
foreach(@templates) {
my $fullname = decode("UTF-8", File::Spec->rel2abs($_));
if(-f && -s && -T && open(IN, "<:encoding(UTF-8)", $fullname)) {
while(local $_ = <IN>) {
$_ =~ /^(.+?)\s*\t+(.+?)\s*\t+\s*\'?\s*(.+?)\s*\'?\s*$/;
if($1 ne $2) {
foreach my $path (split(/\s*\'?\s*,\s*\'?\s*/, $3)) {
for(my $i = 0; $i <= scalar @paths; $i++) {
if(scalar @paths == 0
|| ($i == $#paths && $path ne $paths[$i]->{path})) {
$paths[++$#paths] = {
path => $path,
chns => [$1],
orgs => [$2]
};
last;
}
if(scalar @paths != 0 && $path eq $paths[$i]->{path}) {
unless($2 ~~ @{$paths[$i]->{orgs}}) {
@{$paths[$i]->{orgs}}[++$#{$paths[$i]->{orgs}}] = $2;
@{$paths[$i]->{chns}}[++$#{$paths[$i]->{chns}}] = $1;
}
last;
}
}
}
}
}
close(IN);
} else {
print "Can’t open $fullname: $!\n";
}
}
foreach my $path (@paths) {
my $source = undef;
if($opts{e}->[0] eq '*') {
$opte[0] = `enca -r '$path->{path}'` || "UTF-8"; chomp $opte[0];
} else {
$opte[0] = $opts{e}->[0];
}
open(IN, "<:encoding($opte[0])", $path->{path})
or print "Can’t open $path->{path}: $!\n" and next;
while(local $_ = <IN>) {$source .= $_;}
close(IN);
for(my $i = 0; $i < @{$path->{orgs}}; $i++) {
if($source =~ s/\Q$path->{orgs}->[$i]\E/$path->{chns}->[$i]/g) {
$changed = 1;
}
}
if($changed) {
$changed = 0;
copy($path->{path}, $path->{path} . "~")
or print "Can’t make backup of $path->{path}: $!\n" and next
if exists $opts{b};
if($opts{e}->[1] eq '*') {$opte[1] = $opte[0]}
else {$opte[1] = $opts{e}->[1];}
open(OUT, ">:encoding($opte[1])", $path->{path})
or print "Can’t open to write $path->{path}: $!\n" and next;
print OUT $source;
close(OUT);
}
}
exit 0;