なんだか最近プライベートでやってること、興味の方向性に、まったく統一感がありませんが、
いまはPHPで文字数を数えて、原稿用紙換算枚数を出しつつ、LaTexに流し込む、
なんてことに挑戦しています。
LaTexに関しては、もう少し弄り倒してからブログで取り上げるとして、今日はPHPのお話。
今回もダメダメな指標を立てます。
何千枚という分量でもないし、ローカル環境で、個人的にスクリプトを走らせるので、
スマートなソースじゃなくていい。テキトーでいいわけです。
ところが、意外と、UTF-8で書かれた文字数をPHPで数えるのには骨が折れるということが判明。
マルチバイトってうまくいかない。
でも、本家サイトの書き込みに良い方法がありました。
http://www.php.net/manual/ja/function.mb-split.php
正規表現を使って、モード修飾子の”u”を指定しつつ、一文字ずつに分解して、配列にして返すという力技。
[php]
function mb_str_split( $string ) {
return preg_split(‘/(?<!^)(?!$)/um’, $string );
}
[/php]
こういうの大好き(笑)。
ちなみにモード修飾子の”u”と一緒に指定した”m”は、複数行に渡って置換を行うかというものです。
ならば、と、僕も一文字ずつ数えていって、行端の20文字に来たら、禁則文字をチェックして数えていく、
という、さらにそこへ力技をかぶせる方法にしてみました。
[php]
//***************************************************************************
// 原稿用紙換算枚数カウント
// return: 行数
//***************************************************************************
function CountGenkoCharacter($all_text){
//一行の文字数
$wordCount = 20;
//ぶら下がり文字数制限
$hangdownNum = 2;
//行頭禁則:
$kin_line_top = "、。,.・?!゛゜ヽヾゝゞ々ー)]}」』ぁぃぅぇぉっゃゅょァィゥェォッャュョ!),.:;?]}。」、・ー゙゚";
//行末禁則:
$kin_line_end = "([{「『#([{「";
//カウントする行数
$linesNum = 0;
//一行ごとに処理
$array_text = explode( "\n", $all_text );
for ( $i = 0; $i < count($array_text); $i++ ){
$charNum = 0;
$array_char = mb_str_split($array_text[$i]);
while ( count($array_char) > 0 ){
if ($array_char[0] === "" || $array_char[0] === null){
break;
}
if ( $charNum == 0 ){ //行頭禁則のチェック
if ( mb_strpos($kin_line_top, $array_char[0]) !== false){
$charNum = 0;
}
else{
$charNum++;
}
}
elseif ( $charNum > $wordCount-1 ){ //行末禁則のチェック
if ( mb_strpos($kin_line_end, $array_char[0]) !== false){
if ( $charNum > $wordCount+$hangdownNum-1){ //ぶら下がり文字数を超えた
$charNum = 0;
$linesNum++;
}
else{
$charNum++;
}
}
else{
$charNum = 0;
$linesNum++;
}
}
else{
$charNum++;
}
array_shift($array_char);
}
//一行文字数ピッタリの場合は行数をカウントしない
if ( $charNum < $wordCount+1){
$linesNum++;
}
}
return($linesNum);
}
//***************************************************************************
function mb_str_split( $string ) {
# http://www.php.net/manual/ja/function.mb-split.php
# Split at all position not after the start: ^
# and not before the end: $
return preg_split(‘/(?<!^)(?!$)/um’, $string );
}
//***************************************************************************
[/php]
PHPで原稿用紙換算枚数を数えるなんて需要あるのか? と思いつつ、ネットであまり見かけませんでしたので、
GitHubに一式アップロードしておきます。MacからもWindowsからも行けるように、バッチファイル付きです。
https://github.com/hibara/GenkoCount
なんか、数えた結果が正確じゃないぞ、とお気づきの方は、プルリクエストからお願いいたします。
このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください。
日々の開発作業で気づいたこと共有を。同じところで躓いている人が、 検索で辿り着けたら良いな、というスタンスで記事を書くので不定期更新になります。
コメントする