#!/usr/bin/env python3 """ ========================================================================= User-guide local links => online links, for the program-only zip [2.1]. Part of the thumbspage program (learning-python.com/thumbspage.html). Replace all local 'example/' URLs in UserGuide.html with online URLs. This script creates a new file for its result, UserGuideLive.html. Run me from anywhere (it uses the script's own dir explicitly, not cwd). An inverse function can also unpatch the live links, if ever needed. At 246M in 2.1, the examples/ folder may be better accessed online, but links to it in the user guide need to use either local or online content. To support both, local links (href="examples/) are always used when writing the guide, and this script is run at build time to change all examples/ links to point online instead (href="https://...). HTML has no notion of variables; the guide could use a tag replaced on demand, but this make it difficult to view content being developed, and JavaScript is a nonstarter for this document. No other HTML files can use local examples/ links (they're elsewhere in the site). This script also looks for any online links in original (they should all be locals). Note: the user guide also references other top-level items besides examples/ content (e.g., docetc/ images, build/ scripts, and top-level code files), so it cannot be shipped with the examples-only zip. The program zip is everything but examples/, so these links work. They could be changed to online links too, but examples/ is the real size hog. Verification of Apr-2022 changes here (using UserGuideLive at ?? ahead): .../thumbspage$ rm -f UserGuideLive.html UserGuideLocal.html .../thumbspage$ cd build/ .../thumbspage/build$ py3 userguide-online-links.py > /dev/null .../thumbspage/build$ py3 userguide-online-links.py - > /dev/null .../thumbspage/build$ cd .. .../thumbspage$ diff UserGuide.html UserGuideLocal.html .../thumbspage$ diff UserGuideLive.html progzip/thumbspage/UserGuide.html .../thumbspage$ ========================================================================= """ import os, sys trace = lambda *args, **kargs: print(' '*4, *args, **kargs) mydir = os.path.dirname(__file__) def patchFile(fromfile, tofile, fromkey, tokey): """ ----------------------------------------------- Replace all fromkey with tokey in fromfile, put result in tofile. Trace lines, return #changed. ----------------------------------------------- """ orig = open(fromfile, 'r', encoding='utf8') copy = open(tofile, 'w', encoding='utf8') patches = 0 for line in orig: if fromkey in line: trace(line, end='') patches += 1 line = line.replace(fromkey, tokey) copy.write(line) orig.close() copy.close() return patches localLink = '="examples' onlineLink = '="https://learning-python.com/thumbspage/examples' def patchOnlineToLocal(): """ ----------------------------------------------- Revert online=>local links in a new doc copy. Use this to undo patchLocalToOnline's output. ----------------------------------------------- """ print('Unpatched lines:') source = os.path.join(mydir, '..', 'UserGuide.html') # or UserGuideLive?? dest = os.path.join(mydir, '..', 'UserGuideLocal.html') patches = patchFile(source, dest, fromkey=onlineLink, tokey=localLink) print('Lines unpatched:', patches) def patchLocalToOnline(): """ ----------------------------------------------- Change local=>online links in a new doc copy. This could be a sed command, of course, but Py is more portable and flexible (and funner). ----------------------------------------------- """ print('Patched lines:') source = os.path.join(mydir, '..', 'UserGuide.html') dest = os.path.join(mydir, '..', 'UserGuideLive.html') patches = patchFile(source, dest, fromkey=localLink, tokey=onlineLink) print('Lines patched:', patches) def findLurkers(): """ ----------------------------------------------- Are there any online links in the original? There were 4 initially, plus 2 valid refs. ----------------------------------------------- """ print('Finding lurkers') source = os.path.join(mydir, '..', 'UserGuide.html') local1 = '="examples' orig = open(source, 'r', encoding='utf8') l1 = [line for line in orig if local1 in line] print('Local links:', len(l1)) local2 = 'examples/' orig = open(source, 'r', encoding='utf8') l2 = [line for line in orig if local2 in line] print('Possible online links:', len(l2)) lurkers = set(l2) - set(l1) if lurkers: print('Possible online links in original:', len(l2) - len(l1)) for line in lurkers: trace(line, end='') print() if __name__ == '__main__': findLurkers() # report before changes if len(sys.argv) > 1: patchOnlineToLocal() # any arg: undo patched online links else: patchLocalToOnline() # normal run: patch local=>online links """ ============================================================================== Output: ~/MY-STUFF/Code/thumbspage/build$ python3 userguide-online-links.py Finding lurkers Local links: 268 Possible online links: 274 Possible online links in original: 6 here ... Patched lines: packaged examples, browser. index page with generated ... Lines patched: 268 ============================================================================== """