# Extending Coders An example of a custom coder to print images generate with python svgwrite. Examples taken from https://github.com/mozman/svgwrite/blob/master/examples/LSystem.py ```bash id=0447fd3d-adda-4fae-9c65-07579ca08ddb pip install svgwrite ``` ```python id=eb60bc4f-69cd-4811-976e-860977c23172 import svgwrite def write_svg(svg, path): with open(path, "w") as f: f.write(svg.tostring()) return {'kind': 'file', 'content-type': 'image/svg+xml'} register_coder("svg", lambda value: isinstance(value, svgwrite.Drawing), lambda value, path: write_svg(value, path)) ``` ```python id=425c7cb8-41a5-4cff-8952-93414d80690e import math import svgwrite LevyDragon = {'length':1, 'numAngle':4, 'level':16, 'init': 'FX', 'target': 'X', 'replacement': 'X+YF+', 'target2': 'Y', 'replacement2': '-FX-Y'} KochSnowflake = {'length':1, 'numAngle':6, 'level':6, 'init': 'F++F++F', 'target': 'F', 'replacement': 'F-F++F-F', 'target2': '', 'replacement2': ''} LevyCurve = {'length':1, 'numAngle':8, 'level':17, 'init': 'F', 'target': 'F', 'replacement': '+F--F+', 'target2': '', 'replacement2': ''} HilbertSpaceFillingCurve = {'length':1, 'numAngle':4, 'level':5, 'init': 'L', 'target': 'L', 'replacement': '+RF-LFL-FR+', 'target2': 'R', 'replacement2': '-LF+RFR+FL-'} def LSystem(name, formula=LevyCurve): ## {{{ http://code.activestate.com/recipes/577159/ (r1) # L-System Fractals # FB - 201003276 # image size # generate the fractal drawing string def _LSystem(formula): state = formula['init'] target = formula['target'] replacement = formula['replacement'] target2 = formula['target2'] replacement2 = formula['replacement2'] level = formula['level'] for counter in range(level): state2 = '' for character in state: if character == target: state2 += replacement elif character == target2: state2 += replacement2 else: state2 += character state = state2 return state print("creating: %s\n" % name) xmin, ymin = (100000, 100000) xmax, ymax = (-100000, -100000) numAngle = formula['numAngle'] length = formula['length'] fractal = _LSystem(formula) na = 2.0 * math.pi / numAngle sn = [] cs = [] for i in range(numAngle): sn.append(math.sin(na * i)) cs.append(math.cos(na * i)) x = 0.0 y = 0.0 # jx = int((x - xa) / (xb - xa) * (imgx - 1)) # jy = int((y - ya) / (yb - ya) * (imgy - 1)) k = 0 dwg = svgwrite.Drawing(name, debug=True) curve = dwg.polyline(points=[(x, y)], stroke='black', fill='none', stroke_width=0.1) for ch in fractal: if ch == 'F': # turtle forward(length) x += length * cs[k] y += length * sn[k] curve.points.append( (x, y) ) # find maxima xmin = min(xmin, x) xmax = max(xmax, x) ymin = min(ymin, y) ymax = max(ymax, y) elif ch == '+': # turtle right(angle) k = (k + 1) % numAngle elif ch == '-': # turtle left(angle) k = ((k - 1) + numAngle) % numAngle print("L-System with %d segements.\n" % (len(curve.points)-1)) dwg.viewbox(xmin, ymin, xmax-xmin, ymax-ymin) dwg.add(curve) return dwg # LSystem('hilbert.svg', formula=HilbertSpaceFillingCurve) # LSystem('lsys_levydragon.svg', formula=LevyDragon) LSystem('lsys_levycurve.svg', formula=LevyCurve) # LSystem('lsys_kochsnowflake.svg', formula=KochSnowflake) ```
This notebook was exported from https://nextjournal.com/a/CDoRsRsJzsFLBNbL3FeoUy?change-id=CDpppsnHJtzLz6etHTHJCp ```edn nextjournal-metadata {:article {:settings nil, :nodes {"0447fd3d-adda-4fae-9c65-07579ca08ddb" {:compute-ref #uuid "4c857330-479a-11e8-8106-e3215b1a3e29", :exec-duration 1134, :id "0447fd3d-adda-4fae-9c65-07579ca08ddb", :kind "code", :name "polished-grass", :output-log-lines {:stdout 6}, :runtime [:runtime "65d2af85-1f85-49ac-8b97-a83ba6eb8305"]}, "425c7cb8-41a5-4cff-8952-93414d80690e" {:compute-ref #uuid "7d4b4260-479a-11e8-8106-e3215b1a3e29", :exec-duration 1977, :id "425c7cb8-41a5-4cff-8952-93414d80690e", :kind "code", :name "ancient-bar", :runtime [:runtime "65d2af85-1f85-49ac-8b97-a83ba6eb8305"]}, "65d2af85-1f85-49ac-8b97-a83ba6eb8305" {:environment [:environment {:node/id "b4280fd7-fcf3-4240-98da-1f57674266f0", :article/nextjournal.id #uuid "5accb601-b16a-4637-ae55-5fd73544a52f", :change/nextjournal.id #uuid "5acdc9f3-9c8e-49c5-8e42-1877c6439787"}], :id "65d2af85-1f85-49ac-8b97-a83ba6eb8305", :kind "runtime", :language "python", :name "SVG Runtime", :type :nextjournal}, "eb60bc4f-69cd-4811-976e-860977c23172" {:compute-ref #uuid "4f02a830-479a-11e8-8106-e3215b1a3e29", :exec-duration 2439, :id "eb60bc4f-69cd-4811-976e-860977c23172", :kind "code", :name "wandering-scene", :runtime [:runtime "65d2af85-1f85-49ac-8b97-a83ba6eb8305"]}}, :nextjournal/id #uuid "5ade1031-72fc-4cac-b0a9-07a70aba3d76", :article/change {:nextjournal/id #uuid "5adeec66-b82c-48c4-9470-d24447b96871"}}} ```