Skip to content

Commit

Permalink
Add orientation:{portrait/landscape} parameter to .pageformat
Browse files Browse the repository at this point in the history
  • Loading branch information
iamgio committed Jul 15, 2024
1 parent e527282 commit 7fe39fd
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 35 deletions.
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
package eu.iamgio.quarkdown.document

import eu.iamgio.quarkdown.document.page.PageOrientation

/**
* Type of produced document, which affects its post-rendering stage.
* @param preferredOrientation the preferred orientation of the document, to apply if not overridden by the user
*/
enum class DocumentType {
enum class DocumentType(val preferredOrientation: PageOrientation) {
/**
* A document whose rendered content is not altered by the post-rendering stage.
* Plain Markdown is often used as plain (e.g. READMEs).
*/
PLAIN,
PLAIN(PageOrientation.PORTRAIT),

/**
* A document that is split into pages of mostly text content: books, articles, papers, etc.
*/
PAGED,
PAGED(PageOrientation.PORTRAIT),

/**
* A slides-based document for presentations.
*/
SLIDES,
SLIDES(PageOrientation.LANDSCAPE),
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package eu.iamgio.quarkdown.document.page

/**
* A generic bounding box with a width and a height.
*/
data class BoundingBox(
val width: Size,
val height: Size,
) {
/**
* A 90-degrees rotated version of this bounding box,
* which happens to be a new [BoundingBox] with the height and width swapped.
*/
val rotated: BoundingBox
get() = BoundingBox(height, width)
}

/**
* Shorthand for creating a [BoundingBox] from two [Size]s.
* @param height height of the bounding box
* @return a new [BoundingBox] with [this] width and the given [height]
*/
infix fun Size.by(height: Size) = BoundingBox(this, height)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package eu.iamgio.quarkdown.document.page

/**
* The orientation of a page.
*/
enum class PageOrientation {
/**
* Vertical orientation, where `height >= width`
*/
PORTRAIT,

/**
* Horizontal orientation, where `width > height`
*/
LANDSCAPE,
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,42 @@ package eu.iamgio.quarkdown.document.page

/**
* Standard page sizes.
* @param width width of the page
* @param height height of the page
* @param bounds size the page
*/
enum class PageSizeFormat(val width: Size, val height: Size) {
A0(841.0.mm, 1189.0.mm),
A1(594.0.mm, 841.0.mm),
A2(420.0.mm, 594.0.mm),
A3(297.0.mm, 420.0.mm),
A4(210.0.mm, 297.0.mm),
A5(148.0.mm, 210.0.mm),
A6(105.0.mm, 148.0.mm),
A7(74.0.mm, 105.0.mm),
A8(52.0.mm, 74.0.mm),
A9(37.0.mm, 52.0.mm),
A10(26.0.mm, 37.0.mm),
B0(1000.0.mm, 1414.0.mm),
B1(707.0.mm, 1000.0.mm),
B2(500.0.mm, 707.0.mm),
B3(353.0.mm, 500.0.mm),
B4(250.0.mm, 353.0.mm),
B5(176.0.mm, 250.0.mm),
LETTER(8.5.inch, 11.0.inch),
LEGAL(8.5.inch, 14.0.inch),
LEDGER(11.0.inch, 17.0.inch),
enum class PageSizeFormat(private val bounds: BoundingBox) {
A0(841.0.mm by 1189.0.mm),
A1(594.0.mm by 841.0.mm),
A2(420.0.mm by 594.0.mm),
A3(297.0.mm by 420.0.mm),
A4(210.0.mm by 297.0.mm),
A5(148.0.mm by 210.0.mm),
A6(105.0.mm by 148.0.mm),
A7(74.0.mm by 105.0.mm),
A8(52.0.mm by 74.0.mm),
A9(37.0.mm by 52.0.mm),
A10(26.0.mm by 37.0.mm),
B0(1000.0.mm by 1414.0.mm),
B1(707.0.mm by 1000.0.mm),
B2(500.0.mm by 707.0.mm),
B3(353.0.mm by 500.0.mm),
B4(250.0.mm by 353.0.mm),
B5(176.0.mm by 250.0.mm),
LETTER(8.5.inch by 11.0.inch),
LEGAL(8.5.inch by 14.0.inch),
LEDGER(11.0.inch by 17.0.inch),
;

/**
* Base orientation of the format.
*/
private val orientation: PageOrientation
// Assuming width and height are declared with the same size unit.
get() = if (bounds.width.value > bounds.height.value) PageOrientation.LANDSCAPE else PageOrientation.PORTRAIT

/**
* @param orientation orientation of the page
* @return the bounds of the format for the given orientation
* If, for instance, the document is landscape and the given format is portrait, the format is converted to landscape.
*/
fun getBounds(orientation: PageOrientation): BoundingBox = if (this.orientation == orientation) bounds else bounds.rotated
}
23 changes: 15 additions & 8 deletions stdlib/src/main/kotlin/eu/iamgio/quarkdown/stdlib/Document.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import eu.iamgio.quarkdown.document.DocumentInfo
import eu.iamgio.quarkdown.document.DocumentTheme
import eu.iamgio.quarkdown.document.DocumentType
import eu.iamgio.quarkdown.document.page.PageMarginPosition
import eu.iamgio.quarkdown.document.page.PageOrientation
import eu.iamgio.quarkdown.document.page.PageSizeFormat
import eu.iamgio.quarkdown.document.page.Size
import eu.iamgio.quarkdown.document.page.Sizes
Expand Down Expand Up @@ -143,27 +144,33 @@ fun theme(
/**
* Sets the format of the document.
* If a value is `null`, the default value supplied by the underlying renderer is used.
* @param format standard size format of each page (overrides [width] and [height])
* If neither [format] nor [width] or [height] are `null`, the latter override the former.
* If both [format] and [width] or [height] are `null`, the default value is used.
* @param format standard size format of each page (overridden by [width] and [height])
* @param orientation orientation of each page.
* If not specified, the preferred orientation of the document type is used.
* Does not take effect if [format] is not specified.
* @param width width of each page
* @param height height of each page
* @param margin blank space around the content of each page. Only supported in paged mode.
* @throws IllegalArgumentException if both [format] and either [width] or [height] are not `null`
*/
@Name("pageformat")
fun pageFormat(
@Injected context: Context,
@Name("size") format: PageSizeFormat? = null,
orientation: PageOrientation = context.documentInfo.type.preferredOrientation,
width: Size? = null,
height: Size? = null,
margin: Sizes? = null,
): VoidValue {
if (format != null && (width != null || height != null)) {
throw IllegalArgumentException("Specifying a page size format overrides manual width and height")
}

with(context.documentInfo.pageFormat) {
this.pageWidth = format?.width ?: width
this.pageHeight = format?.height ?: height
// If, for instance, the document is landscape and the given format is portrait,
// the format is converted to landscape.
val formatBounds = format?.getBounds(orientation)

// Width and/or height override the format size if both are not null.
this.pageWidth = width ?: formatBounds?.width ?: this.pageWidth
this.pageHeight = height ?: formatBounds?.height ?: this.pageHeight
this.margin = margin
}

Expand Down

0 comments on commit 7fe39fd

Please sign in to comment.