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

Table of contents (only for WordDocumentBuilder at this time) #38

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
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
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
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
}
58 changes: 56 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,9 +9,13 @@ 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
Expand Down Expand Up @@ -41,4 +45,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")
}
}
}
10 changes: 10 additions & 0 deletions core/src/main/groovy/com/craigburke/document/core/Toc.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.craigburke.document.core

/**
* Table of Contents.
*/
class Toc extends BaseNode {
Toc() {}

Toc(Map attributes) {}
}
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
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import com.craigburke.document.core.factory.CellFactory

import com.craigburke.document.core.Document
import com.craigburke.document.core.Font
import com.craigburke.document.core.factory.TocFactory

/**
* Document Builder base class
Expand Down Expand Up @@ -184,6 +185,7 @@ abstract class DocumentBuilder extends FactoryBuilderSupport {
registerFactory('heading4', new HeadingFactory())
registerFactory('heading5', new HeadingFactory())
registerFactory('heading6', new HeadingFactory())
registerFactory('toc', new TocFactory())
}
}

Expand Down
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
@@ -0,0 +1,18 @@
package com.craigburke.document.core.factory

import com.craigburke.document.core.Toc

/**
* Table of Contents factory.
*/
class TocFactory extends AbstractFactory {

boolean isLeaf() { true }

def newInstance(FactoryBuilderSupport builder, name, value, Map attributes) {
Toc toc = new Toc(attributes)
toc.parent = builder.parentName == 'create' ? builder.document : builder.current
builder.setNodeProperties(toc, attributes, 'toc')
toc
}
}
Loading