Ajout des sous-commandes extract & list, correction du formatage des octets, correction, ajout de fonctions pour rechercher en profondeur dans l’arborescence des objets pdf, intégration de starship comme prompt + ajout des modules souvent utilisés

This commit is contained in:
Benjamin VAUDOUR 2021-12-24 13:50:36 +00:00
parent 40c07d15d8
commit 39beac61a9
4 changed files with 386 additions and 22 deletions

View File

@ -343,6 +343,195 @@ fn info {|@args|
} $part } $part
} }
fn -list-attachments {|in|
all (pdf:attachments $in)
}
fn -display-attachments {|in|
var @data = (-list-attachments $in)
printf "%d pièce(s)-jointe(s) trouvée(s):\n\n" (count $data)
all $data | each $echo~
echo
}
fn -extract-attachments {|in out|
-list-attachments $in | each {|f|
pdf:attachment $in $out/$f $f
}
}
fn -list-fonts {|in|
pdf:fonts $in | each {|f|
if (has-key $f /FontDescriptor) {
put [&font=$f &fd=$f[/FontDescriptor]]
}
} | each {|f|
if (has-key $f[fd] /FontName) {
assoc $f name $f[fd][/FontName]
}
} | each {|f|
var @_ n = (str:split '+' $f[name])
var font = $f[font]
var fd = $f[fd]
var embed = (has-key $fd /FontFile2)
var file = ''
set n = (str:trim-prefix $n '/')
if $embed {
set file = $fd[/FontFile2]
}
put [
&id=$font[id]
&name=$n
&embed=$embed
&file=$file
&type=(str:trim-prefix $font[/Subtype] '/')
&encoding=(str:trim-prefix $font[/Encoding] '/')
]
}
}
fn -display-fonts {|in|
var @data = (-list-fonts $in)
printf "%d police(s) trouvée(s):\n\n" (count $data)
var props = [
(format:column &align=center id ID)
(format:column name Nom)
(format:column type Type)
(format:column encoding Encodage)
(format:column &align=center embed Téléchargeable)
(format:column &align=center file Fichier)
]
format:list $props $data
echo
}
fn -extract-fonts {|in out|
-list-fonts $in | each {|f|
if $f[embed] {
pdf:filtered-stream $in (printf '%s/%s.ttf' $out $f[name]) $f[file]
}
}
}
fn -list-images {|in|
pdf:images $in | each {|i|
var c = ''
var w = (format:int $i[/Width])
var h = (format:int $i[/Height])
if (has-key $i /ColorSpace) {
set c = $i[/ColorSpace][0]
}
put [
&id=$i[id]
&page=(format:int $i[page])
&name=(str:trim-prefix $i[name] '/')
&width=$w
&height=$h
&dim=(printf '%dx%d' $w $h)
&filter=(str:trim-prefix $i[/Filter] '/')
&size=(format:size $i[/Length])
&bpc=(format:int $i[/BitsPerComponent])
&color=(str:trim-prefix $c '/')
]
}
var objects = (pdf:objects $in)
all (pdf:pages $in) | each {|p|
var pn = (format:int $p[pageposfrom1])
all $p[images] | each {|img|
var id = $img[object]
var o = (pdf:-object &extend=$true $objects $id)
var s = $o[/Length]
var c = ''
var w = (format:int $o[/Width])
var h = (format:int $o[/Height])
if (has-key $o /ColorSpace) {
set c = $o[/ColorSpace][0]
}
put [
&id=$id
&page=$pn
&name=(str:trim-prefix $img[name] '/')
&width=$w
&height=$h
&dim=(printf '%dx%d' $w $h)
&filter=(str:trim-prefix $o[/Filter] '/')
&size=(format:size $s)
&bpc=(format:int $o[/BitsPerComponent])
&color=(str:trim-prefix $c '/')
]
}
}
}
fn -display-images {|in|
var @data = (-list-images $in)
printf "%d image(s) trouvée(s):\n\n" (count $data)
var props = [
(format:column &align=right page Page)
(format:column &align=center id ID)
(format:column name Nom)
(format:column &align=right size Taille)
(format:column &align=right dim Dimensions)
(format:column color Couleur)
(format:column &align=right bpc BPC)
(format:column &align=center filter Filtre)
]
format:list $props $data
echo
}
fn -extract-images {|in out|
# En attendant de savoir décoder correctement les images, on utilise poppler
pdfimages -all $in $out/Im
}
fn list {|@args|
if (!= (count $args) 2) {
fail 'list doit comporter 2 paramètres'
}
var types in = $@args
-must-pdf-exist $in
var display = [
&a=$-display-attachments~
&f=$-display-fonts~
&i=$-display-images~
]
str:split ',' $types | each {|t|
set t = (str:to-lower $t)
-must-valid $t {|e|
and (> (count $e) 0) (has-key $display $e[0])
}
$display[$t[0]] $in
}
}
fn extract {|@args|
if (!= (count $args) 3) {
fail 'extract doit comporter 3 paramètres'
}
var types in out = $@args
-must-pdf-exist $in
-must-not-exist $out
var extr = [
&a=$-extract-attachments~
&f=$-extract-fonts~
&i=$-extract-images~
]
try {
mkdir $out
str:split ',' $types | each {|t|
set t = (str:to-lower $t)
-must-valid $t {|e|
and (> (count $e) 0) (has-key $extr $e[0])
}
$extr[$t[0]] $in $out
}
} except e {
rm -rf $out
fail $e
}
}
edit:add-var pdf~ {|action @args| edit:add-var pdf~ {|action @args|
var actions = [ var actions = [
&help=$help~ &help=$help~
@ -358,8 +547,8 @@ edit:add-var pdf~ {|action @args|
&zip=$zip~ &zip=$zip~
&unzip=$unzip~ &unzip=$unzip~
&info=$info~ &info=$info~
#&list=$list~ &list=$list~
#&extract=$extract~ &extract=$extract~
] ]
if (not (has-key $actions $action)) { if (not (has-key $actions $action)) {
fail (printf '%s: action inconnue' $action) fail (printf '%s: action inconnue' $action)

View File

@ -195,7 +195,7 @@ fn size {|size|
if (== $u 0) { if (== $u 0) {
put $size put $size
} else { } else {
var p = (math:pow 2 (+ $u 10)) var p = (math:pow 2 $u)
var e = (/ $size $p) var e = (/ $size $p)
printf '%.1f%s' $e $m[$u] printf '%.1f%s' $e $m[$u]
} }

View File

@ -30,6 +30,10 @@ fn is-rotate-selection {|v|
re:match '^(\+|-)?\d+(:(r?\d+|z)(-(r?\d+|z))?(,(r?\d+|z)(-(r?\d+|z))?)*(:(even|odd))?)?$' (to-string $v) re:match '^(\+|-)?\d+(:(r?\d+|z)(-(r?\d+|z))?(,(r?\d+|z)(-(r?\d+|z))?)*(:(even|odd))?)?$' (to-string $v)
} }
fn is-object {|v|
re:match '^ \d+\ 0\ R$' $v
}
fn is-selection {|v| fn is-selection {|v|
or (is-page-selection $v) (is-rotate-selection $v) or (is-page-selection $v) (is-rotate-selection $v)
} }
@ -59,39 +63,185 @@ fn objects {|in|
put $json[objects] put $json[objects]
} }
fn -object {|extend objects key| fn -format {|dict o|
if (not (has-key $objects $key)) { var t = (kind-of $o)
put $nil if (eq $t string) {
return if (has-key $dict $o) {
} set o = $dict[$o]
var o = $objects[$key] }
if (and $extend (eq (kind-of $o) 'map')) { } elif (eq $t list) {
keys $o | each {|k| set @o = (all $o | each {|e|
var v = $o[$k] if (has-key $dict $e) {
if (has-key $objects $v) { put $dict[$e]
set o[$k] = (-object $extend $objects $v) } else {
put $e
} }
})
} elif (eq $t map) {
keys $o | each {|k|
set o[$k] = (-format $dict $o[$k])
} }
} }
put $o put $o
} }
fn -deep {|&dict=$nil objects @keys|
if (== (count $keys) 0) {
if (not-eq $dict $nil) {
put (-format $dict $objects) $true
} else {
put $objects $true
}
return
}
if (not-eq $dict $nil) {
set objects = (-format $dict $objects)
}
var id @next = $@keys
var t = (kind-of $objects)
if (eq $t map) {
if (has-key $objects $id) {
-deep &dict=$dict $objects[$id] $@next
}
} elif (eq $t list) {
if (and (is-number $id) (< $id (count $objects))) {
-deep &dict=$dict $objects[$id] $@next
}
} else {
put $nil $false
}
}
fn -object {|&extend=$false objects id|
var dict = $nil
if $extend {
set dict = $objects
}
var o _ = (-deep &dict=$dict $objects $id)
put $o
}
fn deep {|&extend=$false in @keys|
var dict = (objects $in)
if $extend {
-deep &dict=$dict $dict $@keys
} else {
-deep $dict $@keys
}
}
fn contains {|in @keys|
var _ ok = (deep $in $@keys)
put $ok
}
fn value {|&extend=$false in @keys|
var v _ = (deep &extend=$extend $in $@keys)
put $v
}
fn object {|&extend=$false in key| fn object {|&extend=$false in key|
-object $extend (objects $in) $key -object &extend=$extend (objects $in) $key
}
fn -filter {|&extend=$false objects cond|
var out = [&]
keys $objects | each {|k|
var o = (-object &extend=$extend $objects $k)
if ($cond $o) {
set out[$k] = $o
}
}
put $out
} }
fn filter {|&extend=$false in cond| fn filter {|&extend=$false in cond|
var objects = (objects $in) -filter &extend=$extend (objects $in) $cond
keys $objects | each {|k| }
var o = (-object $extend $objects $k)
if ($cond $o) { fn font-filter {|o|
put [&id=$k &object=$o] and ^
(eq (kind-of $o) map) ^
(has-key $o /Type) ^
(eq $o[/Type] /Font)
}
fn fonts {|in|
var dict = (objects $in)
var fonts = (-filter $dict $font-filter~)
keys $fonts | each {|id|
var f = $fonts[$id]
keys $f | each {|k|
var v = $f[$k]
if (has-key $dict $v) {
set f[$k] = $dict[$v]
}
}
var fd = $f[/FontDescriptor]
keys $fd | each {|k|
var v = $fd[$k]
if (and (not-eq $k /FontFile2) (has-key $dict $v)) {
set fd[$k] = $dict[$v]
}
}
set f[/FontDescriptor] = $fd
set f[id] = $id
put $f
}
}
fn image-filter {|o|
and ^
(eq (kind-of $o) map) ^
(has-key $o /Subtype) ^
(eq $o[/Subtype] /Image)
}
fn images {|in|
var json = (json $in)
var dict = $json[objects]
all $json[pages] | each {|p|
var n = $p[pageposfrom1]
all $p[images] | each {|i|
var id = $i[object]
var img = (-object $dict $id)
keys $img | each {|k|
var v = $img[$k]
if (has-key $dict $v) {
set img[$k] = $dict[$v]
}
}
if (has-key $img /ColorSpace) {
var @cs = (all $img[/ColorSpace] | each {|v|
if (has-key $dict $v) {
put $dict[$v]
} else {
put $v
}
})
set img[/ColorSpace] = $cs
}
if (has-key $img /DecodeParms) {
var dp = $img[/DecodeParms]
keys $dp | each {|k|
var v = $dp[$k]
if (has-key $dict $v) {
set dp[$k] = $dict[$v]
}
}
set img[/DecodeParms] = $dp
}
set img[id] = $id
set img[page] = $n
set img[name] = $i[name]
put $img
} }
} }
} }
fn trailer {|in| fn trailer {|&extend=$false in|
object $in 'trailer' object &extend=$extend $in 'trailer'
} }
fn pages {|in| fn pages {|in|
@ -107,6 +257,18 @@ fn nb-pages {|in|
qpdf --show-npages $in qpdf --show-npages $in
} }
fn attachments {|in|
var data = []
var json = (json $in)
var attachments = $json[attachments]
if (> (count $attachments) 0) {
set @data = (qpdf --list-attachments $in | eawk {|_ f @_|
put $f
})
}
put $data
}
fn parse-selection {|@selection| fn parse-selection {|@selection|
var out = [] var out = []
var in = $nil var in = $nil
@ -291,3 +453,7 @@ fn raw-stream {|in out id|
fn filtered-stream {|in out id| fn filtered-stream {|in out id|
qpdf $in --show-object=$id --filtered-stream-data --normalize-content=n --stream-data=uncompress --decode-level=all > $out qpdf $in --show-object=$id --filtered-stream-data --normalize-content=n --stream-data=uncompress --decode-level=all > $out
} }
fn attachment {|in out id|
qpdf $in --show-attachment=$id > $out
}

9
rc.elv
View File

@ -3,6 +3,7 @@ set-env BAT_PAGER 'less -RF'
set-env EDITOR vim set-env EDITOR vim
set-env VIEW 'vim -R' set-env VIEW 'vim -R'
set-env CURRENT_SHELL 'elvish' set-env CURRENT_SHELL 'elvish'
set-env STARSHIP_CONFIG ~/.config/starship/starship.toml
set paths = [$@paths /home/benjamin/bin /home/benjamin/Go/bin ] set paths = [$@paths /home/benjamin/bin /home/benjamin/Go/bin ]
{ {
@ -19,13 +20,21 @@ set edit:insert:binding[Ctrl-H] = $edit:histlist:start~
set edit:prompt = { go-prompt } set edit:prompt = { go-prompt }
set edit:rprompt = { nop } set edit:rprompt = { nop }
#eval (starship init elvish)
eval (starship init elvish --print-full-init | upgrade-scripts-for-0.17 -lambda | slurp)
# Carapace completion: https://github.com/rsteube/carapace-bin # Carapace completion: https://github.com/rsteube/carapace-bin
eval (carapace _carapace|slurp) eval (carapace _carapace|slurp)
# On ajoute les modules natifs que jutilise beaucoup
use str
use re
use math
use moi/completion use moi/completion
use moi/alias use moi/alias
use moi/util/common use moi/util/common
use moi/util/format
{ {
use ./aliases/get-uid uid use ./aliases/get-uid uid