Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ plugins {
}

allprojects {
apply plugin: 'maven'
apply plugin: 'groovy'
apply plugin: 'idea'
apply plugin: 'eclipse'
apply plugin: 'codenarc'
apply plugin: 'nebula.provided-base'

group = 'com.craigburke.document'
version = '0.4.15'
version = '0.4.16-SNAPSHOT'
targetCompatibility = 1.6

repositories {
Expand Down
15 changes: 14 additions & 1 deletion core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,17 @@ project.ext {
name: 'Mozilla Public License, Version 2.0',
url : 'https://www.mozilla.org/MPL/2.0/'
]
}
}

task updateVersion {
ant.propertyfile(
file: 'src/main/resources/document-builder.properties') {
entry( key: 'document-builder.version', value: project.version)
}
ant.replaceregexp(file: 'src/main/resources/document-builder.properties', match: /(?s)^#.*document/, replace: 'document')

}

tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn updateVersion
}
12 changes: 12 additions & 0 deletions core/src/main/groovy/com/craigburke/document/core/Dimension.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.craigburke.document.core

import groovy.transform.Immutable

/**
* Two dimensional width/height.
*/
@Immutable
class Dimension {
BigDecimal width
BigDecimal height
}
60 changes: 58 additions & 2 deletions core/src/main/groovy/com/craigburke/document/core/Document.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,20 @@ import static com.craigburke.document.core.UnitUtil.inchToPoint
class Document extends BlockNode {
static Margin defaultMargin = new Margin(top: 72, bottom: 72, left: 72, right: 72)

private static final String PORTRAIT = 'portrait'
private static final String LANDSCAPE = 'landscape'

int pageCount
final int width = inchToPoint(8.5)
final int height = inchToPoint(11)
int width = inchToPoint(PaperSize.LETTER.width)
int height = inchToPoint(PaperSize.LETTER.height)
String orientation = PORTRAIT

def template
def header
def footer

Map metadata = [:]

private Map templateMap

Map getTemplateMap() {
Expand All @@ -41,4 +47,54 @@ class Document extends BlockNode {
List children = []
List<EmbeddedFont> embeddedFonts = []

/**
* Set width and height of the document.
*
* @param arg name of a standard paper size ("a4", "letter", "legal")
*/
void setSize(String arg) {
setSize(PaperSize.get(arg))
}

/**
* Set width and height of the document.
*
* @param arg a Dimension instance
*/
void setSize(Dimension arg) {
width = inchToPoint(arg.width)
height = inchToPoint(arg.height)
}

/**
* Set width and height of the document.
*
* @param args width, height
*/
void setSize(List<Number> args) {
width = args[0]
height = args[1]
}

/**
* Set document orientation.
*
* @param arg "portrait" or "landscape"
*/
void setOrientation(String arg) {
arg = arg.toLowerCase()
if (arg != PORTRAIT && arg != LANDSCAPE) {
throw new IllegalArgumentException("invalid orientation: $arg, only '$PORTRAIT' or '$LANDSCAPE' allowed")
}
if (this.@orientation != arg) {
this.@orientation = arg
def tmp = width
width = height
height = tmp
}
}

boolean isLandscape() {
this.orientation == LANDSCAPE
}
}
28 changes: 25 additions & 3 deletions core/src/main/groovy/com/craigburke/document/core/Image.groovy
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.craigburke.document.core

import java.security.MessageDigest

/**
* Image node
* @author Craig Burke
Expand All @@ -9,9 +11,29 @@ class Image extends BaseNode {
ImageType type = ImageType.JPG
Integer width
Integer height
String url
byte[] data

void setType(String value) {
type = Enum.valueOf(ImageType, value.toUpperCase())

void setType(String value) {
type = Enum.valueOf(ImageType, value.toUpperCase())
}

byte[] getData() {
if(this.@data == null && url != null) {
this.data = new URL(url).bytes
}
this.@data
}

def withInputStream(Closure work) {
work.call(new ByteArrayInputStream(getData()))
}

String getHash() {
Formatter hexHash = new Formatter()
MessageDigest.getInstance('SHA-1').digest(getData()).each {
b -> hexHash.format('%02x', b)
}
hexHash.toString()
}
}
39 changes: 39 additions & 0 deletions core/src/main/groovy/com/craigburke/document/core/PaperSize.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.craigburke.document.core

/**
* Standard paper size utility. Returned dimensions are inches.
*/
class PaperSize {

static final Dimension A1 = new Dimension(23.4, 33.1)
static final Dimension A2 = new Dimension(16.5, 23.4)
static final Dimension A3 = new Dimension(11.7, 16.5)
static final Dimension A4 = new Dimension(8.27, 11.7)
static final Dimension A5 = new Dimension(5.83, 8.27)
static final Dimension A6 = new Dimension(4.13, 5.83)
static final Dimension LETTER = new Dimension(8.5, 11)
static final Dimension LEGAL = new Dimension(8.5, 14)

static Dimension get(String name) {
switch (name.toLowerCase()) {
case 'a1':
return A1
case 'a2':
return A2
case 'a3':
return A3
case 'a4':
return A4
case 'a5':
return A5
case 'a6':
return A6
case 'letter':
return LETTER
case 'legal':
return LEGAL
default:
throw new IllegalArgumentException("invalid paper size: $name")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class UnitCategory {
BigDecimal getInch() { this * UnitUtil.POINTS_PER_INCH }
BigDecimal getCentimeters() { this * UnitUtil.POINTS_PER_CENTIMETER }
BigDecimal getCentimeter() { this * UnitUtil.POINTS_PER_CENTIMETER }
BigDecimal getCm() { this * UnitUtil.POINTS_PER_CENTIMETER }
BigDecimal getPt() { this }
BigDecimal getPx() { this }
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ package com.craigburke.document.core
*/
class UnitUtil {
static final BigDecimal POINTS_PER_INCH = 72
static final BigDecimal POINTS_PER_CENTIMETER = 28.346457
static final BigDecimal CENTIMETER_PER_INCH = 2.54
static final BigDecimal POINTS_PER_CENTIMETER = POINTS_PER_INCH / CENTIMETER_PER_INCH
static final BigDecimal PICA_POINTS = 6
static final BigDecimal TWIP_POINTS = 20
static final BigDecimal EIGTH_POINTS = 8
Expand All @@ -21,6 +22,14 @@ class UnitUtil {
point / POINTS_PER_INCH
}

static BigDecimal cmToPoint(BigDecimal cm) {
cm * POINTS_PER_CENTIMETER
}

static BigDecimal pointToCm(BigDecimal point) {
point / POINTS_PER_CENTIMETER
}

static BigDecimal pointToPica(BigDecimal point) {
point * PICA_POINTS
}
Expand Down Expand Up @@ -61,4 +70,11 @@ class UnitUtil {
emu / EMU_POINTS
}

static BigDecimal inchToCm(BigDecimal inch) {
inch * CENTIMETER_PER_INCH
}

static BigDecimal cmToInch(BigDecimal inch) {
inch / CENTIMETER_PER_INCH
}
}
30 changes: 30 additions & 0 deletions core/src/main/groovy/com/craigburke/document/core/Version.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.craigburke.document.core

/**
* Get version of document builder.
*
*/
class Version {

private static final String VERSION_PROPERTIES = 'document-builder.properties'

private Version() {}

static String getVersion() {
String version = 'unknown'
try {
Properties props = new Properties()
InputStream is = Version.class.getClassLoader().getResourceAsStream(VERSION_PROPERTIES)
try {
props.load(is)
} finally {
is.close()
}
version = props.getProperty('document-builder.version', version)
} catch (IOException e) {
e.printStackTrace()
}
version
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import com.craigburke.document.core.TextBlock

import javax.imageio.ImageIO
import java.awt.image.BufferedImage
import java.security.MessageDigest

/**
* Factory for image nodes
Expand All @@ -22,10 +21,18 @@ class ImageFactory extends AbstractFactory {
Image image = new Image(attributes)

if (!image.width || !image.height) {
InputStream inputStream = new ByteArrayInputStream(image.data)
BufferedImage bufferedImage = ImageIO.read(inputStream)
image.width = bufferedImage.width
image.height = bufferedImage.height
BufferedImage bufferedImage = image.withInputStream { ImageIO.read(it) }
if(bufferedImage == null) {
throw new IllegalStateException("could not read image $attributes")
}
if(image.width) {
image.height = image.width * (bufferedImage.height / bufferedImage.width)
} else if(image.height) {
image.width = image.height * (bufferedImage.width / bufferedImage.height)
} else {
image.width = bufferedImage.width
image.height = bufferedImage.height
}
}

if (!image.name || builder.imageFileNames.contains(image.name)) {
Expand All @@ -46,11 +53,7 @@ class ImageFactory extends AbstractFactory {
}

String generateImageName(Image image) {
Formatter hexHash = new Formatter()
MessageDigest.getInstance('SHA-1').digest(image.data).each {
b -> hexHash.format('%02x', b)
}
"${hexHash}.${image.type == ImageType.JPG ? 'jpg' : 'png'}"
"${image.hash}.${image.type == ImageType.JPG ? 'jpg' : 'png'}"
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,27 @@ abstract class BaseBuilderSpec extends Specification {
currentMargin << testMargins
}

def "document metadata"() {
when:
def result = builder.create {
document(metadata: [
title: 'Groovy Document Builder',
subject: 'Programatically build documents in a Groovy way',
keywords: 'groovy,document,creator,word,doc,docx,pdf',
description: 'The Groovy Document Builder is an awesome tool for the document oriented developer',
author: 'Craig Burke'
])
}


then:
result.document.metadata.title == 'Groovy Document Builder'
result.document.metadata.subject == 'Programatically build documents in a Groovy way'
result.document.metadata.keywords == 'groovy,document,creator,word,doc,docx,pdf'
result.document.metadata.description == 'The Groovy Document Builder is an awesome tool for the document oriented developer'
result.document.metadata.author == 'Craig Burke'
}

def "create a simple table"() {
when:
builder.create {
Expand Down
1 change: 1 addition & 0 deletions core/src/main/resources/document-builder.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
document-builder.version=0.4.16-SNAPSHOT
Loading