1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-07-19 13:19:43 +02:00
documize/model/page/numbering.go
2018-06-09 19:13:38 +01:00

158 lines
3.3 KiB
Go

// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
package page
import (
"fmt"
)
// Numberize calculates numbers for pages, e.g. 1, 1.1, 2.2.1
// for the document's Table of Contents.
func Numberize(pages []Page) {
var prevPageLevel uint64
parts := []int{1} // we store 1, 1, 2, and then generate numbering as "1.1.2"
for i, p := range pages {
// handle bad data
if p.Level == 0 || (i == 0 && p.Level > 1) {
p.Level = 1
}
if i != 0 {
// we ...
if p.Level > prevPageLevel {
parts = append(parts, 1)
}
if p.Level == prevPageLevel {
j := len(parts) - 1
if j >= 0 {
parts[j]++
}
}
if p.Level < prevPageLevel {
end := (prevPageLevel - p.Level)
if int(end) > len(parts) {
end = uint64(len(parts))
}
parts = parts[0 : len(parts)-int(end)]
i := len(parts) - 1
if i < 0 {
i = 0
}
if i >= 0 && i < len(parts) {
parts[i]++
}
}
}
// generate numbering for page using parts array
numbering := ""
for i, v := range parts {
dot := ""
if i != len(parts)-1 {
dot = "."
}
numbering = fmt.Sprintf("%s%d%s", numbering, v, dot)
}
pages[i].Numbering = numbering
// Troubleshooting help
if len(numbering) == 0 {
fmt.Println(fmt.Sprintf("No number allocated to page %s ('%s')",
pages[i].RefID, pages[i].Title))
}
// update state
prevPageLevel = p.Level
}
}
// Levelize ensure page level increments are consistent
// after a page is inserted or removed.
//
// Valid: 1, 2, 3, 4, 4, 4, 2, 1
// Invalid: 1, 2, 4, 4, 2, 1 (note the jump from 2 --> 4)
//
// Rules:
// 1. levels can increase by 1 only (e.g. from 1 to 2 to 3 to 4)
// 2. levels can decrease by any amount (e.g. drop from 4 to 1)
func Levelize(pages []Page) {
var prevLevel uint64
prevLevel = 1
for i := 0; i < len(pages); i++ {
currLevel := pages[i].Level
// handle deprecated level value of 0
if pages[i].Level == 0 {
pages[i].Level = 1
}
// first time thru
if i == 0 {
// first time thru
pages[i].Level = 1
prevLevel = 1
continue
}
if currLevel == prevLevel {
// nothing doing
continue
}
if currLevel > prevLevel+1 {
// bad data detected e.g. prevLevel=1 and pages[i].Level=3
// so we re-level to pages[i].Level=2 and all child pages
// and then increment i to correct point
prevLevel++
pages[i].Level = prevLevel
// safety check before entering loop and renumbering child pages
if i+1 <= len(pages) {
for j := i + 1; j < len(pages); j++ {
if pages[j].Level < prevLevel {
i = j
break
}
if pages[j].Level == currLevel {
pages[j].Level = prevLevel
} else if (pages[j].Level - prevLevel) > 1 {
currLevel = pages[j].Level
prevLevel++
pages[j].Level = prevLevel
}
i = j
}
}
continue
}
prevLevel = currLevel
}
}
// Sequenize will re-generate page sequence numbers for a document
func Sequenize(p []Page) {
var seq float64
seq = 2048
for i := range p {
p[i].Sequence = seq
seq = seq * 2
}
}