summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/cartonaugh/cartonaugh.lua
blob: d0f44debfdea7ebf6d72a8d2c5a80b3f696becd4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
DEBUG_FLAG = 0

CARTONAUGH_COLORS = {'red', 'green', 'yellow', 'cyan', 'blue', 'magenta'}
CARTONAUGH_DEFAULT_COLOR = 'cyan'

cartonaugh_env_settings = {}
used_cells = {}

-- Function that is used to either print to LaTeX or to the console
-- Used for debugging mode
function localPrint(str)
    if DEBUG_FLAG==1 then
        print(str)
    end
    tex.sprint(str)
end

-- Function that takes a string and splits it be delimiter, then returns it back
-- From https://stackoverflow.com/questions/19262761/lua-need-to-split-at-comma
function split(source, delimiters)
    local elements = {}
    local pattern = '([^'..delimiters..']+)'
    string.gsub(source, pattern, function(value) elements[#elements + 1] = value;  end);
    return elements
end

-- Function that converts a decimal number to binary
function decimalToBin(num, numb_bits, return_concat)
    if return_concat == nil then return_concat=true end
    num = tonumber(num)
    numb_bits = tonumber(numb_bits)
    local t={}
    for b=numb_bits,1,-1 do
        rest=math.floor(math.fmod(num,2))
        t[b]=rest
        num=(num-rest)/2
    end
    if return_concat == true then
        return table.concat(t)
    else
        return t
    end
end

-- Function that converts a decimal number to grey code
function decimalToGreyBin(num, numb_bits)
    -- Get the binary array
    num = num ~ (num >> 1)
    local t = decimalToBin(num, numb_bits, false)
    return table.concat(t)
end

function greyBinToDecimal(num)
--     num = tonumber(num,2)
    local mask = num
    while mask > 0 do
        mask = mask >> 1
        num = num ~ mask
    end
    return tonumber(num)
end

-- Function to pad a string by a amount with b string
function padString(str, pad_to, pad_with)
    local ret = str
    for l=1, (pad_to-string.len(str)) do
        ret = pad_with .. ret
    end
    return ret
end

function getColor(index)
    if index <= 0 then return CARTONAUGH_DEFAULT_COLOR end
    if CARTONAUGH_COLORS[index] ~= nil then
        return CARTONAUGH_COLORS[index]
    else
        return CARTONAUGH_DEFAULT_COLOR
    end
end

function customColor(color)
    -- Some high number so it's not in the CARTONAUGH_COLORS array
    cartonaugh_env_settings.color_index = 100
    CARTONAUGH_DEFAULT_COLOR = color
end

-- Function to generate a kmap template
function generateKMap(column, row, grid_numb)
    local outside_column_bits = 1
    local outside_row_bits = 1
    local outside_grid_numb_bits = 2
    local return_str = ''
    if row >= 4 then
        outside_row_bits = 2
    end
    if column >= 4 then
        outside_column_bits = 2
    end
    for c=1,column,1 do
        for r=1,row,1 do
            if r == 0 then
                if c == 0 then
                    -- Do Nothing...
                elseif c == (column+1) then
                    return_str = return_str .. ("\\phantom{" .. decimalToBin(0, outside_column_bits) .. "}")
                else
                    return_str = return_str .. (decimalToGreyBin(c-1, outside_column_bits))
                end
            elseif r==(row+1) then
                if c==0 then
                    return_str = return_str .. ("\\phantom{" .. decimalToBin(0, outside_column_bits) .. "}")
                end
            else
                if c == 0 then
                    return_str = return_str .. (decimalToGreyBin(r-1, outside_row_bits))
                elseif c == (column+1) then

                else
                    return_str = return_str ..("|(" .. padString((decimalToGreyBin(grid_numb, outside_grid_numb_bits) .. decimalToGreyBin(c-1, outside_column_bits) .. decimalToGreyBin(r-1, outside_row_bits)), 6, 0) ..  ")|" .. "\\phantom{0}")
                    --TODO: Look into why reversing c and r from where they should be makes it work
                end
            end

            if r == (row) then
                return_str = return_str .. ("\\\\")
            else
                return_str = return_str .. ("\\&")
            end
        end
    end
    return return_str
end

function init_cartonaught_env(numb_cols, numb_row, numb_submaps, is_bw, var12_str, var34_str, var56_str, is_submap_seperated)
    -- Change the default texts depending on the number of submaps if not custom name has been given
    -- TODO: Get this to actually work
    if var12_str == 'X_1X_0' and var34_str == 'X_3X_2' and var56_str == 'X_5X_4' then
        if numb_submaps == 1 then
            var56_str = 'X_3'
        end
        if numb_cols == 1 then
            var12_str = 'X_0'
        end
    end
    cartonaugh_env_settings = {
        cols = numb_cols,
        rows = numb_row,
        submaps = numb_submaps,
        bw = tonumber(is_bw),
        var_string = {
                v12 = var12_str,
                v34 = var34_str,
                v56 = var56_str,
        },
        color_index = 1,
        implicant_settings = {
            inner_sep = 0.35,
            outer_sep = 0.55,
        }
    }
    used_cells = {}

    if is_submap_seperated == 0 then
        is_submap_seperated = false
    else
        is_submap_seperated = true
    end

    draw_pgf_kmap(numb_cols, numb_row, numb_submaps, var12_str, var34_str, var56_str, is_submap_seperated)
end

function change_implicant_inner_spread(new_amount)
    cartonaugh_env_settings.implicant_settings.inner_sep = new_amount
end

function change_implicant_outer_spread(new_amount)
    cartonaugh_env_settings.implicant_settings.outer_sep = new_amount
end

-- Function to generate the k-maps
-- NOTE: Each variable/cell in the k-map is 1cm. This is so that everything alings with each other just be adding
-- the number of row and column. It's a bit of hack, but for now it will stay this way. Resizing of the matrix
-- will be done with the scale option in the future
function draw_pgf_kmap(column, row, submaps_n, var1, var2, var3, is_submap_seperated)
    submaps_n = submaps_n-1
    -- TODO: Transform the following settings variables into arguments
    local is_multitable_seperated = is_submap_seperated    -- Setting to determine if the graphs are drawn with a sperator line or distanced out
    local graph_seperator = 1.5                -- Seperation lenght between kmaps if is_multitable_seperated=false
    local kmaplevel_seperator_lenght = 0.1   -- Setting to determine the seperator line's thickness if is_multitable_seperated=true
    local line_width = 0.015                 -- Set the line thickness of things here
    local zero_var_line_lenght = 0.75         -- The lenght of the line at the top-left corner of the kmap where the implacants reside
    local column_header_numb_bits = ((column-1) // 2)+1
    local row_header_numb_bits = ((row-1) // 2)+1
    if is_multitable_seperated then graph_seperator = 0 end
    for d=0,submaps_n,1 do
        -- Find the top-left corner of each grid (seperated by 1 unit)
        local grid_x_loc = (d % 2)*(column+graph_seperator)
        local grid_y_loc = -(d // 2)*(row+graph_seperator)
    --         localPrint(string.format("\\node[above] at (%f,%f) {\\small{%s}};", 0, 0, abimplecant))
        if is_multitable_seperated then
            if (d % 2) == 1 then
                local add_heigh = 0
                if d >= 2 then add_heigh = kmaplevel_seperator_lenght end
                localPrint(string.format("\\fill[black] (%f,%f) rectangle (%f,%f);", grid_x_loc, grid_y_loc, grid_x_loc+kmaplevel_seperator_lenght, grid_y_loc-row-line_width-add_heigh))
                grid_x_loc = grid_x_loc + kmaplevel_seperator_lenght
            end
            if d >= 2 then
                localPrint(string.format("\\fill[black] (%f,%f) rectangle (%f,%f);", grid_x_loc, grid_y_loc, grid_x_loc+column+line_width, grid_y_loc-kmaplevel_seperator_lenght))
                grid_y_loc = grid_y_loc - kmaplevel_seperator_lenght
            end
        end
        -- Print out the top-left line corner with the variables
        if (is_multitable_seperated == false) or (d==0) then
            localPrint(string.format("\\draw[inner sep=0pt, outer sep=0pt] (%f, %f) -- (%f, %f);", grid_x_loc+line_width, grid_y_loc-line_width, grid_x_loc-zero_var_line_lenght, grid_y_loc+zero_var_line_lenght))
            localPrint(string.format("\\node[left] at (%f,%f) {\\small{%s}};", grid_x_loc-0.3, grid_y_loc+0.3, var2))
            localPrint(string.format("\\node[right] at (%f,%f) {\\small{%s}};", grid_x_loc-0.6, grid_y_loc+0.6, var1))
        end
        -- Print out the top boolean column header
        if (is_multitable_seperated == false) or (d < 2) then
            localPrint(string.format("\\matrix[matrix of nodes, ampersand replacement=\\&, column sep={1cm,between origins}, nodes={align=center,text width=1cm,inner sep=0pt}, anchor=south west, inner sep=0pt, outer sep=0pt] at (%f, %f) {",grid_x_loc,grid_y_loc+0.05))
            for c=0, column-1, 1 do
                localPrint(string.format("%s", decimalToGreyBin(c, column_header_numb_bits)))
                if c ~= (column-1) then localPrint("\\&") end
            end
            localPrint("\\\\};")
        end
        -- Print out the side boolean row header
        if (is_multitable_seperated == false) or (d%2 == 0) then
            localPrint(string.format("\\matrix[matrix of nodes, ampersand replacement=\\&, row sep={1cm,between origins}, nodes={minimum height=1cm,inner sep=0pt, text height=2ex, text depth=0.5ex}, anchor=north east, inner sep=0pt, outer sep=0pt] at (%f, %f) {",grid_x_loc-0.05,grid_y_loc))
            for r=0, row-1, 1 do
                localPrint(string.format("%s \\\\", decimalToGreyBin(r, row_header_numb_bits)))
            end
            localPrint("};")
        end
        -- Print out the matrix
        localPrint(string.format("\\matrix[matrix of nodes, ampersand replacement=\\&, column sep={1cm,between origins}, row sep={1cm,between origins}, nodes={rectangle,draw,minimum height=1cm,align=center,text width=1cm,inner sep=0pt, text height=2ex, text depth=0.5ex, line width=0.015cm}, anchor=north west, inner sep=0pt, outer sep=0pt] at (%f, %f) {%s};",
                                    grid_x_loc, grid_y_loc, generateKMap(row, column, d)
                                    ))
        -- Print out the buttom text saying which matrix is which
        if (submaps_n > 0) then
            if (is_multitable_seperated == false) then
                localPrint(string.format("\\node[below] at (%f, %f) {%s = %s};", grid_x_loc+(column//2),grid_y_loc-row,var3, decimalToBin(d, 2)))
            elseif (is_multitable_seperated == true) then
                if (d < 2) then
                    localPrint(string.format("\\node[] at (%f, %f) {%s = %s};", grid_x_loc+(column//2), grid_y_loc+1, var3, decimalToBin(d, 2)))
                end
                if (d % 2 == 0) and (submaps_n > 2) then
                    localPrint(string.format("\\node[rotate=90] at (%f, %f) {%s = %s};", grid_x_loc-1, grid_y_loc-(row//2), var3, decimalToBin(d, 2)))
                end
            end
        end
    end
end

-- Function for drawing an implicant manually (meaning to give the start and endpoint, as well as optional
-- submaps for different ones)
function manual_draw_implicant(st, en, submaps_str)
    local color_index = cartonaugh_env_settings.color_index
    local max_submaps = cartonaugh_env_settings.submaps
    local inner_spread = cartonaugh_env_settings.implicant_settings.inner_sep
    st = tonumber(st)
    en = tonumber(en)
    local submap_arr = split(submaps_str, ',')
    --     Check if the implacent selection
    for s=1,table.getn(submap_arr),1 do
        current_submap = tonumber(submap_arr[s])
        if current_submap < max_submaps then
            local draw_str = string.format("($(%s.center)+(-%s,%s)$) rectangle ($(%s.center)+(%s,-%s)$)", decimalToGreyBin(current_submap, 2) .. decimalToBin(st,4), inner_spread, inner_spread, decimalToGreyBin(current_submap, 2) .. decimalToBin(en,4), inner_spread, inner_spread)
            if cartonaugh_env_settings.bw == 0 then
                localPrint(string.format("\\fill[rounded corners=3pt,fill=%s,fill opacity=0.25,] {%s};", getColor(color_index) , draw_str))
            end
            localPrint(string.format("\\draw[rounded corners=3pt,draw opacity=1.0,] {%s};", draw_str))
        else
            localPrint(string.format("\\PackageWarning{cartonaugh}{You can only draw on existing sub maps. Ignoring instruction to draw on non existing sub map number %d}", s))
        end
    end
    cartonaugh_env_settings.color_index = cartonaugh_env_settings.color_index+1
end

-- Handler function for drawing edge implacants, figuring out orientation as well
function manual_draw_edge_implicant(corner1, corner2, corner3, corner4, submaps_str)
    corner1 = tonumber(corner1)
    corner2 = tonumber(corner2)
    corner3 = tonumber(corner3)
    corner4 = tonumber(corner4)

    if corner1-corner2 > corner1-corner3 then
        manual_draw_edge_implicant_orientation(corner1, corner2, submaps_str, 'n')
        manual_draw_edge_implicant_orientation(corner3, corner4, submaps_str, 's')
    else
        manual_draw_edge_implicant_orientation(corner1, corner2, submaps_str, 'w')
        manual_draw_edge_implicant_orientation(corner3, corner4, submaps_str, 'e')
    end

    cartonaugh_env_settings.color_index = cartonaugh_env_settings.color_index+1

end

-- Function to draw out a 1 edge implacant given 2 corners, the submaps, and the orientation (n, s, e, or w)
-- TODO: Perhaps find a way to repeat the code between n/s and e/w
-- TODO: For the mirror variable, have that apply to the lua var directly instead of having LaTeX handle it
-- TODO: Maybe add option for squigly lines for the end instead of nothing
-- TODO: Open up the internal inner_spread and outer_spead settings to the user
function manual_draw_edge_implicant_orientation(corner1, corner2, submaps_str, orientation)
    local color_index = cartonaugh_env_settings.color_index
    local max_submaps = cartonaugh_env_settings.submaps
    corner1 = tonumber(corner1)
    corner2 = tonumber(corner2)
    local submap_arr = split(submaps_str, ',')
    local inner_spread = cartonaugh_env_settings.implicant_settings.inner_sep
    local outer_spead = cartonaugh_env_settings.implicant_settings.outer_sep
    --     Check if the implacent selection
    for s=1,table.getn(submap_arr),1 do
        current_submap = tonumber(submap_arr[s])
        if current_submap < max_submaps then
            local draw_string = ""
            local mirror = 1
            local corner1_bin = decimalToGreyBin(current_submap, 2) .. decimalToBin(corner1,4)
            local corner2_bin = decimalToGreyBin(current_submap, 2) .. decimalToBin(corner2,4)
            if orientation == 'n' or orientation == 's' then
                -- If the orientation is south, just mirror it
                if orientation == 's' then mirror = -1 end
                draw_string = string.format("($(%s.center)+(-%f,%f*%s)$)", corner1_bin, inner_spread, outer_spead, mirror)
                draw_string = draw_string .. string.format("{[rounded corners=3pt] -- ($(%s.center)+(-%f,-%f*%s)$)}", corner1_bin, inner_spread, inner_spread, mirror)
                draw_string = draw_string .. string.format("{[rounded corners=3pt] -- ($(%s.center)+(%f,-%f*%s)$)}", corner2_bin, inner_spread, inner_spread, mirror)
                draw_string = draw_string .. string.format("-- ($(%s.center)+(%f,%f*%s)$)", corner2_bin, inner_spread, outer_spead, mirror)
            else
                if orientation == 'e' then mirror = -1 end
                draw_string = string.format("($(%s.center)+(-%f*%s,%f)$)", corner1_bin, outer_spead, mirror, inner_spread)
                draw_string = draw_string .. string.format("{[rounded corners=3pt] -- ($(%s.center)+(%f*%s,%f)$)}", corner1_bin, inner_spread, mirror, inner_spread)
                draw_string = draw_string .. string.format("{[rounded corners=3pt] -- ($(%s.center)+(%f*%s,-%f)$)}", corner2_bin, inner_spread, mirror, inner_spread)
                draw_string = draw_string .. string.format("-- ($(%s.center)+(-%f*%s,-%f)$)", corner2_bin, outer_spead, mirror, inner_spread)
            end
            if cartonaugh_env_settings.bw == 0 then
                localPrint(string.format("\\fill[fill=%s,fill opacity=0.25,] {%s};", getColor(color_index), draw_string))
            end
            localPrint(string.format("\\draw[draw opacity=1.0] {%s};", draw_string))
        else
            localPrint(string.format("\\PackageWarning{cartonaugh}{You can only draw on existing sub maps. Ignoring instruction to draw on non existing sub map number %d}", s))
        end
    end
end

-- Function to draw the corner implicants. Only usable on 4x4 matrices
function manual_draw_corner_implicant(submaps_str)
    local corner_arr = {0, 2, 8, 10}
    local submap_arr = split(submaps_str, ',')
    local max_submaps = cartonaugh_env_settings.submaps
    local color = cartonaugh_env_settings.color_index
    local inner_spread = cartonaugh_env_settings.implicant_settings.inner_sep
    local outer_spread = cartonaugh_env_settings.implicant_settings.outer_sep

    if cartonaugh_env_settings.cols ~= 4 or cartonaugh_env_settings.rows ~= 4 then
        localPrint("\\PackageError{cartonaugh}{Cannot use a corner implicant on anything but a 4x4. Sorry!}")
        return
    end

    for s=1,table.getn(submap_arr),1 do
        current_submap = tonumber(submap_arr[s])
        if current_submap < max_submaps then
            for c=0,3,1 do
                local x_mirror = 1-(2*(c%2))
                local y_mirror = 1-(2*(c//2))
                local corner = decimalToGreyBin(current_submap, 2) .. decimalToBin(corner_arr[c+1],4)
                -- Create the string to draw the corners
                local draw_string = string.format("($(%s.center)+(-%f*%d,%f*%d)$)--($(%s.center)+(%f*%d,%f*%d)$)", corner, outer_spread, x_mirror, outer_spread, y_mirror, corner, inner_spread, x_mirror, outer_spread, y_mirror)
                draw_string = draw_string .. string.format("{ [rounded corners=3pt] --($(%s.center)+(%f*%d,-%f*%d)$) }", corner, inner_spread, x_mirror, inner_spread, y_mirror)
                draw_string = draw_string .. string.format("--($(%s.center)+(-%f*%d,-%f*%d)$) -- cycle", corner, outer_spread, x_mirror, inner_spread, y_mirror)
                if cartonaugh_env_settings.bw == 0 then
                    localPrint(string.format("\\fill[fill=%s,fill opacity=0.25,] {%s};", getColor(color), draw_string))
                end
                localPrint(string.format("\\draw[sharp corners, draw opacity=1.0] {%s};", draw_string))
            end
        else
            localPrint(string.format("\\PackageWarning{cartonaugh}{You can only draw on existing sub maps. Ignoring instruction to draw on non existing sub map number %d}", s))
        end
    end

    cartonaugh_env_settings.color_index = cartonaugh_env_settings.color_index+1

end

-- WORK IN PROGRESS/LONG TERM FUNCTION
-- Goals is to eventually give \implicant{1}{x}{0}{x} for example and have it draw it out for you.
-- May give up on this in favor of other things...don't know
function draw_implicant(var_list)
--     local var_list_arr = split(var_list, ',')
    local color_index = cartonaugh_env_settings.color_index
    local max_submaps = cartonaugh_env_settings.submaps
    localPrint("\\PackageWarning{cartonaugh}{This is a UNSTABLE and WIP function. Procede on your own}")

    -- Check argument for submaps greater than 1
    -- TODO: before returning print out a package error
    if max_submaps > 1 then
        for s=0,max_submaps-1,1 do
            if var_list[5+s] == '' then
                -- TODO: Fix this
                localPrint(string.format("\\PackageError{cartonaugh}{Please feed either 1, 0, or x for sub map number %d's variable boolean}", s+1))
                return
            end
        end
    end

    local low_limit = 0
    local high_limit = 0

    for b=1,4,1 do
        if var_list[b] == 'x' then
            print('a',high_limit, greyBinToDecimal(high_limit), decimalToBin(greyBinToDecimal(high_limit), 4))
            print('b',high_limit | (1 << (b-1)), greyBinToDecimal(high_limit | (1 << (b-1))), decimalToBin(greyBinToDecimal(high_limit | (1 << (b-1))), 4))
            if greyBinToDecimal(high_limit) < greyBinToDecimal(high_limit | (1 << (b-1))) then
                high_limit = high_limit | (1 << (b-1))
                print(decimalToBin(greyBinToDecimal(high_limit),4), decimalToBin(greyBinToDecimal(high_limit & ~(1 << (b-2))),4))
                if greyBinToDecimal(high_limit) < greyBinToDecimal(high_limit & ~(1 << (b-2))) then
                    high_limit = high_limit & ~(1 << (b-2))
                end
            end
        elseif var_list[b] == '1' then
            high_limit = high_limit | (1 << (b-1))
            low_limit = low_limit | (1 << (b-1))
        end
        print('low_limit=', low_limit, 'high_limit=', high_limit)
    end

    local st = decimalToBin(low_limit,4)
    local en = decimalToBin(high_limit,4)

    print('low_limit', greyBinToDecimal(low_limit), 'high_limit', greyBinToDecimal(high_limit), 'st=', st, 'en=', en)

    for s=1,1,1 do
        current_submap = 0
        if current_submap < max_submaps then
            if cartonaugh_env_settings.bw == 0 then
                localPrint(string.format("\\fill[rounded corners=3pt,fill=%s,fill opacity=0.25,] {($(%s.center)+(-0.3,0.3)$) rectangle ($(%s.center)+(0.3,-0.3)$)};", getColor(color_index) , decimalToGreyBin(current_submap, 2) .. st, decimalToGreyBin(current_submap, 2) .. en))
                color_index = color_index+1
            end
            localPrint(string.format("\\draw[rounded corners=3pt,draw opacity=1.0,] {($(%s.center)+(-0.3,0.3)$)rectangle($(%s.center)+(0.3,-0.3)$)};", decimalToGreyBin(current_submap, 2) .. st, decimalToGreyBin(current_submap, 2) .. en))
        else
            localPrint(string.format("\\PackageWarning{cartonaugh}{You can only draw on existing sub maps. Ignoring instruction to draw on non existing sub map number %d}", s))
        end
    end
    cartonaugh_env_settings.color_index = color_index
end

function autoterms(what_to_write)
   local max_cells = cartonaugh_env_settings.submaps * cartonaugh_env_settings.cols * cartonaugh_env_settings.rows
   for cell=0,max_cells-1,1 do
       if used_cells[cell] == nil then
           used_cells[cell] = true
           localPrint(string.format("\\path (%s) node {%s};", decimalToBin(cell, 6), what_to_write))
       end
   end
end

function manualterms(what_to_write)
    local what_to_write_arr = split(what_to_write, ',')
    for cell=0,table.getn(what_to_write_arr)-1,1 do
        if used_cells[cell] == nil then
            used_cells[cell] = true
            localPrint(string.format("\\path (%s) node {%s};", decimalToBin(cell, 6), what_to_write_arr[cell+1]))
        end
    end
end

function write_to_cell(cells, what_to_write)
    local cells_arr = split(cells, ',')
    for c=1,table.getn(cells_arr),1 do
        local cell = tonumber(cells_arr[c])
        if used_cells[cell] == nil then
            used_cells[cell] = true
            localPrint(string.format("\\path (%s) node {%s};", decimalToBin(cell, 6), what_to_write))
        end
    end
end