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

Add page label info to page marker flags #330

Merged
Merged
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
111 changes: 65 additions & 46 deletions src/guiguts/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
PAGE_FLAG_TAG,
PAGEMARK_PIN,
BOOKMARK_TAG,
PAGEMARK_PREFIX,
img_from_page_mark,
page_mark_from_img,
)
from guiguts.page_details import (
PageDetail,
PageDetails,
PAGE_LABEL_PREFIX,
NUMBER_INCREMENT,
STYLE_ARABIC,
STYLE_DITTO,
)
Expand Down Expand Up @@ -54,6 +54,18 @@
PAGE_FLAGS_NONE = 0
PAGE_FLAGS_SOME = 1
PAGE_FLAGS_ALL = 2
PAGE_FLAG_PREFIX = "Img"
PAGE_FLAG_START = "["
PAGE_FLAG_START_E = re.escape(PAGE_FLAG_START)
PAGE_FLAG_END = "]"
PAGE_FLAG_END_E = re.escape(PAGE_FLAG_END)
PAGE_FLAG_SEP = "|"
PAGE_FLAG_SEP_E = re.escape(PAGE_FLAG_SEP)
PAGE_FLAG_ARABIC = "A"
PAGE_FLAG_ROMAN = "R"
# 3 capture groups for img, style (Roman/Arabic), number (or +1/None)
# Label is calculated from other info after file load.
PAGE_FLAG_REGEX = rf"{PAGE_FLAG_START_E}{PAGE_FLAG_PREFIX}(.+?){PAGE_FLAG_SEP_E}(.+?){PAGE_FLAG_SEP_E}(.+?){PAGE_FLAG_END_E}"

PAGE_SEPARATOR_REGEX = r"File:.+?([^/\\ ]+)\.(png|jpg)"

Expand Down Expand Up @@ -206,18 +218,12 @@ def load_file(self, filename: str) -> None:
"Main file and bin (.json) file do not match.\n"
" File may have been edited in a different editor.\n"
)
if flags_found == PAGE_FLAGS_ALL:
if flags_found:
logger.warning(
msg_start + " However, page marker flags were detected,\n"
" so page boundary positions were updated if necessary."
)
elif flags_found == PAGE_FLAGS_SOME:
logger.error(
msg_start + " Not all page marker flags are present,\n"
" so some boundary positions were not updated."
)
else:
assert flags_found == PAGE_FLAGS_NONE
logger.error(
msg_start + " You may continue, but page boundary positions\n"
" may not be accurate."
Expand Down Expand Up @@ -444,9 +450,7 @@ def mark_page_boundaries(self) -> None:
standard_line = f"-----File: {page}.{ext}"
standard_line += "-" * (75 - len(standard_line))
# Don't standarize line if it has a page marker flag on it, or you'll delete the flag!
if line != standard_line and not re.search(
rf"\[{PAGEMARK_PREFIX}\S+?\]", line
):
if line != standard_line and not re.search(PAGE_FLAG_REGEX, line):
maintext().delete(line_start, line_end)
maintext().insert(line_start, standard_line)
page_mark = page_mark_from_img(page)
Expand All @@ -458,7 +462,7 @@ def mark_page_boundaries(self) -> None:
line_start, page_num_style, page_num
)
page_num_style = STYLE_DITTO
page_num = "+1"
page_num = NUMBER_INCREMENT

search_start = line_end

Expand Down Expand Up @@ -597,21 +601,30 @@ def _next_prev_page(self, direction: Literal[1, -1]) -> None:
return
sound_bell()

# Note that the following code must match the equivalent code in Guiguts 1
# or file transfer between the two will be broken.
def add_page_flags(self) -> None:
"""Add [PgNNN] flag at each page boundary.
"""Add page flag at each page boundary.

Done in reverse order so two adjacent boundaries preserve their order.
"""
mark: str = tk.END
while mark := maintext().page_mark_previous(mark):
maintext().insert(mark, "[" + mark + "]", PAGE_FLAG_TAG)
img = img_from_page_mark(mark)
style = self.page_details[img]["style"]
number = self.page_details[img]["number"]
info = PAGE_FLAG_SEP.join([PAGE_FLAG_PREFIX + img, style, number])
maintext().insert(
mark,
PAGE_FLAG_START + info + PAGE_FLAG_END,
PAGE_FLAG_TAG,
)

def remove_page_flags(self) -> None:
"""Remove [PgNNN] flags."""
search_regex = r"\[" + PAGEMARK_PREFIX + r".+?\]"
"""Remove page flags."""
search_range = IndexRange(maintext().start(), maintext().end())
while match := maintext().find_match(
search_regex,
PAGE_FLAG_REGEX,
search_range,
nocase=False,
regexp=True,
Expand All @@ -621,43 +634,49 @@ def remove_page_flags(self) -> None:
maintext().delete(
match.rowcol.index(), match.rowcol.index() + f"+{match.count}c"
)
search_range = IndexRange(match.rowcol, maintext().end())

def update_page_marks_from_flags(self) -> int:
"""Update page mark locations from flags in file.
def update_page_marks_from_flags(self) -> bool:
"""If page marker flags in file, replace all existing page marks.

Also tag flags to highlight them.

Returns:
PAGE_FLAGS_ALL/SOME/NONE depending on what flags were present.
True if page marker flags were present.
"""
search_range = IndexRange(maintext().start(), maintext().end())
mark = "1.0"
flag_found = False
flag_not_found = False
while mark := maintext().page_mark_next(mark):
img = img_from_page_mark(mark)
assert img in self.page_details
if match := maintext().find_match(
f"[{mark}]",
search_range,
nocase=False,
regexp=False,
wholeword=False,
backwards=False,
):
if maintext().compare(mark, "!=", match.rowcol.index()):
maintext().mark_set(mark, match.rowcol.index())
maintext().tag_add(
PAGE_FLAG_TAG,
match.rowcol.index(),
match.rowcol.index() + f"+{match.count}c",
)
flag_found = True
else:
flag_not_found = True
if flag_found:
return PAGE_FLAGS_SOME if flag_not_found else PAGE_FLAGS_ALL
return PAGE_FLAGS_NONE
flag_matches = maintext().find_matches(
PAGE_FLAG_REGEX,
search_range,
nocase=False,
regexp=True,
wholeword=False,
)
if not flag_matches:
return False

# Remove existing page marks, if any
self.remove_page_marks()
self.page_details = PageDetails()
for match in flag_matches:
flag_text = maintext().get_match_text(match)
extract = re.fullmatch(PAGE_FLAG_REGEX, flag_text)
# Will always match because same regex as above
assert extract is not None
img = extract[1]
style = extract[2]
number = extract[3]
mark = page_mark_from_img(img)
maintext().set_mark_position(mark, match.rowcol)
self.page_details[img] = PageDetail(match.rowcol.index(), style, number)
maintext().tag_add(
PAGE_FLAG_TAG,
match.rowcol.index(),
match.rowcol.index() + f"+{match.count}c",
)
maintext().set_modified(True)
return True

def add_good_and_bad_words(self) -> None:
"""Load the words from the good and bad words files into the project dictionary."""
Expand Down
2 changes: 1 addition & 1 deletion src/guiguts/page_details.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ def item_clicked(self, event: tk.Event, reverse: bool) -> None:
"Set Number", "Enter page number", parent=self
)
new_value = pagenum if pagenum else value
self.details[row[COL_HEAD_IMG]]["number"] = new_value
self.details[row[COL_HEAD_IMG]]["number"] = str(new_value)

# Refresh the list
self.details.recalculate()
Expand Down
Loading