diff --git a/css/main.css b/css/main.css
index a48f6095f614a88e3cd0db6091af91acf073c1be..e5269214064f15619b11f1d4c7ca3e05c5dd51fb 100644
--- a/css/main.css
+++ b/css/main.css
@@ -408,6 +408,7 @@ label {
 .CodeMirror {
     opacity: 0.6;
     margin: 0 20px 0 -10px;
+    font-size: 10pt;
 }
 
 .editComposite, .editMaterial {
diff --git a/js/cam/assemblers/AssemblerPost.js b/js/cam/assemblers/AssemblerPost.js
index 869c4c55f32fff8a94ac1145989d8d274548a1d4..fa566f5328642ce4ecee5855f739cc5c1f4de9d0 100644
--- a/js/cam/assemblers/AssemblerPost.js
+++ b/js/cam/assemblers/AssemblerPost.js
@@ -101,6 +101,33 @@ define(['underscore', 'appState', 'lattice', 'cam'], function(_, appState, latti
     data += exporter.rapidZ(position.z + context.zClearHeight, settings);
     return data;
 };
+
+        this.customCalcPositionOffsets = function(index, position, material, settings, context){
+    //this feeds into moveXY and placePart's position parameter
+
+    if (index.z%2 != 0){
+        //offset for rotation
+        var offset = this.components.substrate.centerOfRotation.clone().multiplyScalar(settings.scale);//offset in mm
+        var dist = position.clone().sub(offset);
+        position = offset.add(new THREE.Vector3(dist.y, -dist.x, position.z));
+    }
+
+    var stock = _.find(this.stock, function(thisStock){
+        return thisStock.getMaterial() == material
+    });
+    if (stock === undefined) {
+        console.warn("no stock defined of type " + material + " for this assembler");
+        return null;
+    }
+
+    position.sub(stock.getPosition().multiplyScalar(settings.scale));
+    position.sub(settings.originPosition);
+
+    return position;
+}
+
+
+
     }
 
 
@@ -199,23 +226,8 @@ define(['underscore', 'appState', 'lattice', 'cam'], function(_, appState, latti
 
 
 //        position.add(new THREE.Vector3(18.23*((index.z)%2), 0.3*((index.z)%2), 0));
-        if (index.z%2 != 0){
-            //offset for rotation
-            var offset = this.components.substrate.centerOfRotation.clone().multiplyScalar(settings.scale);//offset in mm
-            var dist = position.clone().sub(offset);
-            position = offset.add(new THREE.Vector3(dist.y, -dist.x, position.z));
-        }
-
-        var stock = _.find(this.stock, function(thisStock){
-            return thisStock.getMaterial() == material
-        });
-        if (stock === undefined) {
-            console.warn("no stock defined of type " + material + " for this assembler");
-            return data;
-        }
-        position.sub(stock.getPosition().multiplyScalar(settings.scale));
-        position.sub(settings.originPosition);
-
+        var position = this.customCalcPositionOffsets(index, position, material, settings, context);
+        if (position === null) return data;
 
 
 //        (5.08mm, 5.715mm)
diff --git a/js/menus/templates/AssemblerSetupMenuView.html b/js/menus/templates/AssemblerSetupMenuView.html
index 5c87c19b0fe9d55588ad04fed06fc2bfbd7ce5a1..3e0fdecc0be713cb8b92c74bc00005692d972d37 100644
--- a/js/menus/templates/AssemblerSetupMenuView.html
+++ b/js/menus/templates/AssemblerSetupMenuView.html
@@ -19,6 +19,7 @@ Rotation (xyz):  
 Scale: &nbsp;&nbsp;<input data-property="scale" value="<%= scale %>" placeholder="Scale" class="form-control floatInput assembler" type="text"><br/><br/>
 Edit Code:<br/><br/>
 Context Variables  <a class="editMachineCode" data-name="customFunctionsContext" href="#">Edit</a><br/>
+Position Offsets <a class="editMachineCode" data-name="customCalcPositionOffsets" href="#">Edit</a><br/>
 Header  <a class="editMachineCode" data-name="customHeader" href="#">Edit</a><br/>
 Go Home <a class="editMachineCode" data-name="customHome" href="#">Edit</a><br/>
 <!--Pick up stock <a class="editMachineCode" data-name="customHeader" href="#">Edit</a><br/>-->