khipu

package
v0.0.0-...-ae32867 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 12, 2020 License: BSD-3-Clause Imports: 15 Imported by: 0

README

Package khipu is about encoding text into typesetting items.

Metaphor

"Khipu were recording devices fashioned from strings historically used by a number of cultures in the region of Andean South America. Khipu is the word for "knot" in Cusco Quechua. A khipu usually consisted of cotton or camelid fiber strings. The Inca people used them for collecting data and keeping records, monitoring tax obligations, properly collecting census records, calendrical information, and for military organization. The cords stored numeric and other values encoded as knots, often in a base ten positional system. A khipu could have only a few or thousands of cords." ––Excerpt from a Wikipedia article about khipus

The Khipukamayuqs (Quechua for “knot-makers”) were the scribes of those times, tasked with encoding tax figures and other administrative information in knots. We will use this analogy to call typesetting items "khipus" or "knots", and objects which produce khipus will be "Khipukamayuqs". Knots implement items for typesetting paragraphs. We will use a box-and-glue model and the various knot types more or less implement the corresponding node types from the TeX typesetting system.

A Khipukamayuqs is part of a typsetting pipeline and will transform text into khipus. Khipus are the input for linebreakers. The overall process of creating them and the interaction with line breaking looks like this:

Create Khipus from Text

  1. Normalize Unicode text

    https://godoc.org/golang.org/x/text/unicode/norm

  2. Find natural text wrap opportunities (words in many scripts, syllables/character in East Asia, etc.)

    https://godoc.org/github.com/npillmayer/gotype/gtcore/uax

  3. Bi-directional text

    https://godoc.org/golang.org/x/text/unicode/bidi https://www.w3.org/International/articles/inline-bidi-markup/

  4. Hyphenation: Lliang patterns + language-specific code

    https://godoc.org/github.com/npillmayer/gotype/gtcore/hyphenation

  5. Translate feasible breakpoints to penalties, glue and discretionaries

    https://wiki.apache.org/xmlgraphics-fop/KnuthsModel

  6. Shape text -> Glyphs + alternative glyphs (end-of-line condensed in Arabic, etc.)

    http://behdad.org/text/

At this point, text has been fully converted to khipus.

Documentation

Overview

Package khipu is about encoding text into typesetting items.

"Khipu were recording devices fashioned from strings historically used by a number of cultures in the region of Andean South America. Khipu is the word for "knot" in Cusco Quechua. A khipu usually consisted of cotton or camelid fiber strings. The Inca people used them for collecting data and keeping records, monitoring tax obligations, properly collecting census records, calendrical information, and for military organization. The cords stored numeric and other values encoded as knots, often in a base ten positional system. A khipu could have only a few or thousands of cords." ––Excerpt from a Wikipedia article about khipus

The Khipukamayuqs (Quechua for “knot-makers”) were the scribes of those times, tasked with encoding tax figures and other administrative information in knots. We will use this analogy to call typesetting items "khipus" or "knots", and objects which produce khipus will be "Khipukamayuqs". Knots implement items for typesetting paragraphs. We will use a box-and-glue model, the various knot types more or less implementing the corresponding node types from the TeX typesetting system.

A Khipukamayuqs is part of a typsetting pipeline and will transform text into khipus. Khipus are the input for linebreakers. The overall process of creating them and the interaction with line breaking looks like this:

Create Khipus from Text

(1) Normalize Unicode text

https://godoc.org/golang.org/x/text/unicode/norm

(2) Find natural text wrap opportunities (words in many scripts, syllables/character in East Asia, etc.)

https://godoc.org/github.com/npillmayer/gotype/core/uax

(3) Bi-directional text

https://godoc.org/golang.org/x/text/unicode/bidi
https://www.w3.org/International/articles/inline-bidi-markup/

(4) Hyphenation: Lliang patterns + language-specific code

https://godoc.org/github.com/npillmayer/gotype/core/hyphenation

(5) Translate feasible breakpoints to penalties, glue and discretionaries

https://wiki.apache.org/xmlgraphics-fop/KnuthsModel

(6) Shape text -> Glyphs + alternative glyphs (end-of-line condensed in Arabic, etc.)

http://behdad.org/text/

At this point, text has been fully converted to khipus.

