Skip to content

Commit

Permalink
Add viewerpref command
Browse files Browse the repository at this point in the history
  • Loading branch information
hhrutter committed Oct 20, 2023
1 parent 9cdf2fd commit 821def5
Show file tree
Hide file tree
Showing 25 changed files with 2,225 additions and 413 deletions.
17 changes: 17 additions & 0 deletions cmd/pdfcpu/init.go
Expand Up @@ -217,6 +217,18 @@ func initPageLayoutCmdMap() commandMap {
return m
}

func initViewerPreferencesCmdMap() commandMap {
m := newCommandMap()
for k, v := range map[string]command{
"list": {processListViewerPreferencesCommand, nil, "", ""},
"set": {processSetViewerPreferencesCommand, nil, "", ""},
"reset": {processResetViewerPreferencesCommand, nil, "", ""},
} {
m.register(k, v)
}
return m
}

func initCommandMap() {
annotsCmdMap := initAnnotsCmdMap()
attachCmdMap := initAttachCmdMap()
Expand All @@ -234,6 +246,7 @@ func initCommandMap() {
watermarkCmdMap := initWatermarkCmdMap()
pageModeCmdMap := initPageModeCmdMap()
pageLayoutCmdMap := initPageLayoutCmdMap()
viewerPrefsCmdMap := initViewerPreferencesCmdMap()

cmdMap = newCommandMap()

Expand Down Expand Up @@ -283,6 +296,7 @@ func initCommandMap() {
"validate": {processValidateCommand, nil, usageValidate, usageLongValidate},
"watermark": {nil, watermarkCmdMap, usageWatermark, usageLongWatermark},
"version": {printVersion, nil, usageVersion, usageLongVersion},
"viewerpref": {nil, viewerPrefsCmdMap, usageViewerPreferences, usageLongViewerPreferences},
} {
cmdMap.register(k, v)
}
Expand Down Expand Up @@ -346,6 +360,9 @@ func initFlags() {

flag.StringVar(&upw, "upw", "", "user password")
flag.StringVar(&opw, "opw", "", "owner password")

flag.BoolVar(&all, "all", false, "")
flag.BoolVar(&all, "a", false, "")
}

func initLogging(verbose, veryVerbose bool) {
Expand Down
2 changes: 1 addition & 1 deletion cmd/pdfcpu/main.go
Expand Up @@ -27,7 +27,7 @@ var (
upw, opw, key, perm, unit, conf string
verbose, veryVerbose bool
links, quiet, sorted, bookmarks bool
json, replaceBookmarks bool
all, json, replaceBookmarks bool
needStackTrace = true
cmdMap commandMap
)
Expand Down
49 changes: 49 additions & 0 deletions cmd/pdfcpu/process.go
Expand Up @@ -2410,3 +2410,52 @@ func processResetPageModeCommand(conf *model.Configuration) {
}
process(cli.ResetPageModeCommand(inFile, "", conf))
}

func processListViewerPreferencesCommand(conf *model.Configuration) {
if len(flag.Args()) != 1 || selectedPages != "" {
fmt.Fprintf(os.Stderr, "usage: %s\n", usageViewerPreferences)
os.Exit(1)
}

inFile := flag.Arg(0)
if conf.CheckFileNameExt {
ensurePDFExtension(inFile)
}
process(cli.ListViewerPreferencesCommand(inFile, all, json, conf))
}

func processSetViewerPreferencesCommand(conf *model.Configuration) {
if len(flag.Args()) != 2 || selectedPages != "" {
fmt.Fprintf(os.Stderr, "usage: %s\n", usageViewerPreferences)
os.Exit(1)
}

inFile := flag.Arg(0)
if conf.CheckFileNameExt {
ensurePDFExtension(inFile)
}

inFileJSON, stringJSON := "", ""

s := flag.Arg(1)
if hasJSONExtension(s) {
inFileJSON = s
} else {
stringJSON = s
}

process(cli.SetViewerPreferencesCommand(inFile, inFileJSON, "", stringJSON, conf))
}

func processResetViewerPreferencesCommand(conf *model.Configuration) {
if len(flag.Args()) != 1 || selectedPages != "" {
fmt.Fprintf(os.Stderr, "usage: %s\n", usageViewerPreferences)
os.Exit(1)
}

inFile := flag.Arg(0)
if conf.CheckFileNameExt {
ensurePDFExtension(inFile)
}
process(cli.ResetViewerPreferencesCommand(inFile, "", conf))
}
210 changes: 112 additions & 98 deletions cmd/pdfcpu/usage.go

Large diffs are not rendered by default.

42 changes: 39 additions & 3 deletions pkg/api/pageLayout.go
Expand Up @@ -26,8 +26,8 @@ import (
"github.com/pkg/errors"
)

// ListPageLayout lists rs's page layout.
func ListPageLayout(rs io.ReadSeeker, conf *model.Configuration) (*model.PageLayout, error) {
// PageLayout returns rs's page layout.
func PageLayout(rs io.ReadSeeker, conf *model.Configuration) (*model.PageLayout, error) {
if rs == nil {
return nil, errors.New("pdfcpu: PageLayout: missing rs")
}
Expand All @@ -47,8 +47,44 @@ func ListPageLayout(rs io.ReadSeeker, conf *model.Configuration) (*model.PageLay
return ctx.PageLayout, nil
}

// PageLayoutFile returns inFile's page layout.
func PageLayoutFile(inFile string, conf *model.Configuration) (*model.PageLayout, error) {
f, err := os.Open(inFile)
if err != nil {
return nil, err
}
defer f.Close()

return PageLayout(f, conf)
}

// ListPageLayout lists rs's page layout.
func ListPageLayout(rs io.ReadSeeker, conf *model.Configuration) ([]string, error) {
if rs == nil {
return nil, errors.New("pdfcpu: ListPageLayout: missing rs")
}

if conf == nil {
conf = model.NewDefaultConfiguration()
} else {
conf.ValidationMode = model.ValidationRelaxed
}
conf.Cmd = model.LISTPAGELAYOUT

ctx, _, _, err := readAndValidate(rs, conf, time.Now())
if err != nil {
return nil, err
}

if ctx.PageLayout != nil {
return []string{ctx.PageLayout.String()}, nil
}

return []string{"No page layout set, PDF viewers will default to \"SinglePage\""}, nil
}

// ListPageLayoutFile lists inFile's page layout.
func ListPageLayoutFile(inFile string, conf *model.Configuration) (*model.PageLayout, error) {
func ListPageLayoutFile(inFile string, conf *model.Configuration) ([]string, error) {
f, err := os.Open(inFile)
if err != nil {
return nil, err
Expand Down
42 changes: 39 additions & 3 deletions pkg/api/pageMode.go
Expand Up @@ -26,8 +26,8 @@ import (
"github.com/pkg/errors"
)

// ListPageMode lists rs's page mode.
func ListPageMode(rs io.ReadSeeker, conf *model.Configuration) (*model.PageMode, error) {
// PageMode returns rs's page mode.
func PageMode(rs io.ReadSeeker, conf *model.Configuration) (*model.PageMode, error) {
if rs == nil {
return nil, errors.New("pdfcpu: PageMode: missing rs")
}
Expand All @@ -47,8 +47,44 @@ func ListPageMode(rs io.ReadSeeker, conf *model.Configuration) (*model.PageMode,
return ctx.PageMode, nil
}

// PageModeFile returns inFile's page mode.
func PageModeFile(inFile string, conf *model.Configuration) (*model.PageMode, error) {
f, err := os.Open(inFile)
if err != nil {
return nil, err
}
defer f.Close()

return PageMode(f, conf)
}

// ListPageMode lists rs's page mode.
func ListPageMode(rs io.ReadSeeker, conf *model.Configuration) ([]string, error) {
if rs == nil {
return nil, errors.New("pdfcpu: ListPageMode: missing rs")
}

if conf == nil {
conf = model.NewDefaultConfiguration()
} else {
conf.ValidationMode = model.ValidationRelaxed
}
conf.Cmd = model.LISTPAGEMODE

ctx, _, _, err := readAndValidate(rs, conf, time.Now())
if err != nil {
return nil, err
}

if ctx.PageMode != nil {
return []string{ctx.PageMode.String()}, nil
}

return []string{"No page mode set, PDF viewers will default to \"UseNone\""}, nil
}

// ListPageModeFile lists inFile's page mode.
func ListPageModeFile(inFile string, conf *model.Configuration) (*model.PageMode, error) {
func ListPageModeFile(inFile string, conf *model.Configuration) ([]string, error) {
f, err := os.Open(inFile)
if err != nil {
return nil, err
Expand Down
8 changes: 4 additions & 4 deletions pkg/api/test/pageLayout_test.go
Expand Up @@ -33,7 +33,7 @@ func TestPageLayout(t *testing.T) {

pageLayout := model.PageLayoutTwoColumnLeft

pl, err := api.ListPageLayoutFile(inFile, nil)
pl, err := api.PageLayoutFile(inFile, nil)
if err != nil {
t.Fatalf("%s %s: list pageLayout: %v\n", msg, inFile, err)
}
Expand All @@ -45,22 +45,22 @@ func TestPageLayout(t *testing.T) {
t.Fatalf("%s %s: set pageLayout: %v\n", msg, inFile, err)
}

pl, err = api.ListPageLayoutFile(inFile, nil)
pl, err = api.PageLayoutFile(inFile, nil)
if err != nil {
t.Fatalf("%s %s: list pageLayout: %v\n", msg, inFile, err)
}
if pl == nil {
t.Fatalf("%s %s: list pageLayout, missing page layout\n", msg, inFile)
}
if *pl != pageLayout {
t.Fatalf("%s %s: list pageLayout, want:%s, got:%s\n", msg, inFile, pageLayout, *pl)
t.Fatalf("%s %s: list pageLayout, want:%s, got:%s\n", msg, inFile, pageLayout.String(), pl.String())
}

if err := api.ResetPageLayoutFile(inFile, "", nil); err != nil {
t.Fatalf("%s %s: reset pageLayout: %v\n", msg, inFile, err)
}

pl, err = api.ListPageLayoutFile(inFile, nil)
pl, err = api.PageLayoutFile(inFile, nil)
if err != nil {
t.Fatalf("%s %s: list page layout: %v\n", msg, inFile, err)
}
Expand Down
12 changes: 6 additions & 6 deletions pkg/api/test/pageMode_test.go
Expand Up @@ -33,7 +33,7 @@ func TestPageMode(t *testing.T) {

pageMode := model.PageModeUseOutlines

pl, err := api.ListPageModeFile(inFile, nil)
pl, err := api.PageModeFile(inFile, nil)
if err != nil {
t.Fatalf("%s %s: list pageMode: %v\n", msg, inFile, err)
}
Expand All @@ -45,22 +45,22 @@ func TestPageMode(t *testing.T) {
t.Fatalf("%s %s: set pageMode: %v\n", msg, inFile, err)
}

pl, err = api.ListPageModeFile(inFile, nil)
pm, err := api.PageModeFile(inFile, nil)
if err != nil {
t.Fatalf("%s %s: list pageMode: %v\n", msg, inFile, err)
}
if pl == nil {
if pm == nil {
t.Fatalf("%s %s: list pageMode, missing page mode\n", msg, inFile)
}
if *pl != pageMode {
t.Fatalf("%s %s: list pageMode, want:%s, got:%s\n", msg, inFile, pageMode, *pl)
if *pm != pageMode {
t.Fatalf("%s %s: list pageMode, want:%s, got:%s\n", msg, inFile, pageMode.String(), pm.String())
}

if err := api.ResetPageModeFile(inFile, "", nil); err != nil {
t.Fatalf("%s %s: reset pageMode: %v\n", msg, inFile, err)
}

pl, err = api.ListPageModeFile(inFile, nil)
pl, err = api.PageModeFile(inFile, nil)
if err != nil {
t.Fatalf("%s %s: list pageMode: %v\n", msg, inFile, err)
}
Expand Down
80 changes: 80 additions & 0 deletions pkg/api/test/viewerPreferences_test.go
@@ -0,0 +1,80 @@
/*
Copyright 2023 The pdf Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package test

import (
"path/filepath"
"testing"

"github.com/pdfcpu/pdfcpu/pkg/api"
"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/model"
)

func TestViewerPreferences(t *testing.T) {
msg := "testViewerPreferences"

fileName := "Hybrid-PDF.pdf"
inFile := filepath.Join(outDir, fileName)
copyFile(t, filepath.Join(inDir, fileName), inFile)
inFileJSON := filepath.Join(inDir, "json", "viewerPreferences.json")
stringJSON := "{\"HideMenuBar\": true, \"CenterWindow\": true}"

vp, err := api.ViewerPreferencesFile(inFile, false, nil)
if err != nil {
t.Fatalf("%s %s: viewerPref struct: %v\n", msg, inFile, err)
}
if vp == nil {
t.Fatalf("%s %s: missing viewerPref struct\n", msg, inFile)
}

if err := api.ResetViewerPreferencesFile(inFile, "", nil); err != nil {
t.Fatalf("%s %s: reset: %v\n", msg, inFile, err)
}

vp, err = api.ViewerPreferencesFile(inFile, false, nil)
if err != nil {
t.Fatalf("%s %s: viewerPref struct: %v\n", msg, inFile, err)
}
if vp != nil {
t.Fatalf("%s %s: unexpected viewerPref struct: %v\n", msg, inFile, vp)
}

if err := api.SetViewerPreferencesFileFromJSONFile(inFile, "", inFileJSON, nil); err != nil {
t.Fatalf("%s %s: set via JSON file: %v\n", msg, inFile, err)
}

vp, err = api.ViewerPreferencesFile(inFile, false, nil)
if err != nil {
t.Fatalf("%s %s: viewerPref struct: %v\n", msg, inFile, err)
}
if vp == nil {
t.Fatalf("%s %s: missing viewerPref struct\n", msg, inFile)
}

vp = &model.ViewerPreferences{}
vp.SetCenterWindow(true)
vp.SetHideMenuBar(true)
vp.SetNumCopies(5)

if err := api.SetViewerPreferencesFile(inFile, "", *vp, nil); err != nil {
t.Fatalf("%s %s: set: %v\n", msg, inFile, err)
}

if err := api.SetViewerPreferencesFileFromJSONBytes(inFile, "", []byte(stringJSON), nil); err != nil {
t.Fatalf("%s %s: set via JSON string: %v\n", msg, inFile, err)
}
}

0 comments on commit 821def5

Please sign in to comment.