Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lua image size #9343

Merged
merged 2 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions doc/lua-filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -4607,6 +4607,67 @@ Returns:

<!-- END: AUTOGENERATED CONTENT -->

<!-- BEGIN: AUTOGENERATED CONTENT for module pandoc.image -->

# Module pandoc.image

Basic image querying functions.

## Functions {#pandoc.image-functions}

### size {#pandoc.image.size}

`size (image[, opts])`

Returns a table containing the size and resolution of an image;
throws an error if the given string is not an image, or if the
size of the image cannot be determined.

The resulting table has four entires: *width*, *height*,
*dpi_horz*, and *dpi_vert*.

The `opts` parameter, when given, should be either a WriterOptions
object such as `PANDOC_WRITER_OPTIONS`, or a table with a `dpi`
entry. It affects the calculation for vector image formats such as
SVG.

Parameters:

`image`
: image data (string)

`opts`
: writer options ([WriterOptions]\|table)

Returns:

- image size information or error message (table)

*Since: 3.1.13*

### format {#pandoc.image.format}

`format (image)`

Returns the format of an image as a lowercase string.

Formats recognized by pandoc include *png*, *gif*, *tiff*, *jpeg*,
*pdf*, *svg*, *eps*, and *emf*.

Parameters:

`image`
: binary image data (string)

Returns:

- image format, or nil if the format cannot be determined
(string\|nil)

*Since: 3.1.13*

<!-- END: AUTOGENERATED CONTENT -->

<!-- BEGIN: AUTOGENERATED CONTENT for module pandoc.json -->

# Module pandoc.json
Expand Down
2 changes: 2 additions & 0 deletions pandoc-lua-engine/pandoc-lua-engine.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ library
, Text.Pandoc.Lua.Marshal.CommonState
, Text.Pandoc.Lua.Marshal.Context
, Text.Pandoc.Lua.Marshal.Format
, Text.Pandoc.Lua.Marshal.ImageSize
, Text.Pandoc.Lua.Marshal.PandocError
, Text.Pandoc.Lua.Marshal.ReaderOptions
, Text.Pandoc.Lua.Marshal.Reference
Expand All @@ -82,6 +83,7 @@ library
, Text.Pandoc.Lua.Marshal.WriterOptions
, Text.Pandoc.Lua.Module.CLI
, Text.Pandoc.Lua.Module.Format
, Text.Pandoc.Lua.Module.Image
, Text.Pandoc.Lua.Module.JSON
, Text.Pandoc.Lua.Module.MediaBag
, Text.Pandoc.Lua.Module.Pandoc
Expand Down
2 changes: 2 additions & 0 deletions pandoc-lua-engine/src/Text/Pandoc/Lua/Init.hs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import qualified HsLua.Module.Path as Module.Path
import qualified HsLua.Module.Zip as Module.Zip
import qualified Text.Pandoc.Lua.Module.CLI as Pandoc.CLI
import qualified Text.Pandoc.Lua.Module.Format as Pandoc.Format
import qualified Text.Pandoc.Lua.Module.Image as Pandoc.Image
import qualified Text.Pandoc.Lua.Module.JSON as Pandoc.JSON
import qualified Text.Pandoc.Lua.Module.MediaBag as Pandoc.MediaBag
import qualified Text.Pandoc.Lua.Module.Pandoc as Module.Pandoc
Expand Down Expand Up @@ -91,6 +92,7 @@ loadedModules :: [Module PandocError]
loadedModules =
[ Pandoc.CLI.documentedModule
, Pandoc.Format.documentedModule
, Pandoc.Image.documentedModule
, Pandoc.JSON.documentedModule
, Pandoc.MediaBag.documentedModule
, Pandoc.Scaffolding.documentedModule
Expand Down
31 changes: 31 additions & 0 deletions pandoc-lua-engine/src/Text/Pandoc/Lua/Marshal/ImageSize.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{- |
Module : Text.Pandoc.Lua.Marshal.ImageSize
Copyright : © 2024 Albert Krewinkel
License : GPL-2.0-or-later
Maintainer : Albert Krewinkel <[email protected]>

Marshaling image properties.
-}
module Text.Pandoc.Lua.Marshal.ImageSize
( pushImageType
, pushImageSize
) where

import Data.Char (toLower)
import HsLua
import Text.Pandoc.ImageSize

-- | Pushes an 'ImageType' as a string value.
pushImageType :: LuaError e => Pusher e ImageType
pushImageType = pushString . map toLower . show

-- | Pushes a dimensional value.
pushImageSize :: LuaError e => Pusher e ImageSize
pushImageSize = pushAsTable
[ ("width", pushIntegral . pxX)
, ("height", pushIntegral . pxY)
, ("dpi_horz", pushIntegral . dpiX)
, ("dpi_vert", pushIntegral . dpiY)
]
98 changes: 98 additions & 0 deletions pandoc-lua-engine/src/Text/Pandoc/Lua/Module/Image.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
{-# LANGUAGE OverloadedStrings #-}
{-|
Module : Text.Pandoc.Lua.Module.Image
Copyright : © 2024 Albert Krewinkel
License : MIT
Maintainer : Albert Krewinkel <[email protected]>

Lua module for basic image operations.
-}
module Text.Pandoc.Lua.Module.Image (
-- * Module
documentedModule

-- ** Functions
, size
, format
)
where

import Prelude hiding (null)
import Data.Default (Default (def))
import Data.Maybe (fromMaybe)
import Data.Version (makeVersion)
import HsLua.Core
import HsLua.Marshalling
import HsLua.Packaging
import Text.Pandoc.Error (PandocError)
import Text.Pandoc.ImageSize (imageType, imageSize)
import Text.Pandoc.Lua.PandocLua ()
import Text.Pandoc.Lua.Marshal.ImageSize (pushImageType, pushImageSize)
import Text.Pandoc.Lua.Marshal.WriterOptions (peekWriterOptions)

import qualified Data.Text as T

-- | The @pandoc.image@ module specification.
documentedModule :: Module PandocError
documentedModule = Module
{ moduleName = "pandoc.image"
, moduleDescription = "Basic image querying functions."
, moduleFields = fields
, moduleFunctions = functions
, moduleOperations = []
, moduleTypeInitializers = []
}

--
-- Fields
--

-- | Exported fields.
fields :: LuaError e => [Field e]
fields = []

--
-- Functions
--

functions :: [DocumentedFunction PandocError]
functions =
[ size `since` makeVersion [3, 1, 13]
, format `since` makeVersion [3, 1, 13]
]

-- | Find the size of an image.
size :: DocumentedFunction PandocError
size = defun "size"
### liftPure2 (\img mwriterOpts -> imageSize (fromMaybe def mwriterOpts) img)
<#> parameter peekByteString "string" "image" "image data"
<#> opt (parameter peekWriterOptions "WriterOptions|table" "opts"
"writer options")
=#> functionResult (either (failLua . T.unpack) pushImageSize) "table"
"image size information or error message"
#? T.unlines
[ "Returns a table containing the size and resolution of an image;"
, "throws an error if the given string is not an image, or if the size"
, "of the image cannot be determined."
, ""
, "The resulting table has four entires: *width*, *height*, *dpi\\_horz*,"
, "and *dpi\\_vert*."
, ""
, "The `opts` parameter, when given, should be either a WriterOptions"
, "object such as `PANDOC_WRITER_OPTIONS`, or a table with a `dpi` entry."
, "It affects the calculation for vector image formats such as SVG."
]

-- | Returns the format of an image.
format :: LuaError e => DocumentedFunction e
format = defun "format"
### liftPure imageType
<#> parameter peekByteString "string" "image" "binary image data"
=#> functionResult (maybe pushnil pushImageType) "string|nil"
"image format, or nil if the format cannot be determined"
#? T.unlines
[ "Returns the format of an image as a lowercase string."
, ""
, "Formats recognized by pandoc include *png*, *gif*, *tiff*, *jpeg*,"
, "*pdf*, *svg*, *eps*, and *emf*."
]
2 changes: 2 additions & 0 deletions pandoc-lua-engine/test/Tests/Lua/Module.hs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ tests =
("lua" </> "module" </> "pandoc-list.lua")
, testPandocLua "pandoc.format"
("lua" </> "module" </> "pandoc-format.lua")
, testPandocLua "pandoc.image"
("lua" </> "module" </> "pandoc-image.lua")
, testPandocLua "pandoc.json"
("lua" </> "module" </> "pandoc-json.lua")
, testPandocLua "pandoc.mediabag"
Expand Down
68 changes: 68 additions & 0 deletions pandoc-lua-engine/test/lua/module/pandoc-image.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
--
-- Tests for the system module
--
local image = require 'pandoc.image'
local tasty = require 'tasty'

local group = tasty.test_group
local test = tasty.test_case
local assert = tasty.assert

local svg_image = [==[<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
height="70" width="70"
viewBox="-35 -35 70 70">
<title>test</title>
<!-- document shape -->
<polygon points="-10,-31.53 -10,-3.25 0,0 10,-3.25 10,-23.53 2,-31.53" />
</svg>
]==]

return {
-- Check existence of static fields
group 'static fields' {
},

group 'size' {
test('returns a table', function ()
local imgsize = {
width = 70,
height = 70,
dpi_horz = 96,
dpi_vert = 96,
}
assert.are_same(image.size(svg_image), imgsize)
end),
test('fails on faulty eps', function ()
assert.error_matches(
function () image.size('%!PS EPSF') end,
'could not determine EPS size'
)
end),
test('fails if input is not an image', function ()
assert.error_matches(
function () image.size('not an image') end,
'could not determine image type'
)
end),
test('respects the dpi setting', function ()
local imgsize = {
width = 70,
height = 70,
dpi_horz = 300,
dpi_vert = 300,
}
assert.are_same(image.size(svg_image, {dpi=300}), imgsize)
end),
},

group 'format' {
test('SVG', function ()
assert.are_equal(image.format(svg_image), 'svg')
end),
test('returns nil if input is not an image', function ()
assert.is_nil(image.format('not an image'))
end),
},
}
1 change: 1 addition & 0 deletions src/Text/Pandoc/ImageSize.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Portability : portable
Functions for determining the size of a PNG, JPEG, or GIF image.
-}
module Text.Pandoc.ImageSize ( ImageType(..)
, ImageSize(..)
, imageType
, imageSize
, sizeInPixels
Expand Down