However, it's possible for anyone with a LifeWiki trusted flag to add a rule with a @TREE section to the Rules: namespace. After a refresh, LifeViewer will start working on patterns with that rule name in the header. I'm not absolutely sure that there won't be some weird effect with cases like the ^ character in "ExtendedLife^2", but I think it will work fine -- might be worth trying.
Here's how it works in detail:
1) Save the following RuleTableToTree-hacked.py to the same subfolder in Golly as the regular RuleTableToTree (/Scripts/Python/RuleGenerators/).
EDIT: altered line 23 in a way that hopefully will be more tolerant of different OSes:
Code: Select all
# RuleTableToTree-hacked.py, version 1.1
# modified version of RuleTableToTree.py,
# intended to create a version of any @TABLE .rule file that can be copied
# directly into the LifeWiki Rule: namespace for LifeViewer to use
# This involves adding a @TREE section that contains an equivalent encoding of the @TABLE section
# TODO: add warning message if the @TREE section is so big that LifeViewer won't be able to handle it?
import golly
import os
from glife.ReadRuleTable import *
from glife.RuleTree import *
from glife.EmulateTriangular import *
from glife.EmulateMargolus import *
from glife.EmulateOneDimensional import *
from glife.EmulateHexagonal import *
rulesource="The selected rule"
s = golly.getclipstr()
if s[:5]=="@RULE":
# create a temporary file and set rulefilename to that
firstline = s.split("\n")[0]
rulefilename = golly.getdir("temp") + firstline.split(" ")[1].replace("\r","").replace("\n","") + ".rule"
with open(rulefilename, "w") as f0:
f0.write(s)
rulesource = "The rule in the clipboard"
else:
# ask user to select .rule file
rulefilename = golly.opendialog('Open a rule table file, to add a @TREE section:', 'Rule files (*.rule)|*.rule')
if len(rulefilename) == 0: golly.exit() # user hit Cancel
with open(rulefilename,"r") as f:
rulelines = f.readlines()
# golly.note(str(rulelines))
filename = rulefilename.replace(".rule",".table")
if rulefilename == filename:
g.note("This script only works with saved files called *.rule\n-- otherwise things get too confusing.")
g.exit()
with open(filename,"w") as f1:
export = 0
for line in rulelines:
if line[:5] == "@TREE":
golly.note(rulesource + " already has a @TREE section. Nothing to do here.")
golly.exit()
if export != 1:
if line[:6] == "@TABLE":
export = 1
else:
if line[:1] == "@":
export = 2
else:
f1.write(line)
# DMG: now the .table section (only) has been written to a separate file in the same folder,
# and this hacked script can proceed in the same way as the original RuleTableToTree.py
# add new converters here as they become available:
Converters = {
"vonNeumann":ConvertRuleTableTransitionsToRuleTree,
"Moore":ConvertRuleTableTransitionsToRuleTree,
"triangularVonNeumann":EmulateTriangular,
"triangularMoore":EmulateTriangular,
"Margolus":EmulateMargolus,
"square4_figure8v":EmulateMargolus,
"square4_figure8h":EmulateMargolus,
"square4_cyclic":EmulateMargolus,
"oneDimensional":EmulateOneDimensional,
"hexagonal":EmulateHexagonal,
}
golly.show("Reading from rule table file...")
n_states, neighborhood, transitions = ReadRuleTable(filename)
if not neighborhood in Converters:
golly.warn("Unsupported neighborhood: "+neighborhood)
golly.show('')
golly.exit()
# all converters now create a .rule file
golly.show("Building rule...")
rule_name = Converters[neighborhood]( neighborhood,
n_states,
transitions,
filename )
golly.new(rule_name+'-demo.rle')
golly.setalgo('RuleLoader')
golly.show("Created rule " + rule_name + ".")
# now go find the rule just created
newrulefilename = golly.getdir('rules')+rule_name+".rule"
with open(newrulefilename,"r") as f2:
treelines = f2.readlines()
# rewrite the rule file to include a @TABLE as well as a @TREE section
with open(newrulefilename,"w") as f3:
wrotetree = 0
for line in rulelines:
if wrotetree == 0 and (line[:7] == "@COLORS" or line[:6] == "@ICONS"):
foundtree = 0
for treeline in treelines:
if treeline[:5] == "@TREE":
foundtree=1
if foundtree==1:
f3.write(treeline)
wrotetree = 1
if wrotetree == 0: # @TREE version of file will include @COLORS and @ICONS if they're there,
f3.write(line) # so no reason to write that out twice
with open(newrulefilename,"r") as f4:
golly.setclipstr(f4.read())
golly.setrule(rule_name)
golly.show('Created '+rule_name+'.rule and selected that rule.')
3) Run the RuleTableToTree-hacked.py script. You'll end up with a copy of the rule with both @TABLE and @TREE sections installed in Golly's Rules folder, and also copied to your clipboard.
4) Navigate to https://conwaylife.com/wiki/Rule:{your_rulename_here}. Be careful to get the capitalization right. If different variations of capitalization are used after the first letter in the rule name, you'll have to add redirects to get LifeViewer to find the right article.
5) Create the article, paste the contents of the clipboard into it, and save.
After a refresh, LifeViewer should pick up the new @TREE definition and will be able to simulate the rule in-browser.
Handle with Care
Quite possibly some interesting problems or exceptions will show up as this feature gets more use. I wouldn't necessarily advise trying this on a rule table with a huge number of states or transitions, like QuadrupleB3S23 or 1x2Life. When permute symmetry is set as it often is, the @TREE text can end up being much much longer than the @TABLE text, and eventually the LifeWiki server might start having trouble serving up such huge volumes of text -- caching or no caching.
For example, it might be worth keeping an eye out for threads where it takes a very long time for the "Show in Viewer" links to appear, the first time the page is loaded. (?)
EDIT: An interesting detail showed up when I tried converting Foodshapeloop to @TREE form. First, it took fifteen or twenty minutes to complete the conversion, and the resulting file was 119MB. So this is an example of a rule that might be beyond what can reasonably be stored in the Rule: namespace on the LifeWiki: my impression is that you start to get some strange partial-load results when articles get too long. There's a new feature of LifeViewer as of build 453 where you don't have to get rule-tree information from the LifeWiki --
-- so maybe a next step would be to experiment with foodshapeloop locally and see just how painful it is for LifeViewer to load a 119MB rule tree.rowett wrote: Build 453 is now available... Enhancements in this build:
- the location of the rule Repository can be overriden with the <meta> tag on the web page hosting the Viewer
- <meta name="LifeViewer" content="/myrepository/rules/">
- an entry beginning with a "/" is used to define the location
Second, a couple of the variable definition lines were written as "Var ..." instead of "var ..." Until I changed those V's to lowercase, the script gave a mysterious "wrong number" error: it was trying to read it as a regular rule table line, and therefore expected to see ten items (start state, neighbors, end state).
EDIT2: Another oddity I haven't tracked down is that the output foodshapeloop rule file (119MB) or the output shapeloop3 rule file (10MB) for some reason don't get a @COLORS section at the end. They should. So I'm not sure if the input rule file is actually getting processed completely, or if there's a bug in my hacked version. It's possible that the complete @TREE isn't actually getting created -- have to check against the output of the original RuleTableToTree.py.