BSD License

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. Neither the name of this software nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Index

Constants

View Source
const (
	HList int = iota // horizontal list
	VList            // vertical list
	MList            // math list
)

List types

Variables

This section is empty.

Functions

func CT

func CT() tracing.Trace

CT traces to the core-tracer.

func HyphenateTextBoxes

func HyphenateTextBoxes(khipu *Khipu, pipeline *TypesettingPipeline, regs *params.TypesettingRegisters)

HyphenateTextBoxes hypenates all the words in a khipu. Words are contained inside TextBox knots.

Hyphenation is governed by the typesetting registers provided. If regs is nil, no hyphenation is done.

func HyphenateWord

func HyphenateWord(word string, regs *params.TypesettingRegisters) ([]string, bool)

HyphenateWord hyphenates a single word.

func KnotString

func KnotString(k Knot) string

KnotString is a debugging helper and returns a textual representation of a knot.

Types

type Cursor

type Cursor struct {
	// contains filtered or unexported fields
}

A Cursor navigates over the knots of a khipu

func NewCursor

func NewCursor(kh *Khipu) *Cursor

NewCursor creates a cursor for a given khipu. Usage is unsafe if the referenced khipu changes during lifetime of the cursor.

func (Cursor) AsDiscretionary

func (c Cursor) AsDiscretionary() *Discretionary

AsDiscretionary returns the current knot as a discretionary item.

func (Cursor) AsGlue

func (c Cursor) AsGlue() Glue

AsGlue returns the current knot as a glue item.

func (Cursor) AsKern

func (c Cursor) AsKern() Kern

AsKern returns the current knot as a kern item.

func (Cursor) AsPenalty

func (c Cursor) AsPenalty() Penalty

AsPenalty returns the current knot as a penalty.

func (Cursor) AsTextBox

func (c Cursor) AsTextBox() *TextBox

AsTextBox returns the current knot as a text box.

func (Cursor) IsValidPosition

func (c Cursor) IsValidPosition() bool

IsValidPosition returns true, if the cursor is located at a a valid position, false otherwise.

func (*Cursor) Khipu

func (c *Cursor) Khipu() *Khipu

Khipu returns the underlying khipu. Clients should not modify it, except with the methods of the cursor. Different cursors should not modify the same khipu. Modifying a khipu may render previously returned marks invalid.

func (*Cursor) Knot

func (c *Cursor) Knot() Knot

Knot returns the knot at the current position.

func (*Cursor) Mark

func (c *Cursor) Mark() Mark

Mark returns a mark for the current position/glyph.

func (*Cursor) Next

func (c *Cursor) Next() bool

Next moves the cursor one knot ahead. Returns true if the cursor is still at a valid position, false otherwise.

func (*Cursor) Peek

func (c *Cursor) Peek() (Knot, bool)

Peek is lookahead 1. Does not advance the cursor. Returns true if the lookahead is at a valid position, false otherwise.

func (*Cursor) Position

func (c *Cursor) Position() int

Position returns the current position within the khipu as an integer.

func (*Cursor) Prev

func (c *Cursor) Prev() bool

Prev moves the cursor one knot back. Returns true if the cursor is still at a valid position, false otherwise.

func (Cursor) ReplaceKnot

func (c Cursor) ReplaceKnot(knot Knot) Knot

ReplaceKnot replaces the knot under the cursor, if any. It it returns the current knot.

func (Cursor) String

func (c Cursor) String() string

type Discretionary

type Discretionary struct {
	HyphenChar rune
	Width      dimen.Dimen
}

A Discretionary is a hyphenation opportunity

func (Discretionary) IsDiscardable

func (d Discretionary) IsDiscardable() bool

IsDiscardable is part of interface Knot. Discretionaries are not discardable.

func (Discretionary) MaxW

func (d Discretionary) MaxW() dimen.Dimen

MaxW is part of interface Knot. Returns the width of the post-hyphen text.

func (Discretionary) MinW

func (d Discretionary) MinW() dimen.Dimen

MinW is part of interface Knot. Returns the width of the pre-hyphen text.

func (Discretionary) Type

func (d Discretionary) Type() KnotType

Type is part of interface Knot.

func (Discretionary) W

func (d Discretionary) W() dimen.Dimen

