Skip to content
Permalink
Browse files

Fix #71, #72

  • Loading branch information...
hhrutter committed Mar 27, 2019
1 parent b2c24ae commit 80aa62c9dd3076f631a9f903cb7c9779d40fd3db
Showing with 53 additions and 37 deletions.
  1. +7 −1 README.md
  2. +0 −7 pkg/api/api.go
  3. +28 −23 pkg/api/process_test.go
  4. +0 −1 pkg/pdfcpu/context.go
  5. +4 −2 pkg/pdfcpu/dict.go
  6. +8 −1 pkg/pdfcpu/read.go
  7. +5 −1 pkg/pdfcpu/validate/structTree.go
  8. +1 −1 pkg/pdfcpu/writePages.go
@@ -69,12 +69,18 @@ Even if you want to dive right into pdfcpu backend integration it is highly reco
## Status

[Version: 0.1.22](https://github.com/hhrutter/pdfcpu/releases/tag/v0.1.22)

* Support for `go mod`
* Command completion
* `pages insert` inserts empty pages before all selected pages
* `pages remove` removes all selected pages
* Bug fixes #64, #65, #68, #69

## Reminder

Always make sure your work is based on the latest commit!<br>
pdfcpu is still *Alpha* - bugfixes are committed on the fly and will be mentioned on the next release notes.<br>

## Demo Screencast

(using older version with a smaller command set)
@@ -112,7 +118,7 @@ pdfcpu ve
* Feature requests - always welcome!
* Bug fixes - always welcome!
* PRs - also welcome, although I can't promise a merge-in right now.
* pdfcpu is stable but still alpha and occasionally undergoing heavy changes.
* pdfcpu is stable but still *Alpha* and occasionally undergoing heavy changes.

### How

@@ -207,7 +207,6 @@ func writeSinglePagePDF(ctx *pdf.Context, pageNr int, dirOut string) error {
ctx.ResetWriteContext()

w := ctx.Write
w.Command = "ExtractPages"
w.SelectedPages[pageNr] = true
w.DirName = dirOut + "/"
w.FileName = singlePageFileName(ctx, pageNr)
@@ -330,7 +329,6 @@ func pageRangeFileName(ctx *pdf.Context, from, thru int) string {
func writeSpan(ctx *pdf.Context, from, thru int, dirOut string) error {
ctx.ResetWriteContext()
w := ctx.Write
w.Command = "Split"
w.SelectedPages = selectedPageRange(from, thru)
w.DirName = dirOut + "/"
w.FileName = pageRangeFileName(ctx, from, thru)
@@ -457,8 +455,6 @@ func Merge(cmd *Command) ([]string, error) {
return nil, err
}

ctxDest.Write.Command = "Merge"

dirName, fileName := filepath.Split(fileOut)
ctxDest.Write.DirName = dirName
ctxDest.Write.FileName = fileName
@@ -995,7 +991,6 @@ func Trim(cmd *Command) ([]string, error) {
return nil, err
}

ctx.Write.Command = "Trim"
ctx.Write.SelectedPages = pages

dirName, fileName := filepath.Split(fileOut)
@@ -1363,7 +1358,6 @@ func ImportImages(cmd *Command) ([]string, error) {
return nil, err
}

ctx.Write.Command = "Import"
dirName, fileName := filepath.Split(fileOut)
ctx.Write.DirName = dirName
ctx.Write.FileName = fileName
@@ -1577,7 +1571,6 @@ func NUp(cmd *Command) ([]string, error) {
return nil, err
}

ctx.Write.Command = "N-Up"
dirName, fileName := filepath.Split(fileOut)
ctx.Write.DirName = dirName
ctx.Write.FileName = fileName
@@ -66,6 +66,8 @@ func ExampleReadContext() {
// This allows to run pdf as a backend to an http server for on the fly pdf processing.

config := pdf.NewDefaultConfiguration()
config.Cmd = pdf.OPTIMIZE

fileIn := filepath.Join(inDir, "CenterOfWhy.pdf")
fileOut := filepath.Join(outDir, "test.pdf")

@@ -125,15 +127,17 @@ func ExampleReadContext() {

}

func TestReadSeekerAndWriter(t *testing.T) {
func TestOptimizeUsingReadSeekerAndWriter(t *testing.T) {

config := pdf.NewDefaultConfiguration()
config.Cmd = pdf.OPTIMIZE

fileIn := filepath.Join(inDir, "CenterOfWhy.pdf")
fileOut := filepath.Join(outDir, "test.pdf")

f, err := os.Open(fileIn)
if err != nil {
t.Fatalf("TestReadSeekerAndWriter Open: %v\n", err)
t.Fatalf("TestOptimizeUsingReadSeekerAndWriter Open: %v\n", err)
}

defer func() {
@@ -142,27 +146,27 @@ func TestReadSeekerAndWriter(t *testing.T) {

fileInfo, err := f.Stat()
if err != nil {
t.Fatalf("TestReadSeekerAndWriter Stat: %v\n", err)
t.Fatalf("TestOptimizeUsingReadSeekerAndWriter Stat: %v\n", err)
}

ctx, err := ReadContext(f, fileIn, fileInfo.Size(), config)
if err != nil {
t.Fatalf("TestReadSeekerAndWriter Read: %v\n", err)
t.Fatalf("TestOptimizeUsingReadSeekerAndWriter Read: %v\n", err)
}

err = ValidateContext(ctx)
if err != nil {
t.Fatalf("TestReadSeekerAndWriter Validate: %v\n", err)
t.Fatalf("TestOptimizeUsingReadSeekerAndWriter Validate: %v\n", err)
}

err = OptimizeContext(ctx)
if err != nil {
t.Fatalf("TestReadSeekerAndWriter Optimize: %v\n", err)
t.Fatalf("TestOptimizeUsingReadSeekerAndWriter Optimize: %v\n", err)
}

w, err := os.Create(fileOut)
if err != nil {
t.Fatalf("TestReadSeekerAndWriter Create: %v\n", err)
t.Fatalf("TestOptimizeUsingReadSeekerAndWriter Create: %v\n", err)

}

@@ -183,21 +187,23 @@ func TestReadSeekerAndWriter(t *testing.T) {

err = WriteContext(ctx, w)
if err != nil {
t.Fatalf("TestReadSeekerAndWriter Write: %v\n", err)
t.Fatalf("TestOptimizeUsingReadSeekerAndWriter Write: %v\n", err)
}

}

func TestTrimUsingReadSeekerCloser(t *testing.T) {
func TestTrimUsingReadSeekerAndWriter(t *testing.T) {

config := pdf.NewDefaultConfiguration()
config.Cmd = pdf.TRIM

fileIn := filepath.Join(inDir, "pike-stanford.pdf")
fileOut := filepath.Join(outDir, "test.pdf")
pageSelection := []string{"-2"}

f, err := os.Open(fileIn)
if err != nil {
t.Fatalf("TestTrimUsingReadSeekerCloser Open: %v\n", err)
t.Fatalf("TestTrimUsingReadSeekerAndWriter Open: %v\n", err)
}

defer func() {
@@ -206,22 +212,22 @@ func TestTrimUsingReadSeekerCloser(t *testing.T) {

ctx, err := ReadContext(f, "", 0, config)
if err != nil {
t.Fatalf("TestTrimUsingReadSeekerCloser Read: %v\n", err)
t.Fatalf("TestTrimUsingReadSeekerAndWriter Read: %v\n", err)
}

err = ValidateContext(ctx)
if err != nil {
t.Fatalf("TestTrimUsingReadSeekerCloser Validate: %v\n", err)
t.Fatalf("TestTrimUsingReadSeekerAndWriter Validate: %v\n", err)
}

err = OptimizeContext(ctx)
if err != nil {
t.Fatalf("TestTrimUsingReadSeekerCloser Optimize: %v\n", err)
t.Fatalf("TestTrimUsingReadSeekerAndWriter Optimize: %v\n", err)
}

w, err := os.Create(fileOut)
if err != nil {
t.Fatalf("TestTrimUsingReadSeekerCloser Create: %v\n", err)
t.Fatalf("TestTrimUsingReadSeekerAndWriter Create: %v\n", err)

}

@@ -240,22 +246,20 @@ func TestTrimUsingReadSeekerCloser(t *testing.T) {

}()

ctx.Write.Command = "Trim"

pages, err := pagesForPageSelection(ctx.PageCount, pageSelection)
if err != nil {
t.Fatalf("TestTrimUsingReadSeekerCloser pageSelection: %v\n", err)
t.Fatalf("TestTrimUsingReadSeekerAndWriter pageSelection: %v\n", err)
}
ctx.Write.SelectedPages = pages

err = WriteContext(ctx, w)
if err != nil {
t.Fatalf("TestTrimUsingReadSeekerCloser Write: %v\n", err)
t.Fatalf("TestTrimUsingReadSeekerAndWriter Write: %v\n", err)
}

}

func TestMergeUsingReadSeekerCloser(t *testing.T) {
func TestMergeUsingReadSeekerAndWriter(t *testing.T) {

rr := []pdf.ReadSeekerCloser{}

@@ -265,7 +269,7 @@ func TestMergeUsingReadSeekerCloser(t *testing.T) {

f, err := os.Open(fileIn)
if err != nil {
t.Fatalf("TestMergeUsingReadSeekerCloser Open: %v\n", err)
t.Fatalf("TestMergeUsingReadSeekerAndWriter Open: %v\n", err)
}

rr = append(rr, f)
@@ -278,17 +282,18 @@ func TestMergeUsingReadSeekerCloser(t *testing.T) {
}()

config := pdf.NewDefaultConfiguration()
config.Cmd = pdf.MERGE

ctx, err := MergeContexts(rr, config)
if err != nil {
t.Fatalf("TestMergeUsingReadSeekerCloser Open: %v\n", err)
t.Fatalf("TestMergeUsingReadSeekerAndWriter Open: %v\n", err)
}

fileOut := filepath.Join(outDir, "test.pdf")

w, err := os.Create(fileOut)
if err != nil {
t.Fatalf("TestMergeUsingReadSeekerCloser create output file: %v\n", err)
t.Fatalf("TestMergeUsingReadSeekerAndWriter create output file: %v\n", err)
}

defer func() {
@@ -308,7 +313,7 @@ func TestMergeUsingReadSeekerCloser(t *testing.T) {

err = WriteContext(ctx, w)
if err != nil {
t.Fatalf("TestMergeUsingReadSeekerCloser Write output: %v\n", err)
t.Fatalf("TestMergeUsingReadSeekerAndWriter write output: %v\n", err)
}

}
@@ -548,7 +548,6 @@ type WriteContext struct {
DirName string
FileName string
FileSize int64
Command string // The processing command in effect.
SelectedPages IntSet // For split, trim and extract.
BinaryTotalSize int64 // total stream data, counts 100% all stream data written.
BinaryImageSize int64 // total image stream data written = Read.BinaryImageSize.
@@ -40,8 +40,10 @@ func (d Dict) Len() int {

// Insert adds a new entry to this PDFDict.
func (d Dict) Insert(key string, value Object) (ok bool) {
if _, found := d.Find(key); found {
return false
if o, found := d.Find(key); found {
if o.PDFString() != value.PDFString() {
return false
}
}
d[key] = value
return true
@@ -777,7 +777,14 @@ func scanLine(s *bufio.Scanner) (string, error) {
break
}
}
return s.Text(), nil
// Remove comment.
s1 := s.Text()
i := strings.Index(s1, "%")
if i >= 0 {
s1 = s1[:i]
}

return s1, nil
}

func scanTrailer(s *bufio.Scanner, line string) (string, error) {
@@ -88,10 +88,14 @@ func validateObjectReferenceDict(xRefTable *pdf.XRefTable, d pdf.Dict) error {

// Obj: required, indirect reference
ir := d.IndirectRefEntry("Obj")
if ir == nil {
if xRefTable.ValidationMode == pdf.ValidationStrict && ir == nil {
return errors.New("validateObjectReferenceDict: missing required entry \"Obj\"")
}

if ir == nil {
return nil
}

obj, err := xRefTable.Dereference(*ir)
if err != nil {
return err
@@ -182,7 +182,7 @@ func writeKids(ctx *Context, a Array, pageNr *int) (Array, int, error) {
if ctx.Cmd == REMOVEPAGES {
writePage = !writePage
}
if ctx.Write.SelectedPages[*pageNr] {
if writePage {
log.Write.Printf("writeKids: writing page:%d\n", *pageNr)
err = writePageDict(ctx, ir, d, *pageNr)
kids = append(kids, o)

0 comments on commit 80aa62c

Please sign in to comment.
You can’t perform that action at this time.