github.com/pdfcpu/pdfcpu@v0.11.1/pkg/api/trim.go (about)

     1  /*
     2  	Copyright 2020 The pdfcpu Authors.
     3  
     4  	Licensed under the Apache License, Version 2.0 (the "License");
     5  	you may not use this file except in compliance with the License.
     6  	You may obtain a copy of the License at
     7  
     8  		http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  	Unless required by applicable law or agreed to in writing, software
    11  	distributed under the License is distributed on an "AS IS" BASIS,
    12  	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  	See the License for the specific language governing permissions and
    14  	limitations under the License.
    15  */
    16  
    17  package api
    18  
    19  import (
    20  	"io"
    21  	"os"
    22  	"sort"
    23  
    24  	"github.com/pdfcpu/pdfcpu/pkg/log"
    25  	"github.com/pdfcpu/pdfcpu/pkg/pdfcpu"
    26  	"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/model"
    27  	"github.com/pkg/errors"
    28  )
    29  
    30  // Trim generates a trimmed version of rs
    31  // containing all selected pages and writes the result to w.
    32  func Trim(rs io.ReadSeeker, w io.Writer, selectedPages []string, conf *model.Configuration) error {
    33  	if rs == nil {
    34  		return errors.New("pdfcpu: Trim: missing rs")
    35  	}
    36  
    37  	if conf == nil {
    38  		conf = model.NewDefaultConfiguration()
    39  	}
    40  	conf.Cmd = model.TRIM
    41  
    42  	ctx, err := ReadValidateAndOptimize(rs, conf)
    43  	if err != nil {
    44  		return err
    45  	}
    46  
    47  	pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, false, true)
    48  	if err != nil {
    49  		return err
    50  	}
    51  
    52  	if len(pages) == 0 {
    53  		if log.CLIEnabled() {
    54  			log.CLI.Println("aborted: missing page numbers!")
    55  		}
    56  		return nil
    57  	}
    58  
    59  	var pageNrs []int
    60  	for k, v := range pages {
    61  		if v {
    62  			pageNrs = append(pageNrs, k)
    63  		}
    64  	}
    65  	sort.Ints(pageNrs)
    66  
    67  	ctxDest, err := pdfcpu.ExtractPages(ctx, pageNrs, false)
    68  	if err != nil {
    69  		return err
    70  	}
    71  
    72  	if conf.PostProcessValidate {
    73  		if err = ValidateContext(ctxDest); err != nil {
    74  			return err
    75  		}
    76  	}
    77  
    78  	return WriteContext(ctxDest, w)
    79  }
    80  
    81  // TrimFile generates a trimmed version of inFile
    82  // containing all selected pages and writes the result to outFile.
    83  func TrimFile(inFile, outFile string, selectedPages []string, conf *model.Configuration) (err error) {
    84  	var f1, f2 *os.File
    85  
    86  	if f1, err = os.Open(inFile); err != nil {
    87  		return err
    88  	}
    89  
    90  	tmpFile := inFile + ".tmp"
    91  	if outFile != "" && inFile != outFile {
    92  		tmpFile = outFile
    93  		logWritingTo(outFile)
    94  	} else {
    95  		logWritingTo(inFile)
    96  	}
    97  	if f2, err = os.Create(tmpFile); err != nil {
    98  		f1.Close()
    99  		return err
   100  	}
   101  
   102  	defer func() {
   103  		if err != nil {
   104  			f2.Close()
   105  			f1.Close()
   106  			os.Remove(tmpFile)
   107  			return
   108  		}
   109  		if err = f2.Close(); err != nil {
   110  			return
   111  		}
   112  		if err = f1.Close(); err != nil {
   113  			return
   114  		}
   115  		if outFile == "" || inFile == outFile {
   116  			err = os.Rename(tmpFile, inFile)
   117  		}
   118  	}()
   119  
   120  	return Trim(f1, f2, selectedPages, conf)
   121  }