W is part of interface Knot. Returns the width of the un-hyphenated text.

type Glue

type Glue [3]dimen.Dimen

A Glue is a space which can shrink and expand

func NewFill

func NewFill(f int) Glue

NewFill creates a drop of infinitely stretchable glue.

func NewGlue

func NewGlue(w dimen.Dimen, shrink dimen.Dimen, stretch dimen.Dimen) Glue

NewGlue creates a new drop of glue with stretch and shrink.

func (Glue) IsDiscardable

func (g Glue) IsDiscardable() bool

IsDiscardable is part of interface Knot. Glue is discardable.

func (Glue) MaxW

func (g Glue) MaxW() dimen.Dimen

MaxW is part of interface Knot. Maximum width of the glue.

func (Glue) MinW

func (g Glue) MinW() dimen.Dimen

MinW is part of interface Knot. Minimum width of the glue.

func (Glue) String

func (g Glue) String() string

func (Glue) Type

func (g Glue) Type() KnotType

Type is part of interface Knot.

func (Glue) W

func (g Glue) W() dimen.Dimen

W is part of interface Knot. Natural width of the glue.

type Kern

type Kern dimen.Dimen // fixed width

A Kern is an unshrinkable space

func (Kern) IsDiscardable

func (k Kern) IsDiscardable() bool

IsDiscardable is part of interface Knot. Kerns are discardable.

func (Kern) MaxW

func (k Kern) MaxW() dimen.Dimen

MaxW is part of interface Knot. Kerns do not stretch.

func (Kern) MinW

func (k Kern) MinW() dimen.Dimen

MinW is part of interface Knot. Kerns do not shrink.

func (Kern) String

func (k Kern) String() string

func (Kern) Type

func (k Kern) Type() KnotType

Type is part of interface Knot.

func (Kern) W

func (k Kern) W() dimen.Dimen

W is part of interface Knot. Width of the kern.

type Khipu

type Khipu struct {
	// contains filtered or unexported fields
}

Khipu is a string of knots. We handle text/paragraphs as khipus.

func KnotEncode

func KnotEncode(text io.Reader, pipeline *TypesettingPipeline, regs *params.TypesettingRegisters) *Khipu

KnotEncode transforms an input text into a khipu.

func NewKhipu

func NewKhipu() *Khipu

NewKhipu creates a new knot list.

func (*Khipu) AppendKhipu

func (kh *Khipu) AppendKhipu(k *Khipu) *Khipu

AppendKhipu concatenates two khipus.

func (*Khipu) AppendKnot

func (kh *Khipu) AppendKnot(knot Knot) *Khipu

AppendKnot appends a knot at the end of the list.

func (*Khipu) Length

func (kh *Khipu) Length() int

Length gives the number of knots in the list.

func (*Khipu) MaxHeightAndDepth

func (kh *Khipu) MaxHeightAndDepth(from, to int) (dimen.Dimen, dimen.Dimen)

MaxHeightAndDepth finds the maximum height and depth of the knots in the range [from ... to-1]. Only knots of type TextBox are considered.

func (*Khipu) MaxWidth

func (kh *Khipu) MaxWidth(from, to int) dimen.Dimen

MaxWidth finds the maximum width of the knots in the range [from ... to-1].

func (*Khipu) Measure

func (kh *Khipu) Measure(from, to int) (dimen.Dimen, dimen.Dimen, dimen.Dimen)

Measure returns the widths of a subset of this knot list. The subset runs from index [from ... to-1]. The method returns natural, maximum and minimum width.

func (*Khipu) Reach

func (kh *Khipu) Reach(start int, distance dimen.Dimen) (int, int)

Reach iterates over a khipu to find a point beyond a given distance. Starting from a knot (index), return a set of knots which mark possible endpoints for a sequence of knots to cover a certain width distance. The knot set is returned as a pair (from,to) of indices. If the distance cannot be covered, (-1,-1) is returned.

func (*Khipu) ReplaceKnot

func (kh *Khipu) ReplaceKnot(inx int, knot Knot) Knot

ReplaceKnot replaces a knot within the khipu. If inx is not a valid index for the khipu, nothing is done.

Returns the current knot at position inx.

func (*Khipu) String

func (kh *Khipu) String() string

