rewrote in python

This commit is contained in:
rusty-bits
2023-01-27 21:58:55 -05:00
parent 0ab7143c1d
commit 9b1ca614a7
3 changed files with 360 additions and 77 deletions
+343
View File
@@ -0,0 +1,343 @@
import os, sys
import tkinter as tk
def display_info_window(config_tex, search_list, width, valid_only, show_urls):
# probably a simpler way to set up the formatted text
# but found this format online and it works for now
class FormattedText(tk.Text):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
from tkinter import font as tkFont
default_font = tkFont.nametofont(self.cget("font"))
bold_font = tkFont.Font(**default_font.configure())
italic_font = tkFont.Font(**default_font.configure())
normal_font = tkFont.Font(**default_font.configure())
underline_font = tkFont.Font(**default_font.configure())
bold_font.configure(weight="bold")
italic_font.configure(slant="italic")
underline_font.configure(underline=1)
normal_font.configure(weight="normal", slant="roman")
self.tag_configure("bold", font=bold_font)
self.tag_configure("italic", font=italic_font)
self.tag_configure("underline", font=underline_font)
self.tag_configure("normal", font=normal_font)
self.tag_configure(
"inverse", background="white", foreground="black")
result = parse_configuration_tex(config_tex, search_list, width, valid_only, show_urls)
info_window = tk.Toplevel()
info_window.title(" > ".join(search_list)) # set title to search path
info_win_height = len(result) + 1 # size info_window to the search result
if info_win_height > 40:
info_win_height = 40
text = FormattedText(info_window, width=width, height=info_win_height)
text.pack(fill="both", expand=True)
# very basic error checking and display
# length of zero means no result was found
# length of one is an error message
if len(result) == 0:
text.insert("end", "no info found for: ", "bold")
text.insert("end", search_list, "bold")
return
if len(result) == 1:
text.insert("end", result[0], "inverse")
return
style = "normal"
in_escape = False
for line in result:
out = "" # build output string between esc seq one char at a time
for c in line:
# quick hack to decode the escape seqs ret from the parse
# can improve this
if in_escape:
if c == '0':
style = "normal"
if c == '1':
style = "bold"
if c == '3':
style = "italic"
if c == '4':
style = "underline"
if c == '7':
style = "inverse"
if c == 'm':
out = ""
in_escape = False
continue
if c == '\x1b':
# found end of one esc and start of another
# dump formatted output to window
# and start over
text.insert("end", out, style)
out = ""
in_escape = True
continue
out += c
text.insert("end", out, style) # reached end of line, dump out to window
def parse_configuration_tex(config_file, search_list, width, valid_only, show_urls):
try:
config = open(config_file, "r")
except OSError:
return ["Could not find/open Configuration.tex at " + config_file]
result = []
align = False
sub_search = "\\subsection{"
match len(search_list) - 1:
case 0:
pass
case 1:
sub_search += "Properties"
case 2 | 3:
match search_list[0]:
case "NVRAM":
sub_search += "Introduction"
case "DeviceProperties":
sub_search += "Common"
case "Misc":
if len(search_list) < 4:
sub_search += search_list[1]
sub_search += " Properties"
else:
sub_search += "Entry Properties"
case _:
sub_search += search_list[1]
sub_search += " Properties"
case _:
return result
sec_search = "\\section{"
sec_search += search_list[0]
while True:
line = config.readline()
if not line:
return result
if sec_search in line:
break
if len(search_list) != 1:
while True:
line = config.readline()
if not line:
return result
if sub_search in line:
break
text_search = "texttt{"
if search_list[0] == "NVRAM" and len(search_list) > 2:
text_search += search_list[2]
if len(search_list) == 4:
text_search += ":"
text_search += search_list[3]
elif search_list[0] == "DeviceProperties" and len(search_list) == 4:
text_search += search_list[3]
else:
text_search += search_list[len(search_list) - 1]
text_search += "}\\"
while True:
line = config.readline()
if not line:
return result
if text_search in line:
break
itemize = 0
enum = 0
columns = 0
lines_between_valid = 0
while True:
line = config.readline()
if not line:
break
if "\\subsection{Introduction}" in line:
continue
if "\\begin{tabular}" in line:
for c in line:
if c == "c":
columns += 1
continue
if "\\begin(align*}" in line:
align = True
continue
if "\\end{align*}}" in line:
align = False
continue
if "\\begin{itemize}" in line:
itemize += 1
continue
if "\\begin{enumerate}" in line:
enum += 1
continue
if "\\mbox" in line:
continue
if "\\end{tabular}" in line:
columns = 0
continue
if "\\end{itemize}" in line:
itemize -= 1
continue
if "\\end{enumerate}" in line:
enum -= 1
continue
if "\\end{" in line:
continue
if "\\item" in line and ( itemize == 0 and enum == 0 ):
break
if "\\subsection{" in line or "\\section{" in line:
break
parsed_line = parse_line(line, columns, width, align, valid_only, show_urls)
if valid_only:
if itemize > 0:
if "---" in line:
if lines_between_valid < 10:
result.append(parsed_line)
else:
if len(result) > 0:
lines_between_valid += 1
else:
if len(parsed_line) != 0:
result.append(parsed_line)
return result
def parse_line(line, columns, width, align, valid_only, show_urls):
ret = ""
build_key = False
key = ""
col_width = 0
if columns > 0:
col_width = int(width / ( columns + 1 ))
ignore = False
col_contents_len = 0
line = line.rstrip()
for c in line:
if build_key:
match c:
case c if c in "{[":
build_key = False
if not valid_only:
match key:
case "text":
ret += "\x1b[0m"
case "textit":
ret += "\x1b[3m"
case "textbf":
ret += "\x1b[1m"
case "emph":
ret += "\x1b[7m"
case "texttt":
ret += "\x1b[4m"
case "href":
if show_urls:
ret += "\x1b[34m"
else:
ignore = True
case _:
ignore = True
if key != "href":
key = ""
case c if c in " ,()\\0123456789$&":
build_key = False
if key == "item":
if not valid_only:
ret += ""
ret += special_char(key)
col_contents_len += 1
if c in ",()0123456789$":
ret += c
if c == "\\":
if len(key) > 0:
build_key = True
key = ""
case c if c in "_^#":
build_key = False
ret += c
col_contents_len += 1
key = ""
case _:
key += c
else:
match c:
case "\\":
build_key = True
case c if c in "}]":
if not ignore:
if not valid_only:
ret += "\x1b[0m"
if key == "href":
ret += " "
key = ""
elif c == "]":
ret += "]"
ignore = False
case "{":
if not valid_only:
ret += "\x1b[4m"
case "&":
if columns > 0:
pad = col_width - col_contents_len - 1
if pad > 0:
for _ in range(pad):
ret += " "
col_contents_len = 0
ret += "|"
else:
if not align:
ret += "&"
case _:
if not ignore:
ret += c
col_contents_len += 1
if len(key) > 0:
ret += special_char(key)
if not valid_only:
if key == "tightlint":
ret = ""
else:
if key == "hline":
ret = ""
for _ in range(width - 4):
ret += "-"
ret += "\n"
return ret
def special_char(key):
match key:
case "kappa":
return "\u03f0"
case "lambda":
return "\u03bb"
case "mu":
return "\u03bc"
case "alpha":
return "\u03b1"
case "beta":
return "\u03b2"
case "gamma":
return "\u03b3"
case "leq":
return "\u2264"
case "cdot":
return "\u00b7"
case "in":
return "\u220a"
case "infty":
return "\u221e"
case "textbackslash":
return "\\"
case "hline":
return "\u200b"
case _:
return " "
+17 -77
View File
@@ -1,7 +1,9 @@
#!/usr/bin/env python
import sys, os, plistlib, base64, binascii, datetime, tempfile, shutil, re, subprocess, math, hashlib
import rbits
from collections import OrderedDict
from Scripts import config_tex_info
try:
# Python 2
import Tkinter as tk
@@ -391,7 +393,7 @@ class PlistWindow(tk.Toplevel):
self.bind("<{}-f>".format(key), self.hide_show_find)
self.bind("<{}-p>".format(key), self.hide_show_type)
# Add rbits binding
self.bind("<{}-i>".format(key), self.parse_tex)
self.bind("<{}-i>".format(key), self.show_config_info)
# Add the treeview bindings
self._tree.bind("<{}-c>".format(key), self.copy_selection)
self._tree.bind("<{}-C>".format(key), self.copy_all)
@@ -2954,7 +2956,7 @@ class PlistWindow(tk.Toplevel):
popup_menu.add_command(label="Paste{}".format(" (Cmd+V)" if is_mac else ""),command=self.paste_selection,state=p_state,accelerator=None if is_mac else "(Ctrl+V)")
# Add rbits option
popup_menu.add_command(label="Show Info{}".format(
" (Cmd+I)" if is_mac else ""), command=self.parse_tex if is_mac else "(Ctrl+C)")
" (Cmd+I)" if is_mac else ""), command=self.show_config_info if is_mac else "(Ctrl+C)")
# Walk through the menu data if it exists
cell_path = self.get_cell_path(cell)
@@ -3205,80 +3207,18 @@ class PlistWindow(tk.Toplevel):
tags.append("odd" if x % 2 else "even")
self._tree.item(item, tags=tags)
def parse_tex(self, event=None):
# probably a simpler way to set up the formatted text
# but found this format online and it works for now
class FormattedText(tk.Text):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
from tkinter import font as tkFont
default_font = tkFont.nametofont(self.cget("font"))
bold_font = tkFont.Font(**default_font.configure())
italic_font = tkFont.Font(**default_font.configure())
normal_font = tkFont.Font(**default_font.configure())
underline_font = tkFont.Font(**default_font.configure())
bold_font.configure(weight="bold")
italic_font.configure(slant="italic")
underline_font.configure(underline=1)
normal_font.configure(weight="normal", slant="roman")
self.tag_configure("bold", font=bold_font)
self.tag_configure("italic", font=italic_font)
self.tag_configure("underline", font=underline_font)
self.tag_configure("normal", font=normal_font)
self.tag_configure(
"inverse", background="white", foreground="black")
def show_config_info(self, event=None):
# find the path of selected cell
cell = "" if not len(self._tree.selection()) else self._tree.selection()[0]
cell_p = self.split(self.get_cell_path(cell))
cell_p.pop(0) # remove root
if len(cell_p) == 0 or cell_p[-1] == "*": # nothing to search for
search_list = self.split(self.get_cell_path(cell))
search_list.pop(0) # remove root
if len(search_list) == 0 or search_list[-1] == "*": # nothing to search for
return
# get path to Configuration.tex in root dir
# but will need path to tex based on version of plist to work "properly"
conf_path = os.path.abspath(os.getcwd()) + "/Configuration.tex"
result = rbits.parse_config_tex(conf_path, cell_p, 120, False, False)
info_win_height = len(result)+1 # size info_window to the search result
if info_win_height > 40:
info_win_height = 40
info_window = tk.Toplevel()
info_window.title(" > ".join(cell_p)) # set title to search path
text = FormattedText(info_window, width=120, height=info_win_height)
text.pack(fill="both", expand=True)
style = "normal"
in_escape = False
for line in result:
out = "" # build output string between esc seq one char at a time
for c in line:
# quick hack to decode the escape seqs ret from the parse
# can improve this
if in_escape:
if c == '0':
style = "normal"
if c == '1':
style = "bold"
if c == '3':
style = "italic"
if c == '4':
style = "underline"
if c == '7':
style = "inverse"
if c == 'm':
out = ""
in_escape = False
continue
if c == '\x1b':
# found end of one esc and start of another
# dump formatted output to window
# and start over
text.insert("end", out, style)
out = ""
in_escape = True
continue
out += c
text.insert("end", out, style) # reached end of line, dump out to window
# will need path to a Configuration.tex based for the version of OpenCore being used
# for this to provide the correct info
# for now this is a cheap hack to a Configuration.tex in the same location as ProperTree
prop_tree_path = sys.path[0]
if ".app" in prop_tree_path:
prop_tree_path = prop_tree_path[:-30]
config_tex_path = os.path.join(prop_tree_path, "Configuration.tex")
config_tex_info.display_info_window(config_tex_path, search_list, 120, False, False)
BIN
View File
Binary file not shown.