#!/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
==============================================================================
"""