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

     1  /*
     2  	Copyright 2023 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  
    23  	"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/model"
    24  	"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/types"
    25  	"github.com/pkg/errors"
    26  )
    27  
    28  // PageLayout returns rs's page layout.
    29  func PageLayout(rs io.ReadSeeker, conf *model.Configuration) (*model.PageLayout, error) {
    30  	if rs == nil {
    31  		return nil, errors.New("pdfcpu: PageLayout: missing rs")
    32  	}
    33  
    34  	if conf == nil {
    35  		conf = model.NewDefaultConfiguration()
    36  	} else {
    37  		conf.ValidationMode = model.ValidationRelaxed
    38  	}
    39  	conf.Cmd = model.LISTPAGELAYOUT
    40  
    41  	ctx, err := ReadAndValidate(rs, conf)
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  
    46  	return ctx.PageLayout, nil
    47  }
    48  
    49  // PageLayoutFile returns inFile's page layout.
    50  func PageLayoutFile(inFile string, conf *model.Configuration) (*model.PageLayout, error) {
    51  	f, err := os.Open(inFile)
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  	defer f.Close()
    56  
    57  	return PageLayout(f, conf)
    58  }
    59  
    60  // ListPageLayout lists rs's page layout.
    61  func ListPageLayout(rs io.ReadSeeker, conf *model.Configuration) ([]string, error) {
    62  	if rs == nil {
    63  		return nil, errors.New("pdfcpu: ListPageLayout: missing rs")
    64  	}
    65  
    66  	if conf == nil {
    67  		conf = model.NewDefaultConfiguration()
    68  	} else {
    69  		conf.ValidationMode = model.ValidationRelaxed
    70  	}
    71  	conf.Cmd = model.LISTPAGELAYOUT
    72  
    73  	ctx, err := ReadAndValidate(rs, conf)
    74  	if err != nil {
    75  		return nil, err
    76  	}
    77  
    78  	if ctx.PageLayout != nil {
    79  		return []string{ctx.PageLayout.String()}, nil
    80  	}
    81  
    82  	return []string{"No page layout set, PDF viewers will default to \"SinglePage\""}, nil
    83  }
    84  
    85  // ListPageLayoutFile lists inFile's page layout.
    86  func ListPageLayoutFile(inFile string, conf *model.Configuration) ([]string, error) {
    87  	f, err := os.Open(inFile)
    88  	if err != nil {
    89  		return nil, err
    90  	}
    91  	defer f.Close()
    92  
    93  	return ListPageLayout(f, conf)
    94  }
    95  
    96  // SetPageLayout sets rs's page layout and writes the result to w.
    97  func SetPageLayout(rs io.ReadSeeker, w io.Writer, val model.PageLayout, conf *model.Configuration) error {
    98  	if rs == nil {
    99  		return errors.New("pdfcpu: SetPageLayout: missing rs")
   100  	}
   101  
   102  	if conf == nil {
   103  		conf = model.NewDefaultConfiguration()
   104  	} else {
   105  		conf.ValidationMode = model.ValidationRelaxed
   106  	}
   107  	conf.Cmd = model.SETPAGELAYOUT
   108  
   109  	ctx, err := ReadAndValidate(rs, conf)
   110  	if err != nil {
   111  		return err
   112  	}
   113  
   114  	ctx.RootDict["PageLayout"] = types.Name(val.String())
   115  
   116  	return Write(ctx, w, conf)
   117  }
   118  
   119  // SetPageLayoutFile sets inFile's page layout and writes the result to outFile.
   120  func SetPageLayoutFile(inFile, outFile string, val model.PageLayout, conf *model.Configuration) (err error) {
   121  	var f1, f2 *os.File
   122  
   123  	if f1, err = os.Open(inFile); err != nil {
   124  		return err
   125  	}
   126  
   127  	tmpFile := inFile + ".tmp"
   128  	if outFile != "" && inFile != outFile {
   129  		tmpFile = outFile
   130  	}
   131  	if f2, err = os.Create(tmpFile); err != nil {
   132  		f1.Close()
   133  		return err
   134  	}
   135  
   136  	defer func() {
   137  		if err != nil {
   138  			f2.Close()
   139  			f1.Close()
   140  			os.Remove(tmpFile)
   141  			return
   142  		}
   143  		if err = f2.Close(); err != nil {
   144  			return
   145  		}
   146  		if err = f1.Close(); err != nil {
   147  			return
   148  		}
   149  		if outFile == "" || inFile == outFile {
   150  			err = os.Rename(tmpFile, inFile)
   151  		}
   152  	}()
   153  
   154  	return SetPageLayout(f1, f2, val, conf)
   155  }
   156  
   157  // ResetPageLayout resets rs's page layout and writes the result to w.
   158  func ResetPageLayout(rs io.ReadSeeker, w io.Writer, conf *model.Configuration) error {
   159  	if rs == nil {
   160  		return errors.New("pdfcpu: ResetPageLayout: missing rs")
   161  	}
   162  
   163  	if conf == nil {
   164  		conf = model.NewDefaultConfiguration()
   165  	} else {
   166  		conf.ValidationMode = model.ValidationRelaxed
   167  	}
   168  	conf.Cmd = model.RESETPAGELAYOUT
   169  
   170  	ctx, err := ReadAndValidate(rs, conf)
   171  	if err != nil {
   172  		return err
   173  	}
   174  
   175  	delete(ctx.RootDict, "PageLayout")
   176  
   177  	return Write(ctx, w, conf)
   178  }
   179  
   180  // ResetPageLayoutFile resets inFile's page layout and writes the result to outFile.
   181  func ResetPageLayoutFile(inFile, outFile string, conf *model.Configuration) (err error) {
   182  	var f1, f2 *os.File
   183  
   184  	if f1, err = os.Open(inFile); err != nil {
   185  		return err
   186  	}
   187  
   188  	tmpFile := inFile + ".tmp"
   189  	if outFile != "" && inFile != outFile {
   190  		tmpFile = outFile
   191  	}
   192  	if f2, err = os.Create(tmpFile); err != nil {
   193  		f1.Close()
   194  		return err
   195  	}
   196  
   197  	defer func() {
   198  		if err != nil {
   199  			f2.Close()
   200  			f1.Close()
   201  			os.Remove(tmpFile)
   202  			return
   203  		}
   204  		if err = f2.Close(); err != nil {
   205  			return
   206  		}
   207  		if err = f1.Close(); err != nil {
   208  			return
   209  		}
   210  		if outFile == "" || inFile == outFile {
   211  			err = os.Rename(tmpFile, inFile)
   212  		}
   213  	}()
   214  
   215  	return ResetPageLayout(f1, f2, conf)
   216  }