elvish_config/aliases/pdf.elv.save

451 lines
12 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

edit:add-var pdf~ {|action @args|
use flag
use math
use os
use path
use re
use str
use framagit.org/benjamin.vaudour/elv-lib/mods/list
use framagit.org/benjamin.vaudour/elv-lib/mods/map
use framagit.org/benjamin.vaudour/elv-lib/mods/pdf
fn -parse {|rest specs|
var flags = [&]
var @spec = (each {|s|
var d = (map:value-of &default=$false $s 'default')
var sh = $s['short']
var lg = $s['long']
if (has-key $s 'default') {
assoc $s 'arg-required' $true
} else {
set d = $false
assoc $s 'arg-optional' $true
}
set flags[$sh] = $d
set flags[$lg] = $d
} $specs)
var parsed argv = (flag:parse-getopt $rest $spec)
each {|p|
var v = $p['arg']
var s = $p['spec']
var sh = $s['short']
var lg = $s['long']
if (map:value-of &default=$false $s 'arg-optional') {
set v = $true
}
set flags[$sh] = $v
set flags[$lg] = $v
} $parsed
put $flags $argv
}
fn -size {|s|
var b = (num 1024.0)
var u = ['' K M G]
var i = 0
while (and (< $i 3) (>= $s $b)) {
set s i = (/ $s $b) (+ $i 1)
}
if (> $i 0) {
set s = (/ (math:round (* $s 10.0)) 10.0)
}
str:join '' [ (echo $s) $u[$i] ]
}
fn -f {|arg|
if (eq $arg $nil) {
put ''
} elif (pdf:is-string $arg) {
put $arg
} elif (==s (kind-of $arg) 'bool') {
if $arg {
put 'Oui'
} else {
put 'Non'
}
} else {
echo $arg
}
}
fn -format {|title header data|
var size = [&]
each {|c| set size[$c] = (wcswidth $c) } $header
each {|line|
keys $line | each {|k|
var v = $line[$k]
var l = (wcswidth $v)
if (> $l $size[$k]) {
set size[$k] = $l
}
}
} $data
echo (styled $title bold yellow)
if (== (count $data) 0) {
echo 'Aucune donnée…'
} else {
echo (styled (each {|c| pdf:align $c $size[$c] } $header | str:join ' ') bold underlined)
each {|line|
echo (each {|c| pdf:align $line[$c] $size[$c] } $header | str:join ' ')
} $data
}
echo
}
fn help {|@args| e:cat $E:HOME/.config/elvish/aliases/pdf.help }
fn compress {|@rest|
var flags rest = (-parse $rest [
[&short=r &long=resolution &default=$nil]
[&short=t &long=type &default='screen']
])
var input output = (list:value-of $rest 0) (list:value-of $rest 1)
var type resolution = $flags[t] &$flags[r]
pdf:must &not=$true $input {|arg| eq $arg $nil } 'Le fichier dentrée est obligatoire'
pdf:must-pdf-exist $input
if (eq $output $nil) {
set output = (pdf:output $input '_compressed.pdf')
}
pdf:must-pdf-not-exist $output
pdf:must ['default' 'screen' 'ebook' 'printer' 'prepress'] {|arg| has-value $arg $type} (printf '%s: type invalide' $type)
if (not-eq $resolution $nil) {
pdf:must $resolution {|arg| and (pdf:is-number $arg) (>= $arg 72) (<= $arg 300) } 'La résolution doit être comprise entre 72 et 300'
}
pdf:compress &resolution=$resolution &type=$type $input $output
}
fn decrypt {|input @rest|
var output password = (list:value-of &default=(pdf:output $input '_decrypted.pdf') $rest 1) (list:value-of $rest 0)
pdf:must-pdf-exist $input
pdf:must-pdf-not-exist $output
pdf:decrypt &output=$output &password=$password $input
}
fn gray {|input @rest|
var output = (list:value-of &default=(pdf:output $input '_gray.pdf') $rest 0)
pdf:must-pdf-exist $input
pdf:must-pdf-not-exist $output
pdf:gray $input $output
}
fn info {|input|
pdf:must-pdf-exist $input
var json = (pdf:json $input)
var dict = (pdf:objects $json)
var infos = (pdf:object &fmt=$true &rec=$true $dict 'trailer' '/Info')
var page = (pdf:page $json 1)
var dim = (pdf.deep &dict=$dict $page 'object' '/MediaBox')
set dim = [
&w= (pdf:pts2cm $dim[2])
&h= (pdf:pts2cm $dim[3])
]
if (> $dim[w] $dim[h]) {
set dim[l] = 'Paysage'
} else {
set dim[l] = 'Portrait'
}
var encrypted form = 'Non' 'Non'
if (pdf:encryption $json)['encrypted'] {
set encrypted = 'Oui'
}
if (pdf:form $json)['hasacroform'] {
set form = 'Oui'
}
var title = (map:value-of &default='' $infos '/Title')
var subject = (map:value-of &default='' $infos '/Subject')
var author = (map:value-of &default='' $infos '/Author')
var creator = (map:value-of &default='' $infos '/Creator')
var producer = (map:value-of &default='' $infos '/Producer')
var cdate = (map:value-of &default='' $infos '/CreationDate')
var mdate = (map:value-of &default='' $infos '/ModDate')
var result = [
&'Chemin'= (path:abs $input)
&'Version'= (pdf:Version $json)
&'Nombre de pages'= (pdf:nb-pages $input)
&'Format des pages'= (printf '%s×%s cm (%s)' $dim[w] $dim[h] $dim[l])
&'Titre'= $title
&'Sujet'= $subject
&'Auteur'= $author
&'Créateur'= $creator
&'Producteur'= $producer
&'Date de création'= $cdate
&'Date de modification'= $mdate
&'Chiffré'= $encrypted
&'Acroform'= $form
]
var l = 1
keys $result | each {|k|
var w = (+ (wcswidth $k) 1)
if (> $w $l) {
set l = $w
}
}
keys $result each {|k|
var v = $result[$k]
echo (styled (pdf:align $k':' $l)) $v
}
}
fn mono {|@rest|
var flags rest = (-parse $rest [
[&short=d &long=density &default=600]
])
var input output = (list:value-of $rest 0) (list:value-of $rest 1)
var density = $flags[d]
pdf:must &not=$true $input {|arg| eq $arg $nil } 'Le fichier dentrée est obligatoire'
pdf:must-pdf-exist $input
if (eq $output $nil) {
set output = (pdf:output $input '_mono.pdf')
}
pdf:must-pdf-not-exist $output
pdf:must $density {|d| and (pdf:is-number $d) (>= $d 72) (<= $d 1200) } 'La densité doit être comprise entre 72 et 1200'
pdf:mono &density=$density $input $output
}
fn merge {|@selection output|
pdf:must (count $selection) {|c| > $c 0 } 'La commande doit contenir au moins deux paramètres'
pdf:must-pdf-not-exist $output
pdf:merge &output=$output $@selection
}
fn unmerge {|input @selection output|
pdf:must {count $selection} {|c| > $c 0} 'La commande doit contenir au moins trois paramètres'
pdf:must-pdf-exist $input
pdf:must-not-exist $output
pdf:unmerge $input $@selection $output
}
fn split {|@rest input output|
var flags _ = (-parse $rest [
[&short=s &long=size &default=1]
])
var size = $flags[s]
pdf:must-valid $size {|arg |and (pdf:is-number $arg) (> $arg 0) }
pdf:must-pdf-exist $input
pdf:must-not-exist $output
pdf:split &size=$size $input $output
}
fn split-at {|rg input output|
pdf:must-valid $rg {|arg| re:match '^\d+(,\d+)*$' }
var @pages = (str:split ',' $rg | order | compact)
var last = 1
var selection = []
each {|p|
if (== $p $last) {
set @selection = $@selection $p
} elif (> $p $last) {
set @selection = $@selection (printf '%d-%d' $last $p)
}
set last = (+ $p 1)
} $pages
set @selection = $@selection (printf '%d-z' $last)
unmerge $input $@selection $output
}
fn zip {|@rest output|
var flags selection = (-parse $rest [
[&short=c &long=collate &default=0]
])
var collate = $flags[c]
pdf:must-pdf-not-exist $output
pdf:must-valid $collate $pdf:is-number~
pdf:merge &collate &output=$output $@selection
}
fn unzip {|@rest output|
var flags selection = (-parse rest [
[&short=m &long=modulo &default=2]
])
var modulo = $flags[m]
pdf:must-valid $modulo {|arg| and (pdf:is-number $arg) (> $arg 2) }
pdf:must-not-exist $output
var t = (pdf:tmp-pdf)
try {
pdf:merge &output=$t $@selection
var n = (pdf:nb-pages $t)
var @sel = (range $modulo | each {|_| put [] })
range $n {|i|
var s = (% $i $modulo)
set sel[$s] = (conj $sel[$s] (+ $i 1) )
}
set @sel = (each {|s| str:join ',' $s } $sel)
unmerge $t $@sel $output
} catch err {
}
os:remove-all $t
}
fn list {|@rest input|
pdf:must-pdf-exist $input
var flags _ = (-parse $rest [
[&short=a &long=attachments]
[&short=f &long=fonts]
[&short=i &long=images]
])
var json = (pdf:json $input)
if $flags[a] {
var data = (pdf:attachments &fmt=$true &rec=$true $json)
var @attachments = (keys $data | each {|id|
var a = $data[$id]
var name = (pdf:deep $a 'filespec' '/F')
var size = (pdf:deep $a 'filespec' '/EF' '/F' 'dict' '/Params' '/Size')
var mime = (pdf:deep $a 'streams' '/F' 'mimetype')
var desc = (pdf:deep $a 'description')
put [
&'ID'= $id
&'Nom'= $name
&'Taille'= (-size $size)
&'Mimetype'= (-f $mime)
&'Description'= (-f $desc)
]
})
-format 'PIÈCES-JOINTES:' ['ID' 'Nom' 'Taille' 'Mimetype' 'Description'] $attachments
}
if $flags[f] {
var data = (pdf:fonts &fmt=$true &rec=$true $json)
var @fonts = (each {|f|
if (has-key $f '/FontDescriptor') {
put $f
}
} $data | each {|f|
var fd = (pdf:deep $f '/FontDescriptor')
var id = (pdf:deep $fd '/FontFile2' 'object_id')
var file = (pdf:deep $fd '/FontFile2' 'dict')
var name = (pdf:deep $fd '/FontName')
if (not-eq $name $nil) {
set name = (re:replace '^.*\+' '' $name)
}
var basename type encoding = (put '/BaseFont' '/Subtype' '/Encoding' | each {|k|
var v = (pdf:deep $f $k)
if (==s (kind-of $v) 'string') {
str:trim-left $v '/'
} else {
put $v
}
})
put [
&'ID'= $id
&'Nom'= (-f $name)
&'Nom de base'= (-f $basename)
&'Embarqué'= (-f (not-eq $file $nil))
&'Type'= (-f $type)
&'Encodage'= (-f $encoding)
]
})
-format 'POLICES:' ['ID' 'Nom' 'Nom de base' 'Embarqué' 'Type' 'Encodage'] $fonts
}
if $flags[i] {
var data = (pdf:images &fmt=$true &rec=$true $json)
var @images = (each {|i|
var dict = (pdf:deep $i 'object' 'dict')
var id = (pdf:deep $i 'object' 'object_id')
var page = (pdf:deep $i 'page')
var w = (pdf:deep $dict '/Width')
var h = (pdf:deep $dict '/Height')
var size = (pdf:deep $dict '/Length')
var bpc = (pdf:deep $dict '/BitsPerComponent')
var name = (pdf:deep $i 'name')
if (not-eq $name $nil) {
set name = (str:trim-left $name '/')
}
var filter color = (put '/Filter' '/ColorSpace' | each {|k|
var v = (pdf:deep $dict $k)
if (==s (kind-of $v) 'string') {
str:trim-left $v '/'
} else {
put $v
}
})
put [
&'ID'= $id
&'Page'= (-f $page)
&'Nom'= (-f $name)
&'Dimensions'= (printf '%d×%d px' $w $h)
&'Filtre'= (-f $filter)
&'Couleur'= (-f $color)
&'BPC'= (-f $bpc)
&'Taille'= (-size $size)
]
} $data)
-format 'IMAGES:' ['ID' 'Page' 'Nom' 'Dimensions' 'Filtre' 'Couleur' 'BPC' 'Taille'] $images
}
}
var actions = [
&help=$help~
&cat=$merge~
&compress=$compress~
&cut=$split-at~
&decrypt=$decrypt~
#&extract=$extract~
&gray=$gray~
&info=$info~
&list=$list~
&merge=$merge~
&mono=$mono~
&split=$split~
&split-at=$split-at~
&uncat=$unmerge~
&unmerge=$unmerge~
&unzip=$unzip~
&zip=$zip~
]
pdf:must $actions {|arg| has-key $arg $action } (printf '%s: action inconnue' $action)
$actions[$action] $@args
}