///|
fn PdfDocumentPageSpecContext::read_page_label_reference(
self : PdfDocumentPageSpecContext,
spec : BytesView,
open_index : Int,
) -> (Bytes, Int) raise @core.PdfError {
let label : Array[Byte] = []
for index = open_index + 1; index < spec.length(); {
match spec[index] {
b']' => return (Bytes::from_array(label), index + 1)
b'\\' if index + 1 < spec.length() && spec[index + 1] is (b'[' | b']') => {
label.push(spec[index + 1])
continue index + 2
}
b'[' => {
self.bad()
continue index + 1
}
byte => {
label.push(byte)
continue index + 1
}
}
}
self.bad()
(Bytes::new(0), spec.length())
}
///|
fn PdfDocumentPageSpecContext::page_number_bytes_for_label(
self : PdfDocumentPageSpecContext,
label : BytesView,
labels : ArrayView[@label.PdfPageLabel],
) -> Bytes raise @core.PdfError {
for page_number in 1..<=self.end_page {
let page_label = match
@label.pdf_page_label_text_of_page_number(page_number, labels) {
Some(value) => value
None => Bytes::new(0)
}
if page_label[:] == label {
return @ascii.encode(page_number.to_string())
}
}
self.bad()
Bytes::new(0)
}
///|
fn PdfDocumentPageSpecContext::resolve_page_labels(
self : PdfDocumentPageSpecContext,
spec : BytesView,
) -> Bytes raise @core.PdfError {
let labels = self.document.read_page_labels()
let output : Array[Byte] = Array(capacity=spec.length())
for index = 0; index < spec.length(); {
match spec[index] {
b'[' => {
let (label, next_index) = self.read_page_label_reference(spec, index)
let page_number = self.page_number_bytes_for_label(label, labels)
for byte in page_number {
output.push(byte)
}
continue next_index
}
b'\\' if index + 1 < spec.length() && spec[index + 1] is (b'[' | b']') => {
output.push(spec[index + 1])
continue index + 2
}
b']' => {
self.bad()
continue index + 1
}
byte => {
output.push(byte)
continue index + 1
}
}
}
Bytes::from_array(output)
}