Debug representation of a knot list.

func (*Khipu) Text

func (kh *Khipu) Text(from, to int) string

Text returns the text contents of a khipu segment.

type Knot

type Knot interface {
	Type() KnotType      // type identifier of this knot
	W() dimen.Dimen      // width
	MinW() dimen.Dimen   // minimum width
	MaxW() dimen.Dimen   // maximum width
	IsDiscardable() bool // is this knot discardable?
}

A Knot has a width and may be discardable

func NewKnot

func NewKnot(knottype KnotType) Knot

NewKnot is a factory method to create a knot. Parameter is a valid knot type.

type KnotType

type KnotType int8

KnotType is a type for the different flavours of knots.

const (
	KTKern KnotType = iota
	KTGlue
	KTTextBox
	KTPenalty
	KTDiscretionary
	KTUserDefined // clients should use custom knot types above this
)

Knot types

type Mark

type Mark interface {
	Position() int
	Knot() Knot
}

Mark is a type for a position within a khipu.

type Penalty

type Penalty int

A Penalty contributes to demerits, i.e. the quality index of paragraphs

func (Penalty) Demerits

func (p Penalty) Demerits() int32

Demerits returns the penalty as demerits. No numeric changes are made.

func (Penalty) IsDiscardable

func (p Penalty) IsDiscardable() bool

IsDiscardable is part of interface Knot. Penalties are discardable.

func (Penalty) MaxW

func (p Penalty) MaxW() dimen.Dimen

MaxW is part of interface Knot. Returns 0.

func (Penalty) MinW

func (p Penalty) MinW() dimen.Dimen

MinW is part of interface Knot. Returns 0.

func (Penalty) String

func (p Penalty) String() string

func (Penalty) Type

func (p Penalty) Type() KnotType

Type is part of interface Knot.

func (Penalty) W

func (p Penalty) W() dimen.Dimen

W is part of interface Knot. Returns 0.

type TextBox

type TextBox struct {
	Width  dimen.Dimen // width
	Height dimen.Dimen // height
	Depth  dimen.Dimen // depth
	// contains filtered or unexported fields
}

A TextBox is a fixed unit of text

func NewTextBox

func NewTextBox(s string) *TextBox

NewTextBox creates a text box.

func (TextBox) IsDiscardable

func (b TextBox) IsDiscardable() bool

IsDiscardable is part of interface Knot. Text is not discardable.

func (TextBox) MaxW

func (b TextBox) MaxW() dimen.Dimen

MaxW is part of interface Knot. Width of the glue.

func (TextBox) MinW

func (b TextBox) MinW() dimen.Dimen

MinW is part of interface Knot. Width of the glue.

func (TextBox) String

func (b TextBox) String() string

func (TextBox) Text

func (b TextBox) Text() string

Text returns the enclosed text as a string.

func (TextBox) Type

func (b TextBox) Type() KnotType

Type is part of interface Knot.

func (TextBox) W

func (b TextBox) W() dimen.Dimen

W is part of interface Knot. Width of the glue.

type TypesettingPipeline

type TypesettingPipeline struct {
	// contains filtered or unexported fields
}

A TypesettingPipeline consists of steps to produce a khipu from text.

func PrepareTypesettingPipeline

func PrepareTypesettingPipeline(text io.Reader, pipeline *TypesettingPipeline) *TypesettingPipeline

PrepareTypesettingPipeline checks if a typesetting pipeline is correctly initialized and creates a new one if is is invalid.

We use a uax14.LineWrapper as the primary breaker and use a segment.SimpleWordBreaker to extract spans of whitespace. For the inner loop we use a uax29.WordBreaker. This is a default configuration adequate for western languages.

Directories

Path Synopsis
Package linebreak collects types for line-breaking.
Package linebreak collects types for line-breaking.
firstfit
Package firstfit implements a straightforward line-breaking algorithm where lines are broken at the first suitable breakpoint.
Package firstfit implements a straightforward line-breaking algorithm where lines are broken at the first suitable breakpoint.
knuthplass
Package knuthplass implements (in an early draft) a line breaking algorithm described by D.E. Knuth and M.F. Plass.
Package knuthplass implements (in an early draft) a line breaking algorithm described by D.E. Knuth and M.F. Plass.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL