diff --git a/core/utils.py b/core/utils.py index 26be1a0..7e5b212 100644 --- a/core/utils.py +++ b/core/utils.py @@ -124,6 +124,56 @@ def alphabet_suffix(n): suffix = "_X_" + random.choice(string.ascii_lowercase) + random.choice(string.ascii_lowercase) return suffix +def wrap_text(text): + """ + Splits a long string into multiple lines, ensuring that each line is no more than + 70 characters long. Newline characters are inserted immediately before spaces to + prevent breaking words. + + Parameters: + text (str): The input string that needs to be wrapped. + + Returns: + str: The input string formatted with newline characters such that each line + does not exceed 70 characters in length. + + Functionality: + 1. The function first splits the input string into individual words. + 2. It iterates through the words and adds them to the current line, ensuring the + line's length does not exceed 70 characters. + 3. If adding a word would cause the line to exceed the limit, the current line is + added to a list of lines, and a new line is started with the word. + 4. The process repeats until all words are processed, and the final line is added. + 5. The list of lines is then joined with newline characters and returned as a + single formatted string. + + This function written by CoPilot. + BUT interactions between exisitng \n characters makes this much less simple than it appears. + """ + + return text # abort all wrap processing pending proper redesign + + words = text.split(' ') + lines = [] + current_line = "" + + for word in words: + # Check if adding the word exceeds 70 characters + if len(current_line) + len(word) + 1 <= 70: + if current_line: + current_line += ' ' + current_line += word + else: + lines.append(current_line.strip(' ')) + current_line = word + + # Add the last line + if current_line: + lines.append(current_line.strip(' ')) + + # Join the lines with newline characters + return '\n'.join(lines) + def make_new_expo(year): coUniqueAttribs = {"year": year} otherAttribs = {"name": f"CUCC expo {year}", "logbookfile": "logbook.html"} diff --git a/core/views/logbook_edit.py b/core/views/logbook_edit.py index 198cc38..7207842 100644 --- a/core/views/logbook_edit.py +++ b/core/views/logbook_edit.py @@ -23,6 +23,7 @@ from troggle.core.utils import ( sanitize_name, unique_slug, write_and_commit, + wrap_text, ) from troggle.parsers.people import GetPersonExpeditionNameLookup, known_foreigner @@ -70,6 +71,8 @@ def store_edited_entry_into_database(date, place, title, text, others, author, t cave = GetCaveLookup().get(place.lower()) # print(f"store_edited_entry_into_database(): {place=} {cave=}") + text = wrap_text(text) + if LogbookEntry.objects.filter(slug=slug).exists(): # oops. message = f" ! - DUPLICATE SLUG for logbook entry {date} - {slug}" @@ -152,7 +155,21 @@ def logbookedit(request, year=None, slug=None): except: year = current_expo() # creates new Expedition object if needed return year + + def reformat_for_display(entry): + # entry = entry.replace("
", "\n\n") + return entry + def reformat_entry_from_user(entry): + """Makes it easier for user to edit, but hard to make this + idempotent over re-editing, given the wrap_text() used in the writing function. + We want \n in the file as-stored so that git works nicely. + """ + entry = entry.replace('\r','') # remove HTML-standard CR inserted from form. + entry = entry.replace('\n\n','\n
\n') # replace 2 \n with
+ + return entry + def new_entry_form(): # set the date to be "yesterday" as this will, hopefully, usually be the case @@ -212,8 +229,9 @@ def logbookedit(request, year=None, slug=None): entry = request.POST["text"].strip() if "prev_slug" in request.POST: prev_slug = request.POST["prev_slug"].strip() # if we are re-editing the same entry again - entry = entry.replace('\r','') # remove HTML-standard CR inserted from form. - entry = entry.replace('\n\n','\n
\n') # replace 2 \n with
+ + entry = reformat_entry_from_user(entry) + tu = request.POST["tu"].strip() tu = clean_tu(tu) @@ -391,7 +409,7 @@ def logbookedit(request, year=None, slug=None): others = others + ", " + lbe.other_people lenothers = min(70,max(20, len(others))) - text = lbe.text + text = reformat_for_display(lbe.text) rows = max(5,len(text)/50) return render( request,