442 lines
		
	
	
	
		
			8.8 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			442 lines
		
	
	
	
		
			8.8 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
use math
 | 
						||
use path
 | 
						||
use re
 | 
						||
use str
 | 
						||
 | 
						||
var cmd      = $e:qpdf~
 | 
						||
 | 
						||
fn -is-pdf {|f|
 | 
						||
  str:has-suffix $f .pdf
 | 
						||
}
 | 
						||
 | 
						||
fn -is-number {|arg|
 | 
						||
  re:match '^\d+$' $arg
 | 
						||
}
 | 
						||
 | 
						||
fn -is-rotate {|arg|
 | 
						||
  re:match '^(\+|-)(\d+):.*' $arg
 | 
						||
}
 | 
						||
 | 
						||
fn -is-seq {|arg|
 | 
						||
  re:match '^\d+(,\d+)*$' $arg
 | 
						||
}
 | 
						||
 | 
						||
fn -must-pdf {|f|
 | 
						||
  if (not (-is-pdf $f)) {
 | 
						||
    fail $f' n’est pas un fichier PDF'
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
fn -must-not-exist {|f|
 | 
						||
  var exist = ?(stat $f 2>&- > /dev/null)
 | 
						||
  if (bool $exist) {
 | 
						||
    fail $f' existe déjà'
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
fn -must-exist {|f|
 | 
						||
  var exist = ?(stat $f 2>&- > /dev/null)
 | 
						||
  if (not (bool $exist)) {
 | 
						||
    fail $f' n’existe pas'
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
fn -make-tmp {
 | 
						||
  mktemp -q /tmp/qpdf_XXXXXXXXXX.pdf
 | 
						||
}
 | 
						||
 | 
						||
fn -make-seq {|seq|
 | 
						||
  if (not (-is-seq $seq)) {
 | 
						||
    fail $seq': pas une séquence'
 | 
						||
  }
 | 
						||
  set @seq = (order (str:split , $seq))
 | 
						||
  var b = 1
 | 
						||
  each {|ei|
 | 
						||
    var e = (- $ei 1)
 | 
						||
    if (== $b $e) {
 | 
						||
      put $b
 | 
						||
      set b = $ei
 | 
						||
    } elif (< $b $e) {
 | 
						||
      put $b'-'$e
 | 
						||
      set b = $ei
 | 
						||
    }
 | 
						||
  } $seq
 | 
						||
  put $b'-z'
 | 
						||
}
 | 
						||
 | 
						||
fn -out {|in suffix|
 | 
						||
  var out = (str:trim-suffix $in .pdf)
 | 
						||
  str:join '' [ $out .pdf ]
 | 
						||
}
 | 
						||
 | 
						||
fn -parse-selection {|in selection|
 | 
						||
  if (-is-rotate $selection) {
 | 
						||
    var out   = (-make-tmp)
 | 
						||
    var i     = (str:index $selection :)
 | 
						||
    var r sel = $selection[..$i] $selection[(+ $i 1)..]
 | 
						||
    if (eq sel '') {
 | 
						||
      set @sel = $in
 | 
						||
    } else {
 | 
						||
      set @sel = $in $sel
 | 
						||
    }
 | 
						||
    $cmd --empty --pages $@sel -- $out
 | 
						||
    $cmd $out --replace-input --rotate=$r
 | 
						||
    put $out
 | 
						||
  } else {
 | 
						||
    put $in $selection
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
fn -parse-all {|args|
 | 
						||
  var tmpfiles  = []
 | 
						||
  var selection = []
 | 
						||
  var in        = $nil
 | 
						||
  var miss      = $nil
 | 
						||
  try {
 | 
						||
    each {|e|
 | 
						||
      if (-is-pdf $e) {
 | 
						||
        -must-exist $e
 | 
						||
        if (not-eq $miss $nil) {
 | 
						||
          set @selection = $@selection $miss
 | 
						||
          set miss = $e
 | 
						||
        }
 | 
						||
        set in = $e
 | 
						||
      } else {
 | 
						||
        if (eq $in $nil) {
 | 
						||
          fail 'Le pagerange doit être déclaré après un fichier d’entrée'
 | 
						||
        }
 | 
						||
        var @s = (-parse-selection $in $e)
 | 
						||
        if (== (count $s) 1) {
 | 
						||
          set @tmpfiles = $@tmpfiles $@s
 | 
						||
        }
 | 
						||
        set @selection = $@selection $@s
 | 
						||
      }
 | 
						||
    } $args
 | 
						||
  } finally {
 | 
						||
    put $selection $tmpfiles
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
fn -merge {|&collate=$nil selection out|
 | 
						||
  if (< (count $selection) 1) {
 | 
						||
    fail 'Aucune sélection'
 | 
						||
  }
 | 
						||
  var @args = --empty --pages $@selection -- $out
 | 
						||
  if (not-eq $collate $nil) {
 | 
						||
    if (-is-number $collate) {
 | 
						||
      set @args = $collate $@args
 | 
						||
    }
 | 
						||
    set @args = --collate $@args
 | 
						||
  }
 | 
						||
  $cmd $@args
 | 
						||
}
 | 
						||
 | 
						||
fn merge {|@args|
 | 
						||
  var l = (- (count $args) 1)
 | 
						||
  if (< $l 1) {
 | 
						||
    fail "la commande doit contenir au moins 2 paramètres"
 | 
						||
  }
 | 
						||
  var out = $args[$l]
 | 
						||
  -must-pdf $out
 | 
						||
  -must-not-exist $out
 | 
						||
 | 
						||
  var sel tmp = [] []
 | 
						||
  try {
 | 
						||
    set sel tmp = (-parse-all $args[..$l])
 | 
						||
    -merge $sel $out
 | 
						||
  } finally {
 | 
						||
    if (> (count $tmp) 0) {
 | 
						||
      rm -f $@tmp
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
fn split {|@args|
 | 
						||
  var l = (- (count $args) 1)
 | 
						||
  if (< $l 1) {
 | 
						||
    fail "la commande doit contenir au moins 2 paramètres"
 | 
						||
  }
 | 
						||
  var out = $args[$l]
 | 
						||
  -must-pdf $out
 | 
						||
  -must-not-exist $out
 | 
						||
  set args = $args[..$l]
 | 
						||
 | 
						||
  var size = $nil
 | 
						||
  if (-is-number $args[0]) {
 | 
						||
    set size @args = @args
 | 
						||
  }
 | 
						||
 | 
						||
  var sel tmp = [] []
 | 
						||
  try {
 | 
						||
    set sel tmp = (-parse-all $args[..$l])
 | 
						||
    var t = (-make-tmp)
 | 
						||
    -merge $sel $t
 | 
						||
    set @tmp = $@tmp $t
 | 
						||
    var @ac = --split-pages
 | 
						||
    if (not-eq $size $nil) {
 | 
						||
      set @ac = $@ac $size
 | 
						||
    }
 | 
						||
    set @ac = $@ac $t $out/%d.pdf
 | 
						||
    mkdir $out
 | 
						||
    $cmd $@ac
 | 
						||
  } finally {
 | 
						||
    if (> (count $tmp) 0) {
 | 
						||
      rm -f $@tmp
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
fn split-at {|@args|
 | 
						||
  var l = (- (count $args) 1)
 | 
						||
  if (< $l 2) {
 | 
						||
    fail "la commande doit contenir au moins 3 paramètres"
 | 
						||
  }
 | 
						||
  var out = $args[$l]
 | 
						||
  -must-pdf $out
 | 
						||
  -must-not-exist $out
 | 
						||
  var @seq = (-make-seq $args[0])
 | 
						||
  set args = $args[1..$l]
 | 
						||
 | 
						||
  var sel tmp = [] []
 | 
						||
  try {
 | 
						||
    set sel tmp = (-parse-all $args[..$l])
 | 
						||
    var t = (-make-tmp)
 | 
						||
    -merge $sel $t
 | 
						||
    set @tmp = $@tmp $t
 | 
						||
    var i = 1
 | 
						||
    each {|s|
 | 
						||
      $cmd --empty --pages $t $s -- $out/$i.pdf
 | 
						||
      set i = (+ $i 1)
 | 
						||
    } $seq
 | 
						||
  } finally {
 | 
						||
    if (> (count $tmp) 0) {
 | 
						||
      rm -f $@tmp
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
fn zip {|@args|
 | 
						||
  var l = (- (count $args) 1)
 | 
						||
  if (< $l 1) {
 | 
						||
    fail "la commande doit contenir au moins 2 paramètres"
 | 
						||
  }
 | 
						||
  var out = $args[$l]
 | 
						||
  var col = $true
 | 
						||
  -must-pdf $out
 | 
						||
  -must-not-exist $out
 | 
						||
  set args = $args[..$l]
 | 
						||
 | 
						||
  if (-is-number $args[0]) {
 | 
						||
    set col @args = $@args
 | 
						||
  }
 | 
						||
 | 
						||
  var sel tmp = [] []
 | 
						||
  try {
 | 
						||
    set sel tmp = (-parse-all $args)
 | 
						||
    -merge &collate=$col $sel $out
 | 
						||
  } finally {
 | 
						||
    if (> (count $tmp) 0) {
 | 
						||
      rm -f $@tmp
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
fn unzip {|@args|
 | 
						||
  var l = (- (count $args) 1)
 | 
						||
  if (< $l 2) {
 | 
						||
    fail 'unzip doit contenir au moins 3 paramètres'
 | 
						||
  }
 | 
						||
  var mod = $args[0]
 | 
						||
  var out = $args[$l]
 | 
						||
  -must-not-exist $out
 | 
						||
 | 
						||
  var sel tmp = [] []
 | 
						||
  try {
 | 
						||
    set sel tmp = (-parse-all $args[1..$l])
 | 
						||
    var t       = (-make-tmp)
 | 
						||
    -merge $sel $t
 | 
						||
    set @tmp    = $@tmp $t
 | 
						||
    var @sels   = (range $mod | put [])
 | 
						||
    var end     = ($cmd --show-npages $t)
 | 
						||
    range $end | each {|i|
 | 
						||
      var m = (% $i $mod)
 | 
						||
      set sel[$m] = (+ $i 1)
 | 
						||
    }
 | 
						||
    mkdir $out
 | 
						||
    range $mod | each {|i|
 | 
						||
      var @pr = (str:join ',' $@sels[$i])
 | 
						||
      $cmd --empty --pages $t $@pr -- $out'/'(+ $i 1)'.pdf'
 | 
						||
    }
 | 
						||
  } finally {
 | 
						||
    if (> (count $tmp) 0) {
 | 
						||
      rm -f $@tmp
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
fn decrypt {|@args|
 | 
						||
  var l = (count $args)
 | 
						||
  if (or (< $l 1) (> $l 3)) {
 | 
						||
    fail "decrypt doit contenir entre 1 et 3 paramètres"
 | 
						||
  }
 | 
						||
  var in  = $args[0]
 | 
						||
  -must-pdf $in
 | 
						||
  -must-exist $in
 | 
						||
  var out = (-out $in _decrypted.pdf)
 | 
						||
  var p   = $nil
 | 
						||
  if (> $l 1) {
 | 
						||
    set p = $args[1]
 | 
						||
    if (== $l 3) {
 | 
						||
      set out = $args[2]
 | 
						||
      -must-pdf $out
 | 
						||
    }
 | 
						||
  }
 | 
						||
  -must-not-exist $out
 | 
						||
  if (eq $p $nil) {
 | 
						||
    $cmd $in $out --decrypt
 | 
						||
  } else {
 | 
						||
    $cmd $in $out --decrypt $p
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
fn help {|@args|
 | 
						||
  cat $E:HOME/.config/elvish/aliases/qpdf.help
 | 
						||
}
 | 
						||
 | 
						||
fn -date {|raw|
 | 
						||
  var y m d = $raw[2..6] $raw[6..8] $raw[8..10]
 | 
						||
  var h n s = $raw[10..12] $raw[12..14] $raw[14..16]
 | 
						||
  var tz @_ = (str:split "'" $raw[16..])
 | 
						||
  var date = (printf ^
 | 
						||
    '%s-%s-%sT%s:%s:%s%s' ^
 | 
						||
    $y $m $d ^
 | 
						||
    $h $n $s ^
 | 
						||
    $tz)
 | 
						||
  date --date $date
 | 
						||
}
 | 
						||
 | 
						||
fn -pts2cm {|v|
 | 
						||
  / (math:round (* $v 3.52778)) 100
 | 
						||
}
 | 
						||
 | 
						||
fn -size {|size|
 | 
						||
  var u = 0
 | 
						||
  var m = [
 | 
						||
    &10=Kio
 | 
						||
    &20=Mio
 | 
						||
    &30=Gio
 | 
						||
  ]
 | 
						||
  while (< $u 30) {
 | 
						||
    var p = (math:pow 2 (+ $u 10))
 | 
						||
    if (< $size $p) {
 | 
						||
      break
 | 
						||
    }
 | 
						||
    set u = (to-string (+ $u 10))
 | 
						||
  }
 | 
						||
  if (== $u 0) {
 | 
						||
    put $size
 | 
						||
  } else {
 | 
						||
    var p = (math:pow 2 (+ $u 10))
 | 
						||
    var e = (/ $size $p)
 | 
						||
    printf '%.1f%s' $e $m[$u]
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
fn -b2str {|b|
 | 
						||
  if $b {
 | 
						||
    put 'Oui'
 | 
						||
  } else {
 | 
						||
    put 'Non'
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
fn -props {|input json|
 | 
						||
  var objects   = $json[objects]
 | 
						||
  var trailer   = $objects[trailer]
 | 
						||
  var iid       = $trailer[/Info]
 | 
						||
  var rid       = $trailer[/Root]
 | 
						||
  var info      = $objects[$iid]
 | 
						||
  var root      = $objects[$rid]
 | 
						||
  var pages     = $objects[$root[/Pages]]
 | 
						||
  var p1        = $objects[$pages[/Kids][0]][/MediaBox]
 | 
						||
 | 
						||
  var w         = (-pts2cm $p1[2])
 | 
						||
  var h         = (-pts2cm $p1[3])
 | 
						||
  var layout    = 'Portrait'
 | 
						||
  if (> $w $h) {
 | 
						||
    set layout = 'Paysage'
 | 
						||
  }
 | 
						||
 | 
						||
  var props = [
 | 
						||
    &path=(path:abs $input)
 | 
						||
    &fsize=(-size (stat -c '%s' $input))
 | 
						||
    &version=''
 | 
						||
    &psize=(printf '%sx%s cm (%s)' $w $h $layout)
 | 
						||
    &pages=$pages[/Count]
 | 
						||
    &title=''
 | 
						||
    &subject=''
 | 
						||
    &author=''
 | 
						||
    &producer=$info[/Producer]
 | 
						||
    &creator=$info[/Creator]
 | 
						||
    &cdate=(-date $info[/CreationDate])
 | 
						||
    &mdate=''
 | 
						||
    &acroform=(-b2str $json[acroform][hasacroform])
 | 
						||
    &encrypted=(-b2str $json[encrypt][encrypted])
 | 
						||
  ]
 | 
						||
  
 | 
						||
  #@TODO: version pdf
 | 
						||
  if (has-key $info '/Title') {
 | 
						||
    set props[title] = $info[/Title]
 | 
						||
  }
 | 
						||
  if (has-key $info '/Subject') {
 | 
						||
    set props[subject] = $info[/Subject]
 | 
						||
  }
 | 
						||
  if (has-key $info '/Author') {
 | 
						||
    set props[author] = $info[/Author]
 | 
						||
  }
 | 
						||
  if (has-key $info '/ModDate') {
 | 
						||
    set props[mdate] = (-date $info[/ModDate])
 | 
						||
  }
 | 
						||
 | 
						||
  put $props
 | 
						||
}
 | 
						||
 | 
						||
fn info {|@args|
 | 
						||
  var input = $args[0]
 | 
						||
  var json  = ($cmd --json $input | from-json)
 | 
						||
  var props = (-props $input $json)
 | 
						||
 | 
						||
  echo '               Chemin: '$props[path]
 | 
						||
  echo '               Taille: '$props[fsize]
 | 
						||
  echo '          Version PDF: '$props[version]
 | 
						||
  echo '     Taille des pages: '$props[psize]
 | 
						||
  echo '      Nombre de pages: '$props[pages]
 | 
						||
  echo '............................................'
 | 
						||
  echo '                Titre: '$props[title]
 | 
						||
  echo '                Sujet: '$props[subject]
 | 
						||
  echo '               Auteur: '$props[author]
 | 
						||
  echo '             Créateur: '$props[creator]
 | 
						||
  echo '           Producteur: '$props[producer]
 | 
						||
  echo '     Date de création: '$props[cdate]
 | 
						||
  echo ' Date de modification: '$props[mdate]
 | 
						||
  echo '............................................'
 | 
						||
  echo '              Chiffré: '$props[encrypted]
 | 
						||
  echo '             Acroform: '$props[acroform]
 | 
						||
}
 | 
						||
 | 
						||
edit:add-var epdf~ {|action @args|
 | 
						||
  var actions = [
 | 
						||
    &merge=$merge~
 | 
						||
    &split=$split~
 | 
						||
    &split-at=$split-at~
 | 
						||
    &zip=$zip~
 | 
						||
    &unzip=$unzip~
 | 
						||
    &decrypt=$decrypt~
 | 
						||
    &help=$help~
 | 
						||
    &info=$info~
 | 
						||
  ]
 | 
						||
  if (not (has-key $actions $action)) {
 | 
						||
    fail $action': action inconnue'
 | 
						||
  }
 | 
						||
  $actions[$action] $@args
 | 
						||
}
 |