#! py -3
"""
Extract code examples from TIJ4 Refreshed. Extracts from plain text file
"""
from pathlib import Path
import sys, os
import re
import argparse
import shutil
import pprint
destination = Path('.') / "ExtractedExamples"
sourceText = Path('.') / "TIJDirectorsCut.txt"
github = Path(r'C:\Users\Bruce\Documents\GitHub\TIJ-Directors-Cut')
startBuild = """\
"""
endBuild = """\
"""
parser = argparse.ArgumentParser()
parser.add_argument("-e", "--extract", action='store_true',
help="Extract examples from TIJDirectorsCut.txt")
parser.add_argument("-x", "--clean", action='store_true',
help="Remove ExtractedExamples directory")
parser.add_argument("-c", "--compare", action='store_true',
help="Compare files from Github repository to extracted examples")
parser.add_argument("-a", "--ant", action='store_true',
help="Copy ant build files from Github repository to extracted examples")
parser.add_argument("-m", "--makeant", action='store_true',
help="Make ant files that don't exist")
def extractExamples():
if not destination.exists():
destination.mkdir()
if not sourceText.exists():
print("Cannot find", sourceText)
sys.exit()
with sourceText.open("rb") as book:
text = book.read().decode("utf-8", "ignore")
for listing in re.findall("^//:.*?///:~", text, re.DOTALL | re.MULTILINE):
title = listing.splitlines()[0]
if "//: as a special marker" in title:
continue
title = title.split()[1]
print(title)
target = destination / Path(title)
if not target.parent.exists():
target.parent.mkdir(parents=True)
with target.open("w", newline='') as codeListing:
codeListing.writelines(listing)
def clean():
print("clean")
if destination.exists():
shutil.rmtree(str(destination))
def compareWithGithub():
leader = len(str(github)) + 1
githubfiles = [str(file)[leader:] for file in github.glob("**/*")]
githubfiles = [ghf for ghf in githubfiles if not ghf.startswith(".git")]
duplicates = { ghf for ghf in githubfiles if githubfiles.count(ghf) > 1 }
print("duplicates = ", duplicates)
leader2 = len(str(destination)) + 1
destfiles = [str(file)[leader2:] for file in destination.glob("**/*")]
duplicates = { ghf for ghf in destfiles if destfiles.count(ghf) > 1 }
print("duplicates = ", duplicates)
githubfiles = set(githubfiles)
destfiles = set(destfiles)
print("in githubfiles but not destfiles:")
for f in githubfiles.difference(destfiles):
print("\t", f)
print("#" * 80)
print("in destfiles but not githubfiles:")
for f in destfiles.difference(githubfiles):
print("\t", f)
def githubDirs():
leader = len(str(github)) + 1
buildfiles = [str(file)[leader:] for file in github.glob("**/build.xml")]
return {str((github / f).parent)[leader:] for f in buildfiles}
def destDirs(pattern="**"):
leader = len(str(destination)) + 1
return {str(file)[leader:] for file in destination.glob(pattern)}
def copyAntBuildFiles():
for common in githubDirs().intersection(destDirs()):
print("->", common)
build = github / common / "build.xml"
# print (str(build), build.exists())
target = destination / common
# print (str(target), target.exists())
shutil.copy(str(build), str(target))
shutil.copy(str(github / "Ant-Common.xml"), str(destination))
class CodeFile:
def __init__(self, javaFile):
with javaFile.open() as j:
self.code = j.read()
self.lines = self.code.splitlines()
self.main = None
if "public static void main" in self.code:
self.main = True
self.package = None
if "package " in self.code:
for line in self.lines:
if line.startswith("package ") and line.strip().endswith(";"):
self.package = line
break
self.tagLine = self.lines[0][4:]
self.relpath = '../' + '/'.join(self.tagLine.split('/')[:-1])
self.name = javaFile.name.split('.')[0]
def __repr__(self):
result = self.tagLine
if self.package:
result += "\n" + self.package
result += "\n"
return result
# return "\n".join(self.lines)
def packageName(self):
return self.package.split()[1][:-1]
def checkPackage(self):
if not self.package:
return True
path = '.'.join(self.tagLine.split('/')[:-1])
packagePath = self.packageName()
return path == packagePath
class Chapter:
def __init__(self, dir):
self.dir = dir
self.code_files = [CodeFile(javaFile) for javaFile in dir.glob("**/*.java")]
self.excludes = [cf.name + ".java" for cf in self.code_files if "{CompileTimeError}" in cf.code]
def __repr__(self):
result = "-" * 80
result += "\n" + str(self.dir) + "\n"
result += "-" * 80
result += "\n"
for cf in self.code_files:
result += str(cf.name) + "\n"
return result
def checkPackages(self):
for cf in self.code_files:
if not cf.checkPackage():
print("BAD PACKAGE")
print("\t", cf.tagLine)
print("\t", cf.package)
print("\n".join(cf.lines))
def makeBuildFile(self):
buildFile = startBuild % (self.dir.name, " ".join(self.excludes))
for cf in self.code_files:
if cf.name + ".java" in self.excludes:
continue
print(cf.name)
if cf.main:
if not cf.package:
buildFile += ' \n' % cf.name
else:
buildFile += ' \n' % (cf.packageName() + '.' + cf.name, cf.relpath)
buildFile += endBuild
# print(buildFile)
with (self.dir / "build.xml").open("w") as buildxml:
buildxml.write(buildFile)
def createAntFiles():
chapters = [Chapter(fd) for fd in destination.glob("*") if fd.is_dir() if not (fd / "build.xml").exists()]
# chapters = [Chapter(fd) for fd in destination.glob("*") if fd.is_dir()]
for chapter in chapters:
print(chapter)
chapter.checkPackages()
chapter.makeBuildFile()
def default():
clean()
extractExamples()
copyAntBuildFiles()
createAntFiles()
os.chdir("ExtractedExamples")
if __name__ == '__main__':
args = parser.parse_args()
if not any(vars(args).values()): default()
if args.extract:
extractExamples()
copyAntBuildFiles()
createAntFiles()
if args.compare:
compareWithGithub()
if args.ant:
copyAntBuildFiles()
if args.makeant:
createAntFiles()
if args.clean:
clean()