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 }