Skip to content

Commit 66265a7

Browse files
authored
Fix progress bars in tutobooks. (#2093)
Added better detection of blocks that are progress bars. Added better handling of progress bars to only display the final state of each progress bar.
1 parent bdfc1bc commit 66265a7

File tree

2 files changed

+95
-16
lines changed

2 files changed

+95
-16
lines changed

scripts/autogen.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,6 @@ def preprocess_tutobook_md_source(
144144
)
145145
# Insert --- before H2 titles
146146
md_content = md_content.replace("\n## ", "\n---\n## ")
147-
# Clean up progress bar output
148-
if "" in md_content:
149-
md_content = md_content.replace("", " ")
150-
md_content = md_content.replace(" ", " ")
151-
md_content = md_content.replace(" ", " ")
152-
md_content = md_content.replace("", "")
153-
md_content = md_content.replace(" ", "")
154147
return md_content
155148

156149
def make_tutobook_sources_for_directory(

scripts/tutobooks.py

Lines changed: 95 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
"""
6363

6464
import os
65+
import re
6566
import sys
6667
import json
6768
import copy
@@ -486,24 +487,109 @@ def _make_output_code_blocks(md):
486487
is_inside_backticks = False
487488

488489
def is_output_line(line, prev_line, output_lines):
490+
if (
491+
output_lines
492+
and "\x08" in output_lines[-1]
493+
and not output_lines[-1].replace("\x08", "").strip()
494+
):
495+
# We already started a block and the last line is just deletes, that
496+
# implies that the current line will be part of the block (progress
497+
# bar being re-written).
498+
return True
499+
489500
if line.startswith(" ") and len(line) >= 5:
490-
if output_lines or (lines[i - 1].strip() == "" and line.strip()):
501+
# Non-empty indented line
502+
if output_lines:
503+
# Continuation of the output block
504+
return True
505+
if not prev_line.strip():
506+
# Begining of an output block
507+
return True
508+
elif not line.strip():
509+
# Empty line
510+
if output_lines:
511+
# Continuation of the output block
491512
return True
513+
elif line.strip()[0] in ("\x1b", "\x08"):
514+
# Line starts with ESC or delete character, it must be a progress
515+
# bar, which is often not indented.
516+
return True
492517
return False
493518

494519
def flush(output_lines, final_lines):
495520
final_lines.append('<div class="k-default-codeblock">')
496521
final_lines.append("```")
497-
if len(output_lines) == 1:
498-
line = output_lines[0]
499-
final_lines.append(line[4:])
500-
else:
501-
for line in output_lines:
502-
final_lines.append(line[4:])
522+
523+
# When not None, we are in a progress bar and this is its last state.
524+
progress_bar = None
525+
# Used to dedupe empty lines. Also used when in a progress bar.
526+
previous_line_empty = False
527+
528+
for line in output_lines:
529+
# Unindent.
530+
if line.startswith(" "):
531+
# Normal block is indented by 4 spaces.
532+
line = line[4:]
533+
else:
534+
# Progress bar and empty lines.
535+
line = line.strip()
536+
537+
if "\x1b" in line or "\x08" in line:
538+
# This is a progress bar.
539+
if "\x1b" in line:
540+
# Remove escape sequences.
541+
line = re.sub(r"\x1b\[[0-9][0-9]?m", "", line)
542+
543+
if "\x08" in line:
544+
# Delete characters, remove everything up to the last one.
545+
line = line[line.rindex("\x08") + 1 :].strip()
546+
547+
if previous_line_empty and progress_bar is None:
548+
# We're starting a progress bar, flush the empty line.
549+
final_lines.append("")
550+
551+
if progress_bar is None or line:
552+
# Update latest progress bar content.
553+
progress_bar = line
554+
555+
previous_line_empty = not line
556+
# When in a progress bar, don't append.
557+
continue
558+
559+
if progress_bar is not None and not line:
560+
# In a progress bar with an empty line.
561+
previous_line_empty = True
562+
# We're staying in the progress bar, don't append.
563+
continue
564+
565+
# If we get here, we're not / no longer in a progress bar.
566+
567+
if progress_bar:
568+
# Flush progress bar content with the last value.
569+
final_lines.append(progress_bar)
570+
progress_bar = None
571+
572+
if line:
573+
if previous_line_empty:
574+
# Flush empty line before appending non-empty line.
575+
final_lines.append("")
576+
final_lines.append(line)
577+
previous_line_empty = False
578+
else:
579+
previous_line_empty = True
580+
581+
if progress_bar:
582+
# Flush progress bar content with the last value.
583+
final_lines.append(progress_bar)
584+
503585
final_lines.append("```")
504586
final_lines.append("</div>")
505587

506-
for i, line in enumerate(lines):
588+
if previous_line_empty:
589+
# If the last line in the block was empty, put it after the block.
590+
final_lines.append("")
591+
592+
for line in lines:
507593
if line.startswith("```"):
508594
is_inside_backticks = not is_inside_backticks
509595
final_lines.append(line)
@@ -513,7 +599,7 @@ def flush(output_lines, final_lines):
513599
final_lines.append(line)
514600
continue
515601

516-
if i > 0 and is_output_line(line, lines[-1], output_lines):
602+
if final_lines and is_output_line(line, final_lines[-1], output_lines):
517603
output_lines.append(line)
518604
elif not line:
519605
if output_lines:

0 commit comments

Comments
 (0)