///|
fn pdf_addtext_find_byte(bytes : BytesView, start : Int, value : Int) -> Int? {
let mut index = start
while index < bytes.length() {
if bytes[index].to_int() == value {
return Some(index)
}
index += 1
}
None
}
///|
fn pdf_addtext_require_byte(
bytes : BytesView,
start : Int,
value : Int,
) -> Int raise @core.PdfError {
match pdf_addtext_find_byte(bytes, start, value) {
Some(index) => index
None => raise SoftError("bad URL syntax in text")
}
}
///|
fn pdf_addtext_is_url_marker(bytes : BytesView, index : Int) -> Bool {
index + 4 < bytes.length() &&
bytes[index].to_int() == 37 &&
bytes[index + 1].to_int() == 85 &&
bytes[index + 2].to_int() == 82 &&
bytes[index + 3].to_int() == 76 &&
bytes[index + 4].to_int() == 91
}
///|
fn pdf_addtext_utf8_string(bytes : BytesView) -> String raise @core.PdfError {
@utf8.decode(bytes) catch {
_ => raise InvalidUTF8
}
}
///|
fn pdf_addtext_url_visible_length(
bytes : BytesView,
) -> Int raise @core.PdfError {
let mut index = 0
let mut length = 0
while index < bytes.length() {
if pdf_addtext_is_url_marker(bytes, index) {
let text_start = index + 5
let pipe = pdf_addtext_require_byte(bytes, text_start, 124)
let close = pdf_addtext_require_byte(bytes, pipe + 1, 93)
length += pipe - text_start
index = close + 1
} else {
length += 1
index += 1
}
}
length
}
///|
/// Strip cpdf add-text `%URL[text|url]` markup from one line.
///
/// The returned URL spans use byte offsets in the stripped visible text, as in
/// cpdf's `get_urls_line` helper.
pub fn pdf_addtext_get_urls_line(
line : String,
) -> PdfAddTextUrlLine raise @core.PdfError {
let bytes = @utf8.encode(line)
let output = Array::make(pdf_addtext_url_visible_length(bytes), b'\x00')
let urls : Array[PdfAddTextUrl] = Array(capacity=bytes.length() / 5)
let mut index = 0
let mut position = 0
while index < bytes.length() {
if pdf_addtext_is_url_marker(bytes, index) {
let text_start = index + 5
let pipe = pdf_addtext_require_byte(bytes, text_start, 124)
let close = pdf_addtext_require_byte(bytes, pipe + 1, 93)
let start = position
for byte in bytes[text_start:pipe] {
output[position] = byte
position += 1
}
let url = pdf_addtext_utf8_string(bytes[pipe + 1:close])
let end = position
urls.push({ url, start, end, })
index = close + 1
} else {
output[position] = bytes[index]
position += 1
index += 1
}
}
{ text: pdf_addtext_utf8_string(Bytes::from_array(output)), urls, }
}