From 5e5b1144ecd66463f5925fe01f5158c6b6067fed Mon Sep 17 00:00:00 2001 From: Emile Rolley Date: Thu, 31 Aug 2023 18:22:32 +0200 Subject: [PATCH] feat: add ImageRun --- README.md | 8 ++----- examples/Example.res | 35 +++++++++++++++++++++++++++++++ src/Floating.res | 19 +++++++++++++++++ src/HorizontalPositionOptions.res | 25 ++++++++++++++++++++++ src/ImageRun.res | 20 ++++++++++++++++++ src/MediaTransformation.res | 11 ++++++++++ src/TextWrapping.res | 27 ++++++++++++++++++++++++ src/Util.res | 31 ++++++++++++++++----------- src/VerticalPositionOptions.res | 25 ++++++++++++++++++++++ 9 files changed, 183 insertions(+), 18 deletions(-) create mode 100644 examples/Example.res create mode 100644 src/Floating.res create mode 100644 src/HorizontalPositionOptions.res create mode 100644 src/ImageRun.res create mode 100644 src/MediaTransformation.res create mode 100644 src/TextWrapping.res create mode 100644 src/VerticalPositionOptions.res diff --git a/README.md b/README.md index cc8873f..7aa8577 100644 --- a/README.md +++ b/README.md @@ -75,16 +75,12 @@ See which features are covered in the dedicated [doc file](https://github.com/Em * 🚧 Sections * ✅ Paragraph * 🚧 Text -* ❌ Images +* 🚧 Images (_Missing correct modelization of the `ImageRun.options.data` type_) * ✅ Headers & Footers * ❌ Bullet Points * ✅ Hyperlinks * ❌ Numbering -* 🚧 Tables - * ✅ Table - * ✅ TableCell - * ✅ TableRow - * ❌ TableColumn +* ✅ Tables * ❌ Tabs * ❌ Table Of Contents * ✅ Page Numbers diff --git a/examples/Example.res b/examples/Example.res new file mode 100644 index 0000000..92ba171 --- /dev/null +++ b/examples/Example.res @@ -0,0 +1,35 @@ +open Util + +let table = Table.make({ + rows: [ + TableRow.make({ + children: [ + TableCell.make({ + children: [ + Paragraph.make'({ + children: [ + ImageRun.make({ + data: NodeJs.Fs.readFileSync("./images/1.jpg"), + transformation: { + width: 100.0, + height: 100.0, + }, + }), + ], + })->Types.ParagraphOrTable.fromParagraph, + ], + verticalAlign: #center, + }), + TableCell.make({ + children: [ + Paragraph.make'({ + text: "Hello", + heading: #Heading1, + })->Types.ParagraphOrTable.fromParagraph, + ], + verticalAlign: #center, + }), + ], + }), + ], +}) diff --git a/src/Floating.res b/src/Floating.res new file mode 100644 index 0000000..84acae7 --- /dev/null +++ b/src/Floating.res @@ -0,0 +1,19 @@ +type margins = { + bottom?: float, + left?: float, + right?: float, + top?: float, +} + +/** @see https://docx.js.org/api/interfaces/IFloating.html */ +type t = { + allowOverlap?: bool, + behindDocument?: bool, + horizontalPosition?: HorizontalPositionOptions.t, + layoutInCell?: bool, + lockAnchor?: bool, + margins?: margins, + verticalPosition: VerticalPositionOptions.t, + wrap?: TextWrapping.t, + zIndex?: int, +} diff --git a/src/HorizontalPositionOptions.res b/src/HorizontalPositionOptions.res new file mode 100644 index 0000000..98d5123 --- /dev/null +++ b/src/HorizontalPositionOptions.res @@ -0,0 +1,25 @@ +type horizontalPositionAlign = [ + | #center + | #inside + | #left + | #outside + | #right +] + +type horizontalPositionRelativeFrom = [ + | #character + | #column + | #insideMargin + | #leftMargin + | #margin + | #outsideMargin + | #page + | #rightMargin +] + +/** @see https://docx.js.org/api/interfaces/IHorizontalPositionOptions.html */ +type t = { + align?: horizontalPositionAlign, + offset?: float, + relative?: horizontalPositionRelativeFrom, +} diff --git a/src/ImageRun.res b/src/ImageRun.res new file mode 100644 index 0000000..37171be --- /dev/null +++ b/src/ImageRun.res @@ -0,0 +1,20 @@ +type docPropertiesOptions = { + name: string, + dscription: string, + title: string, +} + +type options<'a> = { + /** + * FIXME: should be equivalent to: string | Buffer | Uint8Array | ArrayBuffer + * + * @see https://docx.js.org/api/interfaces/IImageOptions.html#data + */ + data: 'a, + transformation: MediaTransformation.t, + altText?: docPropertiesOptions, + floating?: Floating.t, +} + +@module("docx") @new +external make: options<'a> => ParagraphChild.t = "ImageRun" diff --git a/src/MediaTransformation.res b/src/MediaTransformation.res new file mode 100644 index 0000000..f23a8b0 --- /dev/null +++ b/src/MediaTransformation.res @@ -0,0 +1,11 @@ +/** @see https://docx.js.org/api/interfaces/IMediaTransformation.html */ +type rec t = { + height: float, + width: float, + flip?: flip, + rotation?: float, +} +and flip = { + horizontal?: bool, + vertical?: bool, +} diff --git a/src/TextWrapping.res b/src/TextWrapping.res new file mode 100644 index 0000000..a0bdfe6 --- /dev/null +++ b/src/TextWrapping.res @@ -0,0 +1,27 @@ +type distance = { + distB?: float, + distL?: float, + distR?: float, + distT?: float, +} + +type textWrappingSide = [ + | #bothSides + | #largest + | #left + | #right +] + +/** @see https://docx.js.org/api/enums/TextWrappingType.html */ +type textWrappingType = + | None + | Square + | Tight + | Top_And_Bottom + +/** @see https://docx.js.org/api/interfaces/ITextWrapping.html */ +type t = { + margins?: distance, + side?: textWrappingSide, + @as("type") type_: textWrappingType, +} diff --git a/src/Util.res b/src/Util.res index 1dbd349..c9e46e1 100644 --- a/src/Util.res +++ b/src/Util.res @@ -15,35 +15,42 @@ module Types = { let make = (~negative=false, ~val: float) => `${negative ? "-" : ""}${val->Belt.Float.toString}%` } - // TODO: should be more precise and model the fact that the value could be a 'positive' universal measure - module NumberOrUniversalMeasure = { + + module Number = { type t external fromFloat: float => t = "%identity" - external fromString: string => t = "%identity" } - module NumberOrPositiveUniversalMeasure = { + module Bool = { type t - external fromFloat: float => t = "%identity" - external fromString: string => t = "%identity" + external fromBool: bool => t = "%identity" + } + + // TODO: should be more precise and model the fact that the value could be a 'positive' universal measure + module NumberOrUniversalMeasure = { + include Number + + external fromUniversalMeasure: string => t = "%identity" + } + + module NumberOrPositiveUniversalMeasure = { + include Number + + external fromPositiveUniversalMeasure: string => t = "%identity" } module BoolOrNumberOrUniversalMeasure = { - type t + include NumberOrUniversalMeasure external fromBool: bool => t = "%identity" - external fromFloat: float => t = "%identity" - external fromString: string => t = "%identity" } module NumberOrPercentageOrUniversalMeasure = { - type t + include NumberOrUniversalMeasure external fromPercentage: Percentage.t => t = "%identity" - external fromFloat: float => t = "%identity" - external fromString: string => t = "%identity" } module BoolOrString = { diff --git a/src/VerticalPositionOptions.res b/src/VerticalPositionOptions.res new file mode 100644 index 0000000..75dbb83 --- /dev/null +++ b/src/VerticalPositionOptions.res @@ -0,0 +1,25 @@ +type horizontalPositionAlign = [ + | #center + | #inside + | #bottom + | #outside + | #top +] + +type horizontalPositionRelativeFrom = [ + | #character + | #column + | #insideMargin + | #bottomMargin + | #margin + | #outsideMargin + | #page + | #topMargin +] + +/** @see https://docx.js.org/api/interfaces/IHorizontalPositionOptions.html */ +type t = { + align?: horizontalPositionAlign, + offset?: float, + relative?: horizontalPositionRelativeFrom, +}