elvish_config/lib/moi/util/pdf.elv

285 lines
5.5 KiB
Plaintext
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.

use path
use re
use str
fn is-pdf {|file|
eq (path:ext $file) '.pdf'
}
fn exist {|file|
or (path:is-dir &follow-symlink=$true $file) (path:is-regular &follow-symlink=$true $file)
}
fn not-exist {|file|
not (exist $file)
}
fn is-pdf-exist {|file|
and (is-pdf $file) (exist $file)
}
fn is-number {|v|
re:match '^\d+$' (to-string $v)
}
fn is-page-selection {|v|
re:match '^(r?\d+|z)(-(r?\d+|z))?(,(r?\d+|z)(-(r?\d+|z))?)*(:(even|odd))?$' (to-string $v)
}
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)
}
fn is-selection {|v|
or (is-page-selection $v) (is-rotate-selection $v)
}
fn version {|in|
var version = (head -n 1 $in)
set version @_ = (str:split "\r" $version)
str:trim-prefix $version '%PDF-'
}
fn json {|in|
qpdf $in --json | from-json
}
fn form {|in|
var json = (json $in)
put $json[acroform]
}
fn objects {|in|
var json = (json $in)
put $json[objects]
}
fn -object {|extend objects key|
if (not (has-key $objects $key)) {
put $nil
return
}
var o = $objects[$key]
if (and $extend (eq (kind-of $o) 'map')) {
keys $o | each {|k|
var v = $o[$k]
if (has-key $objects $v) {
set o[$k] = (-object $extend $objects $v)
}
}
}
put $o
}
fn object {|&extend=$false in key|
-object $extend (objects $in) $key
}
fn filter {|&extend=$false in cond|
var objects = (objects $in)
keys $objects | each {|k|
var o = (-object $extend $objects $k)
if ($cond $o) {
put [&id=$k &object=$o]
}
}
}
fn trailer {|in|
object &extend=$true $in 'trailer'
}
fn pages {|in|
var json = (json $in)
put $json[pages]
}
fn nb-pages {|in|
qpdf --show-npages $in
}
fn parse-selection {|@selection|
var out = []
var in = $nil
each {|e|
if (is-pdf $e) {
if (not-exist $e) {
fail (printf '%s: le fichier nexiste pas' $e)
}
if (not-eq $in $nil) {
set @out = $@out $in
}
set in = [
&file=$e
&rotate=$nil
&selections=[]
]
continue
}
if (eq $in $nil) {
fail (printf '%s: pas de fichier avant la sélection' $e)
}
var r rc = $in[rotate] $nil
if (is-page-selection $e) {
set rc = $false
} elif (is-rotate-selection $e) {
set rc = $true
} else {
fail (printf '%s: paramètre invalide' $e)
}
if (not-eq $r $rc) {
if (not-eq $r $nil) {
set @out = $@out $in
set in[selections] = []
}
set in[rotate] = $rc
}
set in[selections] = [ (all $in[selections]) $e ]
} $selection
if (not-eq $in $nil) {
set @out = $@out $in
}
put $out
}
fn -t {
mktemp -q /tmp/qpdf_XXXXXXXXXX.pdf
}
fn rotate {|&empty=$false &out=$nil &keep=$false in @rotate|
var @args = $in
if (eq $out $nil) {
set @args = $@args --replace-input
} else {
set @args = $@args $out
}
if $empty {
set @args = $@args --empty
}
if $keep {
set @rotate = (each {|r| put --rotate=$r } $rotate)
qpdf $@args $@rotate
return
}
var tmp = []
try {
var @tmp = (each {|r|
var t r @s = (-t) (str:split ':' $r)
set s = (str:join ':' $s)
if (eq $s '') {
qpdf $in $t --rotate=$r
} else {
qpdf $in $t --pages $in $s --
qpdf $t --replace-input --rotate=$r
}
put $t
} $rotate)
qpdf $@args --pages $@tmp --
} finally {
rm -f $@tmp
}
}
fn -catarg {|selection|
var f r s = $selection[file] $selection[rotate] $selection[selections]
var out tmp = [] []
if $r {
var t = (-t)
set @tmp = $t
set @out = $@out $t
rotate &out=$t $f $@s
} else {
set @out = $@out $f
if (> (count $s) 0) {
set @out = $@out (str:join ',' $s)
}
}
put $out $tmp
}
fn cat {|&empty=$false &collate=$nil &out=$nil @selection|
var inputs = (parse-selection $@selection)
var pages tmp = [] []
each {|in|
var a t = (-catarg $in)
set @pages = $@pages $@a
set @tmp = $@tmp $@t
} $inputs
try {
var in = $pages[0]
var @args = $in
if (eq $out $nil) {
set @args = $@args --replace-input
} else {
set @args = $@args $out
}
if $empty {
set @args = $@args --empty
}
if (bool $collate) {
var c = --collate
if (is-number $collate) {
set c = (str:join '=' [ $c $collate ])
}
set @args = $@args $c
}
qpdf $@args --pages $@pages --
} finally {
each {|t|
rm -f $t
} $tmp
}
}
fn decrypt {|&out=$nil in @passwd|
var @args = $in
if (eq $out $nil) {
set @args = $@args --replace-input
} else {
set @args = $@args $out
}
set @args = $@args --decrypt
if (> (count $passwd) 0) {
set @args = $@args $passwd[0]
}
qpdf $@args
}
fn -l0 {|n size|
set n = (to-string $n)
var l = (- $size (count $n))
str:join '' [ (repeat $l 0) $n ]
}
fn split {|&empty=$false &size=1 in out|
if (not-exist $out) {
mkdir $out
}
var args = []
if $empty {
set @args = --empty
}
qpdf $@args --split-pages=$size $in $out'/%d.pdf'
}
fn uncat {|&empty=$false in out @selection|
if (not-exist $out) {
mkdir $out
}
var i = 1
var n = (count $selection)
set n = (count (to-string $n))
each {|s|
cat &empty=$empty &out=$out'/'(-l0 $i $n)'.pdf' $in $s
set i = (+ $i 1)
} $selection
}
fn raw-stream {|in out id|
qpdf $in --show-object=$id --raw-stream-data > $out
}
fn filtered-stream {|in out id|
qpdf $in --show-object=$id --filtered-stream-data --normalize-content=n --stream-data=uncompress --decode-level=all > $out
}