mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-08 00:22:14 +01:00
feat(pdfengines): new form field autoIndexBookmarks for the merge route
This commit is contained in:
@@ -409,9 +409,11 @@ func mergeRoute(engine gotenberg.PdfEngine) api.Route {
|
|||||||
|
|
||||||
var inputPaths []string
|
var inputPaths []string
|
||||||
var flatten bool
|
var flatten bool
|
||||||
|
var autoIndexBookmarks bool
|
||||||
err := form.
|
err := form.
|
||||||
MandatoryPaths([]string{".pdf"}, &inputPaths).
|
MandatoryPaths([]string{".pdf"}, &inputPaths).
|
||||||
Bool("flatten", &flatten, false).
|
Bool("flatten", &flatten, false).
|
||||||
|
Bool("autoIndexBookmarks", &autoIndexBookmarks, false).
|
||||||
Validate()
|
Validate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("validate form data: %w", err)
|
return fmt.Errorf("validate form data: %w", err)
|
||||||
@@ -436,19 +438,36 @@ func mergeRoute(engine gotenberg.PdfEngine) api.Route {
|
|||||||
var finalBookmarks []gotenberg.Bookmark
|
var finalBookmarks []gotenberg.Bookmark
|
||||||
if b, ok := bookmarks.([]gotenberg.Bookmark); ok {
|
if b, ok := bookmarks.([]gotenberg.Bookmark); ok {
|
||||||
finalBookmarks = b
|
finalBookmarks = b
|
||||||
} else if b, ok := bookmarks.(map[string][]gotenberg.Bookmark); ok {
|
} else {
|
||||||
offset := 0
|
bMap, _ := bookmarks.(map[string][]gotenberg.Bookmark)
|
||||||
for _, inputPath := range inputPaths {
|
if bMap != nil || autoIndexBookmarks {
|
||||||
filename := filepath.Base(inputPath)
|
offset := 0
|
||||||
if fileBookmarks, ok := b[filename]; ok {
|
for _, inputPath := range inputPaths {
|
||||||
finalBookmarks = append(finalBookmarks, shiftBookmarks(fileBookmarks, offset)...)
|
filename := filepath.Base(inputPath)
|
||||||
}
|
|
||||||
|
|
||||||
pageCount, err := engine.PageCount(ctx, ctx.Log(), inputPath)
|
var fileBookmarks []gotenberg.Bookmark
|
||||||
if err != nil {
|
if bMap != nil {
|
||||||
return fmt.Errorf("get page count of '%s': %w", filename, err)
|
fileBookmarks = bMap[filename]
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(fileBookmarks) == 0 && autoIndexBookmarks {
|
||||||
|
fb, err := engine.ReadBookmarks(ctx, ctx.Log(), inputPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("read bookmarks of '%s': %w", filename, err)
|
||||||
|
}
|
||||||
|
fileBookmarks = fb
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(fileBookmarks) > 0 {
|
||||||
|
finalBookmarks = append(finalBookmarks, shiftBookmarks(fileBookmarks, offset)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
pageCount, err := engine.PageCount(ctx, ctx.Log(), inputPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("get page count of '%s': %w", filename, err)
|
||||||
|
}
|
||||||
|
offset += pageCount
|
||||||
}
|
}
|
||||||
offset += pageCount
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -140,6 +140,16 @@ Feature: /forms/pdfengines/merge
|
|||||||
"""
|
"""
|
||||||
Invalid form data: form field 'bookmarks' is invalid (got 'foo', resulting to unmarshal bookmarks: invalid character 'o' in literal false (expecting 'a'))
|
Invalid form data: form field 'bookmarks' is invalid (got 'foo', resulting to unmarshal bookmarks: invalid character 'o' in literal false (expecting 'a'))
|
||||||
"""
|
"""
|
||||||
|
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||||
|
| files | testdata/page_1.pdf | file |
|
||||||
|
| files | testdata/page_2.pdf | file |
|
||||||
|
| autoIndexBookmarks | foo | field |
|
||||||
|
Then the response status code should be 400
|
||||||
|
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||||
|
Then the response body should match string:
|
||||||
|
"""
|
||||||
|
Invalid form data: form field 'autoIndexBookmarks' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax)
|
||||||
|
"""
|
||||||
|
|
||||||
@convert
|
@convert
|
||||||
Scenario: POST /forms/pdfengines/merge (PDF/A-1b & PDF/UA-1)
|
Scenario: POST /forms/pdfengines/merge (PDF/A-1b & PDF/UA-1)
|
||||||
@@ -281,6 +291,67 @@ Feature: /forms/pdfengines/merge
|
|||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@bookmarks
|
||||||
|
Scenario: POST /forms/pdfengines/merge (Auto-index Bookmarks)
|
||||||
|
Given I have a default Gotenberg container
|
||||||
|
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||||
|
| files | testdata/page_1_with_bookmarks.pdf | file |
|
||||||
|
| files | testdata/page_2_with_bookmarks.pdf | file |
|
||||||
|
| autoIndexBookmarks | true | field |
|
||||||
|
| Gotenberg-Output-Filename | foo | header |
|
||||||
|
Then the response status code should be 200
|
||||||
|
Then the response header "Content-Type" should be "application/pdf"
|
||||||
|
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/bookmarks/read" endpoint with the following form data and header(s):
|
||||||
|
| files | teststore/foo.pdf | file |
|
||||||
|
Then the response status code should be 200
|
||||||
|
Then the response header "Content-Type" should be "application/json"
|
||||||
|
Then the response body should match JSON:
|
||||||
|
"""
|
||||||
|
{
|
||||||
|
"foo.pdf": [
|
||||||
|
{
|
||||||
|
"title": "Page 1",
|
||||||
|
"page": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Page 2",
|
||||||
|
"page": 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
@bookmarks
|
||||||
|
Scenario: POST /forms/pdfengines/merge (Auto-index Bookmarks + Bookmarks Map)
|
||||||
|
Given I have a default Gotenberg container
|
||||||
|
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||||
|
| files | testdata/page_1.pdf | file |
|
||||||
|
| files | testdata/page_2_with_bookmarks.pdf | file |
|
||||||
|
| bookmarks | {"page_1.pdf":[{"title":"Page 1 Index","page":1}]} | field |
|
||||||
|
| autoIndexBookmarks | true | field |
|
||||||
|
| Gotenberg-Output-Filename | foo | header |
|
||||||
|
Then the response status code should be 200
|
||||||
|
Then the response header "Content-Type" should be "application/pdf"
|
||||||
|
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/bookmarks/read" endpoint with the following form data and header(s):
|
||||||
|
| files | teststore/foo.pdf | file |
|
||||||
|
Then the response status code should be 200
|
||||||
|
Then the response header "Content-Type" should be "application/json"
|
||||||
|
Then the response body should match JSON:
|
||||||
|
"""
|
||||||
|
{
|
||||||
|
"foo.pdf": [
|
||||||
|
{
|
||||||
|
"title": "Page 1 Index",
|
||||||
|
"page": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Page 2",
|
||||||
|
"page": 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
@flatten
|
@flatten
|
||||||
Scenario: POST /forms/pdfengines/merge (Flatten)
|
Scenario: POST /forms/pdfengines/merge (Flatten)
|
||||||
Given I have a default Gotenberg container
|
Given I have a default Gotenberg container
|
||||||
|
|||||||
BIN
test/integration/testdata/page_1_with_bookmarks.pdf
vendored
Normal file
BIN
test/integration/testdata/page_1_with_bookmarks.pdf
vendored
Normal file
Binary file not shown.
BIN
test/integration/testdata/page_2_with_bookmarks.pdf
vendored
Normal file
BIN
test/integration/testdata/page_2_with_bookmarks.pdf
vendored
Normal file
Binary file not shown.
Reference in New Issue
Block a user