mirror of
https://github.com/fadden/6502bench.git
synced 2024-11-29 10:50:28 +00:00
First cut at HTML block substitution script
Fairly straightfoward in Python. Also, fixed the sidenav references, which should be using the file in the sgtutorial subdirectory. Also, tweaked index.html a bit.
This commit is contained in:
parent
287ce3c065
commit
403bcf8518
166
docs/block-repl.py
Executable file
166
docs/block-repl.py
Executable file
@ -0,0 +1,166 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# Replace blocks of text in an HTML document with the contents of a file.
|
||||
#
|
||||
# For example:
|
||||
# <div id="masthead">
|
||||
# <!-- START: /masthead-incl.html -->
|
||||
# <script>$("#masthead").load("/masthead-incl.html");</script>
|
||||
# <!-- END: /masthead-incl.html -->
|
||||
# </div>
|
||||
#
|
||||
# Only the lines between START/END are replaced. The START/END lines are
|
||||
# left in place so the process can be performed repeatedly without needing
|
||||
# a separate ".in" file.
|
||||
#
|
||||
#
|
||||
# Run this from the top-level directory. Provide a list of all HTML files
|
||||
# on the command line.
|
||||
#
|
||||
# If the name of the file to include (specified on the START line) begins
|
||||
# with '/', the file will be loaded from the top-level directory, i.e. the
|
||||
# one where this command was run. If not, the file will be read from the
|
||||
# directory where the HTML file lives.
|
||||
#
|
||||
# (Tested with Python v3.8.5)
|
||||
#
|
||||
|
||||
import filecmp
|
||||
import os.path
|
||||
import re
|
||||
import sys
|
||||
|
||||
class LocalError(Exception):
|
||||
"""Errors generated internally"""
|
||||
pass
|
||||
|
||||
# Regex pattern for block substitution. There are three groups:
|
||||
# 0: (full match)
|
||||
# 1: START filename
|
||||
# 2: "active" id (optional)
|
||||
# 3: middle data (to be replaced)
|
||||
# 4: END filename
|
||||
# The START/END names are expected to match. If not, we probably found the
|
||||
# end of a different block, and should tell the user that something is off.
|
||||
findChunk = re.compile(
|
||||
"^\s*<!--\s*START:\s*([\w/\-\.]+)\s*"
|
||||
"(?:active:#([\w\-]*))?\s*-->\s*$."
|
||||
"(.*?)"
|
||||
"^\s*<!--\s*END:\s*([\w/\-\.]+)\s*-->",
|
||||
re.DOTALL | re.MULTILINE)
|
||||
GROUP_ALL = 0
|
||||
GROUP_START = 1
|
||||
GROUP_ACTIVE_ID = 2
|
||||
GROUP_CHUNK = 3
|
||||
GROUP_END = 4
|
||||
|
||||
|
||||
def editFile(inFileName, outFileName):
|
||||
""" Edit a file, replacing blocks with the contents of other files. """
|
||||
|
||||
try:
|
||||
with open(inFileName, "r") as inFile:
|
||||
fileData = inFile.read()
|
||||
outFile = open(outFileName, "x")
|
||||
except IOError as err:
|
||||
raise LocalError(err)
|
||||
|
||||
# For each chunk found, replace the contents.
|
||||
startPos = 0
|
||||
while True:
|
||||
match = findChunk.search(fileData, startPos)
|
||||
if not match:
|
||||
break
|
||||
|
||||
startTag = match.group(GROUP_START)
|
||||
endTag = match.group(GROUP_END)
|
||||
if startTag != endTag:
|
||||
raise LocalError("START/END tag mismatch: " + startTag + " vs. " + endTag)
|
||||
|
||||
replSpan = match.span(GROUP_CHUNK)
|
||||
|
||||
chunk = fileData[replSpan[0] : replSpan[1]]
|
||||
print("== Matched {0}:{1}".format(replSpan[0], replSpan[1]))
|
||||
|
||||
|
||||
activeId = match.group(GROUP_ACTIVE_ID)
|
||||
if activeId:
|
||||
print("== active ID: " + activeId)
|
||||
|
||||
# copy everything up to the chunk
|
||||
outFile.write(fileData[startPos : replSpan[0]])
|
||||
# insert the file, tweaking active ID if appropriate
|
||||
copyFromIncl(inFileName, startTag, activeId, outFile)
|
||||
# copy the rest of the match
|
||||
outFile.write(fileData[replSpan[1] : match.end(GROUP_ALL)])
|
||||
|
||||
# Start next search at end of full search.
|
||||
startPos = match.end(GROUP_ALL)
|
||||
print("== Start next at {0}".format(startPos))
|
||||
|
||||
print("== done")
|
||||
outFile.write(fileData[startPos:])
|
||||
outFile.close()
|
||||
|
||||
|
||||
def copyFromIncl(inFileName, tag, activeId, outFile):
|
||||
""" Copy incl file, substituting active ID if appropriate. """
|
||||
|
||||
if tag[0] == '/':
|
||||
# file is in top-level (current) directory
|
||||
inclFileName = tag[1:]
|
||||
else:
|
||||
# file is in same directory as input file
|
||||
inclFileName = os.path.join(os.path.dirname(inFileName), tag)
|
||||
|
||||
try:
|
||||
with open(inclFileName, "r") as inFile:
|
||||
fileData = inFile.read()
|
||||
except IOError as err:
|
||||
raise LocalError(err)
|
||||
|
||||
if activeId:
|
||||
# Given an HTML block like <li id="sidenav-moving-around">, insert
|
||||
# a class assignment: class="active". The ID to modify is
|
||||
# specified by "activeId".
|
||||
pattern = 'id="' + re.escape(activeId) + '"'
|
||||
repl = 'id="' + activeId + '" class="active"'
|
||||
newData = re.sub(pattern, repl, fileData)
|
||||
if newData == fileData:
|
||||
print("== active ID '" + activeId + "' not found")
|
||||
else:
|
||||
fileData = newData
|
||||
|
||||
outFile.write(fileData)
|
||||
|
||||
|
||||
def main():
|
||||
""" main """
|
||||
|
||||
fileNames = sys.argv[1:]
|
||||
outFileName = None
|
||||
|
||||
try:
|
||||
for name in fileNames:
|
||||
print("Processing: " + name)
|
||||
outFileName = name + "_NEW"
|
||||
editFile(name, outFileName)
|
||||
|
||||
# See if the file has changed. If it hasn't, keep the original
|
||||
# so the file dates don't change.
|
||||
if filecmp.cmp(name, outFileName, False):
|
||||
print("== No changes, removing new")
|
||||
os.remove(outFileName)
|
||||
else:
|
||||
print("== Changed, keeping new")
|
||||
os.rename(outFileName, name)
|
||||
except LocalError as err:
|
||||
print("ERROR: {0}".format(err))
|
||||
if outFileName:
|
||||
print(" check " + outFileName)
|
||||
sys.exit(1)
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
main() # does not return
|
@ -40,23 +40,25 @@ features one tool, the SourceGen disassembler.</p>
|
||||
<p><strong>SourceGen</strong> is an industrial-strength disassembler for 6502,
|
||||
65C02, and 65816 programs. It runs on Windows 7 or later.</p>
|
||||
|
||||
<p>Quick links:</p>
|
||||
<p>Demos and information:</p>
|
||||
<ul>
|
||||
<li>Watch a 9-minute
|
||||
<a href="https://youtu.be/dalISyBPQq8">product introduction video</a> (from v1.0).</li>
|
||||
<li>See an 8-minute
|
||||
<a href="https://youtu.be/lSvEr5nCHbY">demonstration of visualizers</a>
|
||||
in a disassembly of the Apple II game <i>Space Eggs</i>.</li>
|
||||
<li>Download source & binaries for the latest version
|
||||
<a href="https://github.com/fadden/6502bench/releases/">from the Releases page</a>.</li>
|
||||
<li>Check out the
|
||||
<a href="https://github.com/fadden/6502bench/">GitHub project</a>.</li>
|
||||
<li>SourceGen has been used to disassemble software for the Apple II,
|
||||
NES (Nintendo Entertainment System), Atari 2600 VCS, and coin-op arcade
|
||||
systems. Visit 6502disassembly.com to see some
|
||||
<a href="https://6502disassembly.com/">disassembly project examples</a>.</li>
|
||||
systems. Visit 6502disassembly.com to see examples of
|
||||
<a href="https://6502disassembly.com/">completed disassembly projects</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p>Check out the
|
||||
<a href="https://github.com/fadden/6502bench/">GitHub project</a>,
|
||||
where you can download source & binaries for the latest version from the
|
||||
<a href="https://github.com/fadden/6502bench/releases/">Releases page</a>.
|
||||
</p>
|
||||
|
||||
<p>Key features include:</p>
|
||||
<ul>
|
||||
<li>Fully interactive point-and-click GUI. Define labels, set addresses,
|
||||
@ -150,7 +152,7 @@ features one tool, the SourceGen disassembler.</p>
|
||||
</ul></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
<h4>Open Source</h4>
|
||||
|
||||
<p>6502bench is written in C# .NET, using the (free to download) Visual
|
||||
Studio Community 2019 IDE as the primary development environment.
|
||||
|
@ -32,14 +32,14 @@
|
||||
</div>
|
||||
|
||||
<div id="sidenav">
|
||||
<!-- START: /sidenav-incl.html active:#sidenav-about-disasm -->
|
||||
<!-- START: sidenav-incl.html active:#sidenav-about-disasm -->
|
||||
<script>
|
||||
// Load local sidenav content, and mark current page active.
|
||||
$("#sidenav").load("sidenav-incl.html", function() {
|
||||
$("#sidenav-about-disasm").addClass("active");
|
||||
});
|
||||
</script>
|
||||
<!-- END: /sidenav-incl.html -->
|
||||
<!-- END: sidenav-incl.html -->
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
|
@ -32,14 +32,14 @@
|
||||
</div>
|
||||
|
||||
<div id="sidenav">
|
||||
<!-- START: /sidenav-incl.html active:#sidenav-address-tables -->
|
||||
<!-- START: sidenav-incl.html active:#sidenav-address-tables -->
|
||||
<script>
|
||||
// Load local sidenav content, and mark current page active.
|
||||
$("#sidenav").load("sidenav-incl.html", function() {
|
||||
$("#sidenav-address-tables").addClass("active");
|
||||
});
|
||||
</script>
|
||||
<!-- END: /sidenav-incl.html -->
|
||||
<!-- END: sidenav-incl.html -->
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
|
@ -32,14 +32,14 @@
|
||||
</div>
|
||||
|
||||
<div id="sidenav">
|
||||
<!-- START: /sidenav-incl.html active:#sidenav-advanced-topics -->
|
||||
<!-- START: sidenav-incl.html active:#sidenav-advanced-topics -->
|
||||
<script>
|
||||
// Load local sidenav content, and mark current page active.
|
||||
$("#sidenav").load("sidenav-incl.html", function() {
|
||||
$("#sidenav-advanced-topics").addClass("active");
|
||||
});
|
||||
</script>
|
||||
<!-- END: /sidenav-incl.html -->
|
||||
<!-- END: sidenav-incl.html -->
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
|
@ -32,14 +32,14 @@
|
||||
</div>
|
||||
|
||||
<div id="sidenav">
|
||||
<!-- START: /sidenav-incl.html active:#sidenav-digging-deeper -->
|
||||
<!-- START: sidenav-incl.html active:#sidenav-digging-deeper -->
|
||||
<script>
|
||||
// Load local sidenav content, and mark current page active.
|
||||
$("#sidenav").load("sidenav-incl.html", function() {
|
||||
$("#sidenav-digging-deeper").addClass("active");
|
||||
});
|
||||
</script>
|
||||
<!-- END: /sidenav-incl.html -->
|
||||
<!-- END: sidenav-incl.html -->
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
|
@ -32,14 +32,14 @@
|
||||
</div>
|
||||
|
||||
<div id="sidenav">
|
||||
<!-- START: /sidenav-incl.html active:#sidenav-editing-data -->
|
||||
<!-- START: sidenav-incl.html active:#sidenav-editing-data -->
|
||||
<script>
|
||||
// Load local sidenav content, and mark current page active.
|
||||
$("#sidenav").load("sidenav-incl.html", function() {
|
||||
$("#sidenav-editing-data").addClass("active");
|
||||
});
|
||||
</script>
|
||||
<!-- END: /sidenav-incl.html -->
|
||||
<!-- END: sidenav-incl.html -->
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
|
@ -32,14 +32,14 @@
|
||||
</div>
|
||||
|
||||
<div id="sidenav">
|
||||
<!-- START: /sidenav-incl.html active:#sidenav-extension-scripts -->
|
||||
<!-- START: sidenav-incl.html active:#sidenav-extension-scripts -->
|
||||
<script>
|
||||
// Load local sidenav content, and mark current page active.
|
||||
$("#sidenav").load("sidenav-incl.html", function() {
|
||||
$("#sidenav-extension-scripts").addClass("active");
|
||||
});
|
||||
</script>
|
||||
<!-- END: /sidenav-incl.html -->
|
||||
<!-- END: sidenav-incl.html -->
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
|
@ -32,14 +32,14 @@
|
||||
</div>
|
||||
|
||||
<div id="sidenav">
|
||||
<!-- START: /sidenav-incl.html active:#sidenav-generating-code -->
|
||||
<!-- START: sidenav-incl.html active:#sidenav-generating-code -->
|
||||
<script>
|
||||
// Load local sidenav content, and mark current page active.
|
||||
$("#sidenav").load("sidenav-incl.html", function() {
|
||||
$("#sidenav-generating-code").addClass("active");
|
||||
});
|
||||
</script>
|
||||
<!-- END: /sidenav-incl.html -->
|
||||
<!-- END: sidenav-incl.html -->
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
|
@ -32,14 +32,14 @@
|
||||
</div>
|
||||
|
||||
<div id="sidenav">
|
||||
<!-- START: /sidenav-incl.html active:#sidenav-index -->
|
||||
<!-- START: sidenav-incl.html active:#sidenav-index -->
|
||||
<script>
|
||||
// Load local sidenav content, and mark current page active.
|
||||
$("#sidenav").load("sidenav-incl.html", function() {
|
||||
$("#sidenav-index").addClass("active");
|
||||
});
|
||||
</script>
|
||||
<!-- END: /sidenav-incl.html -->
|
||||
<!-- END: sidenav-incl.html -->
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
|
@ -32,14 +32,14 @@
|
||||
</div>
|
||||
|
||||
<div id="sidenav">
|
||||
<!-- START: /sidenav-incl.html active:#sidenav-inline-data -->
|
||||
<!-- START: sidenav-incl.html active:#sidenav-inline-data -->
|
||||
<script>
|
||||
// Load local sidenav content, and mark current page active.
|
||||
$("#sidenav").load("sidenav-incl.html", function() {
|
||||
$("#sidenav-inline-data").addClass("active");
|
||||
});
|
||||
</script>
|
||||
<!-- END: /sidenav-incl.html -->
|
||||
<!-- END: sidenav-incl.html -->
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
|
@ -32,14 +32,14 @@
|
||||
</div>
|
||||
|
||||
<div id="sidenav">
|
||||
<!-- START: /sidenav-incl.html active:#sidenav-labels-symbols -->
|
||||
<!-- START: sidenav-incl.html active:#sidenav-labels-symbols -->
|
||||
<script>
|
||||
// Load local sidenav content, and mark current page active.
|
||||
$("#sidenav").load("sidenav-incl.html", function() {
|
||||
$("#sidenav-labels-symbols").addClass("active");
|
||||
});
|
||||
</script>
|
||||
<!-- END: /sidenav-incl.html -->
|
||||
<!-- END: sidenav-incl.html -->
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
|
@ -32,14 +32,14 @@
|
||||
</div>
|
||||
|
||||
<div id="sidenav">
|
||||
<!-- START: /sidenav-incl.html active:#sidenav-local-variables -->
|
||||
<!-- START: sidenav-incl.html active:#sidenav-local-variables -->
|
||||
<script>
|
||||
// Load local sidenav content, and mark current page active.
|
||||
$("#sidenav").load("sidenav-incl.html", function() {
|
||||
$("#sidenav-local-variables").addClass("active");
|
||||
});
|
||||
</script>
|
||||
<!-- END: /sidenav-incl.html -->
|
||||
<!-- END: sidenav-incl.html -->
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
|
@ -32,14 +32,14 @@
|
||||
</div>
|
||||
|
||||
<div id="sidenav">
|
||||
<!-- START: /sidenav-incl.html active:#sidenav-starting-project -->
|
||||
<!-- START: sidenav-incl.html active:#sidenav-starting-project -->
|
||||
<script>
|
||||
// Load local sidenav content, and mark current page active.
|
||||
$("#sidenav").load("sidenav-incl.html", function() {
|
||||
$("#sidenav-moving-around").addClass("active");
|
||||
});
|
||||
</script>
|
||||
<!-- END: /sidenav-incl.html -->
|
||||
<!-- END: sidenav-incl.html -->
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
|
@ -32,14 +32,14 @@
|
||||
</div>
|
||||
|
||||
<div id="sidenav">
|
||||
<!-- START: /sidenav-incl.html active:#sidenav-odds-ends -->
|
||||
<!-- START: sidenav-incl.html active:#sidenav-odds-ends -->
|
||||
<script>
|
||||
// Load local sidenav content, and mark current page active.
|
||||
$("#sidenav").load("sidenav-incl.html", function() {
|
||||
$("#sidenav-odds-ends").addClass("active");
|
||||
});
|
||||
</script>
|
||||
<!-- END: /sidenav-incl.html -->
|
||||
<!-- END: sidenav-incl.html -->
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
|
@ -32,14 +32,14 @@
|
||||
</div>
|
||||
|
||||
<div id="sidenav">
|
||||
<!-- START: /sidenav-incl.html active:#sidenav-simple-edits -->
|
||||
<!-- START: sidenav-incl.html active:#sidenav-simple-edits -->
|
||||
<script>
|
||||
// Load local sidenav content, and mark current page active.
|
||||
$("#sidenav").load("sidenav-incl.html", function() {
|
||||
$("#sidenav-simple-edits").addClass("active");
|
||||
});
|
||||
</script>
|
||||
<!-- END: /sidenav-incl.html -->
|
||||
<!-- END: sidenav-incl.html -->
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
|
@ -32,14 +32,14 @@
|
||||
</div>
|
||||
|
||||
<div id="sidenav">
|
||||
<!-- START: /sidenav-incl.html active:#sidenav-string-formatting -->
|
||||
<!-- START: sidenav-incl.html active:#sidenav-string-formatting -->
|
||||
<script>
|
||||
// Load local sidenav content, and mark current page active.
|
||||
$("#sidenav").load("sidenav-incl.html", function() {
|
||||
$("#sidenav-string-formatting").addClass("active");
|
||||
});
|
||||
</script>
|
||||
<!-- END: /sidenav-incl.html -->
|
||||
<!-- END: sidenav-incl.html -->
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
|
@ -32,14 +32,14 @@
|
||||
</div>
|
||||
|
||||
<div id="sidenav">
|
||||
<!-- START: /sidenav-incl.html active:#sidenav-using-sourcegen -->
|
||||
<!-- START: sidenav-incl.html active:#sidenav-using-sourcegen -->
|
||||
<script>
|
||||
// Load local sidenav content, and mark current page active.
|
||||
$("#sidenav").load("sidenav-incl.html", function() {
|
||||
$("#sidenav-using-sourcegen").addClass("active");
|
||||
});
|
||||
</script>
|
||||
<!-- END: /sidenav-incl.html -->
|
||||
<!-- END: sidenav-incl.html -->
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
|
@ -32,14 +32,14 @@
|
||||
</div>
|
||||
|
||||
<div id="sidenav">
|
||||
<!-- START: /sidenav-incl.html active:#sidenav-visualizations -->
|
||||
<!-- START: sidenav-incl.html active:#sidenav-visualizations -->
|
||||
<script>
|
||||
// Load local sidenav content, and mark current page active.
|
||||
$("#sidenav").load("sidenav-incl.html", function() {
|
||||
$("#sidenav-visualizations").addClass("active");
|
||||
});
|
||||
</script>
|
||||
<!-- END: /sidenav-incl.html -->
|
||||
<!-- END: sidenav-incl.html -->
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
|
Loading…
Reference in New Issue
Block a user