2015年8月11日

バッチファイルで数値か判定したいがfindstrの正規表現は貧弱と言うので,貧弱な正規表現じゃダメならば普通のを使えばよいじゃないと思ってpowershell呼び出し.

@echo off
powershell -Command "& {'%1' -match '^[0-9]*(\.[0-9]+)?$'}" | find "True" > nul
if "%ERRORLEVEL%" == "0" (echo NUMBER) else (echo NOT NUMBER)

求めているのはこんなんではないようですが……(面白くない的な意味で).そもそも..がまずいならばそれを弾けばいいだけな気もするけど.

それはさておき,PowerShellの使い方を少し覚えてみようと思って,例のバッチファイルをPowerShellで書いてみた.

$pdftex = "pdftex"
$pdftex = "pdftex"
$gs = "rungs"
$extractbb = "extractbb"

$debug = $FALSE
$hires = $FALSE
$separate = $FALSE
$margin_left = 0
$margin_right = 0
$margin_top = 0
$margin_bottom = 0
$i = 0
if($args[$i] -eq "/d"){$debug = $TRUE;++$i;}
if($args[$i] -eq "/h"){$hires = $TRUE;++$i;}
if($args[$i] -eq "/s"){$separate = $TRUE;++$i;}

$inp = $args[$i]
$output = $args[$i + 1]
$page_range = $args[$i + 2]
$b = [double]::TryParse($args[$i + 3],[ref]$margin_left)
$b = [double]::TryParse($args[$i + 4],[ref]$margin_top)
$b = [double]::TryParse($args[$i + 5],[ref]$margin_right)
$b = [double]::TryParse($args[$i + 6],[ref]$margin_bottom)
$def_tex_files = @()


if($inp -eq $null -or -not (Test-Path $inp)){
  Write-Output "file is not found"
  exit
}
$input_dir = [System.IO.Path]::GetDirectoryName($inp)
if($input_dir -eq ""){$input_dir = Get-Location}

if($output -eq $null -or $output -eq ""){
  $output = [System.IO.Path]::Combine($input_dir,[System.IO.Path]::GetFileNameWithoutExtension($inp) + "-crop.pdf");
}

$ret = &"$extractbb" -O $inp
$pages = -1
foreach($out in $ret){
  if($out -match "^%%Pages: *(\d+)"){
    $b = [int]::TryParse($matches[1],[ref]$pages)
  }
}

$first_page = 1
$last_page = $pages
if($page_range -ne "" -and $page_range -ne $null){
  if($page_range -match "^(\d+|\*)-(\d+|\*)$"){
    if($matches[1] -ne "*"){$b = [int]::TryParse($matches[1],[ref]$first_page)}
    if($matches[2] -ne "*"){$b = [int]::TryParse($matches[2],[ref]$last_page)}
  }else{
    $b = [int]::TryParse($page_range,[ref]$first_page)
    if($b -eq $TRUE){$last_page = $first_page}
  }
}

function GetTempFile($dir){
    for($i = 0 ; $i -lt 1000 ; ++$i) {
    $random = [System.IO.Path]::ChangeExtension([System.IO.Path]::GetRandomFileName(), ".tex");
    if(-not ([System.IO.File]::Exists([System.IO.Path]::Combine($dir, $random)))) {
      return $random;
    }
  }
  return $null
}

$tmpdir = $input_dir
$tmpfile = GetTempFile($tmpdir)
$del_tex_files += [System.IO.Path]::Combine($tmpdir,[System.IO.Path]::  GetFileNameWithoutExtension($tmpfile))

$bb_left = @{}
$bb_right = @{}
$bb_bottom = @{}
$bb_top = @{}
for($i = $first_page ; $i -le $last_page ; ++$i){
  $bb_left[$i] = 0;$bb_right[$i] = 0;$bb_bottom[$i] = 0;$bb_top[$i] = 0;
  $reg = ""
  if($hires){$reg = "^%%HiResBoundingBox: ([-\d\.]+) ([-\d\.]+) ([-\d\.]+) ([-\d\.]+)$"}
  else{$reg = "^%%BoundingBox: ([-\d\.]+) ([-\d\.]+) ([-\d\.]+) ([-\d\.]+)$"}
  $ret = &"$gs" -dBATCH -dNOPAUSE -q -sDEVICE=bbox -dFirstPage="$i" -dLastPage="$i" "$inp" 2>&1
  foreach($s in $ret){
    if($s -match $reg){
      $x = 0
      $b = [double]::TryParse($matches[1],[ref]$x);$bb_left[$i] = $x - $margin_left;
      $b = [double]::TryParse($matches[2],[ref]$x);$bb_bottom[$i] = $x - $margin_bottom;
      $b = [double]::TryParse($matches[3],[ref]$x);$bb_right[$i] = $x + $margin_right;
      $b = [double]::TryParse($matches[4],[ref]$x);$bb_top[$i] = $x + $margin_top;
    }
  }
}

Push-Location $tmpdir
$source = @()
for($i = $first_page ; $i -le $last_page ; ++$i){
  $s = "\pdfhorigin=$(-$bb_left[$i])bp\relax`n"
  $s += "\pdfvorigin=$($bb_bottom[$i])bp\relax`n"
  $s += "\pdfpagewidth=$($bb_right[$i] - $bb_left[$i])bp\relax`n"
  $s += "\pdfpageheight=$($bb_top[$i] - $bb_bottom[$i])bp\relax`n"
  $s += "\setbox0=\hbox{\pdfximage page $i mediabox {$inp}\pdfrefximage\pdflastximage}\relax`n"
  $s += "\ht0=\pdfpageheight\relax`n"
  $s += "\shipout\box0\relax`n"
  $source += $s
}
$s = "\pdfoutput=1\relax`n" + [String]::Join("",$source) + "\bye"
"$s" | Out-File $tmpfile -encoding UTF8
$ret = &"$pdftex" --no-shell-escape -interaction=batchmode "$tmpfile" 2>&1
Pop-Location

$generated_file = [System.IO.Path]::Combine($tmpdir,[System.IO.Path]::ChangeExtension($tmpfile,".pdf"))
Move-Item $generated_file $output -Force

if(-not $debug){
  foreach($f in $del_tex_files){
    $del = $f + ".*"
    Remove-Item $del;
  }
}

エラー処理はサボっているし,/sは反応しないので同じじゃないですが.割ときちんとしたプログラミング言語なんだけど,シェルスクリプト的な要素も備えているので,特に文字列的なところで何度かはまった.もう少しきちんとわかれば大丈夫そうな気もする.どーしてもバッチファイルがいいって人は,次を一行目に挿入するとよいようですよ!(PowerShellのスクリプトはデフォルトでは普通には起動できないので,ギャグではない意味もあるかも.)

@powershell -NoProfile -ExecutionPolicy Unrestricted "$s=[scriptblock]::create((gc \"%~f0\"|?{$_.readcount -gt 1})-join\"`n\");&$s" %*&goto:eof

0 件のコメント:

コメントを投稿

コメントの追加にはサードパーティーCookieの許可が必要です