From aa372c0ed6ca775f603a535d8bad70f172751a29 Mon Sep 17 00:00:00 2001 From: eudoxia Date: Fri, 8 Apr 2022 00:32:03 -0400 Subject: control flow restructuring; removed doc timestamps --- .gitignore | 1 + data.lp | 108 ++++++++++++++++++++---------- doc/data.html | 112 ++++++++++++++++++++----------- doc/freestanding/data.html | 111 +++++++++++++++++++++---------- doc/log.html | 1 - doc/tangle.html | 1 - doc/weave.html | 1 - gen-docs.sh | 5 +- src/data.zig | 162 +++++++++++++++++++++++++++------------------ tangle | Bin 16376 -> 16416 bytes weave | Bin 14672 -> 14672 bytes 11 files changed, 324 insertions(+), 178 deletions(-) diff --git a/.gitignore b/.gitignore index 59f7796..b872cdc 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ **/zig-cache +/misc diff --git a/data.lp b/data.lp index 329cd14..ee40f5d 100644 --- a/data.lp +++ b/data.lp @@ -19,6 +19,8 @@ This file contains the various data processing-related constants and functions r @= Section searching function +@= Command type detection function + @= Parsing functions @= Code generation functions @@ -111,7 +113,7 @@ We also define the set of errors which may be encountered by the various process - References to nonexistent section names or configuration commands. @: Error set -pub const Errors = error{ +pub const Errors = error { UnexpectedStart, UnexpectedEnd, DereferenceLimit, @@ -198,6 +200,26 @@ fn search(list: []Section, name: []const u8) !usize { ## Parsing +We first define a function which, for a given line, determines whether it consists of a formatting command, and which type of command it contains. This is done in order to enable the use of switch statements in later functions using this routine. + +@: Command type detection function +const CommandType = enum { start, add, end, ref, none }; + +fn command_type(line: []const u8) CommandType { + if (std.mem.startsWith(u8, line, k_start)) { + return .start; + } else if (std.mem.startsWith(u8, line, k_add)) { + return .add; + } else if (std.mem.eql(u8, line, k_end)) { + return .end; + } else if (std.mem.startsWith(u8, std.mem.trimLeft(u8, line, " \t"), k_ref)) { + return .ref; + } else { + return .none; + } +} +@. + We then define the parsing functions, consisting of the main `parse` function which builds the list of `Section`s, and its auxiliary `parse_code` subroutine which builds the contents of each `CodeSection`. @: Parsing functions @@ -235,15 +257,20 @@ The main parsing routine iterates over the list of lines, adding code sections w var i: u32 = 0; while (i < lines.len) { const line = lines[i]; - if (std.mem.startsWith(u8, line, k_start)) { - @= Add new section - } else if (std.mem.startsWith(u8, line, k_add)) { - @= Append to section - } else if (std.mem.eql(u8, line, k_end)) { - log(.err, "line {d}: unexpected section end", .{i + 1}); - return error.UnexpectedEnd; - } else { - i += 1; + switch (command_type(line)) { + .start => { + @= Add new section + }, + .add => { + @= Append to section + }, + .end => { + log(.err, "line {d}: unexpected section end", .{i + 1}); + return error.UnexpectedEnd; + }, + else => { + i += 1; + }, } } @. @@ -283,15 +310,20 @@ The code parsing subroutine iterates over the list of lines similarly to the mai var i = index; while (i < lines.len) { const line = lines[i]; - if (std.mem.startsWith(u8, line, k_start) or std.mem.startsWith(u8, line, k_add)) { - log(.err, "line {d}: unexpected section start", .{i + 1}); - return error.UnexpectedStart; - } else if (std.mem.startsWith(u8, std.mem.trimLeft(u8, line, " \t"), k_ref)) { - @= Add reference - } else if (std.mem.eql(u8, line, k_end)) { - break; - } else { - @= Add literal range + switch (command_type(line)) { + .start, .add => { + log(.err, "line {d}: unexpected section start", .{i + 1}); + return error.UnexpectedStart; + }, + .ref => { + @= Add reference + }, + .end => { + break; + }, + else => { + @= Add literal range + }, } } @. @@ -392,16 +424,22 @@ pub fn textgen(lines: [][]const u8, alloc: Allocator) ![][]const u8 { or std.mem.startsWith(u8, line, kc_end) or std.mem.startsWith(u8, line, kc_ref)) { continue; - } else if (std.mem.startsWith(u8, line, k_start)) { - @= Format starting command - } else if (std.mem.startsWith(u8, line, k_add)) { - @= Format appending command - } else if (std.mem.startsWith(u8, line, k_end)) { - @= Format ending command - } else if (std.mem.startsWith(u8, std.mem.trimLeft(u8, line, " \t"), k_ref)) { - @= Format reference command - } else { - try buffer.append(line); + } else switch (command_type(line)) { + .start => { + @= Format starting command + }, + .add => { + @= Format appending command + }, + .ref => { + @= Format reference command + }, + .end => { + @= Format ending command + }, + else => { + try buffer.append(line); + }, } } @@ -432,12 +470,6 @@ current_name = line[(k_add.len)..]; try buffer.append(try std.mem.join(alloc, current_name, conf_add)); @. -Processing a section ending command, however, does not require updating the current section name. - -@: Format ending command -try buffer.append(try std.mem.join(alloc, current_name, conf_end)); -@. - To process a reference command, the index of the reference command keyword is first extracted. Then the formatted reference string is created, to which the reference command line's leading whitespace is prepended (to preserve indentation). @: Format reference command @@ -445,3 +477,9 @@ const start = std.mem.indexOf(u8, line, k_ref).?; const ref = try std.mem.join(alloc, line[(start + k_ref.len)..], conf_ref); try buffer.append(try std.mem.concat(alloc, u8, &[_][]const u8{ line[0..start], ref })); @. + +Processing a section ending command is performed similarly to the starting and appending commands, however it does not require updating the current section name. + +@: Format ending command +try buffer.append(try std.mem.join(alloc, current_name, conf_end)); +@. diff --git a/doc/data.html b/doc/data.html index 8d58f42..7b5e079 100755 --- a/doc/data.html +++ b/doc/data.html @@ -10,7 +10,6 @@ data.lp — DistressNetwork° - @@ -40,6 +39,8 @@ (Section searching function) +(Command type detection function) + (Parsing functions) (Code generation functions) @@ -146,7 +147,7 @@ pub const LineRange = struct {

Error set:

-
pub const Errors = error{
+
pub const Errors = error {
     UnexpectedStart,
     UnexpectedEnd,
     DereferenceLimit,
@@ -239,6 +240,27 @@ while (iterator.next()) |line| {
 
 

Parsing

+

We first define a function which, for a given line, determines whether it consists of a formatting command, and which type of command it contains. This is done in order to enable the use of switch statements in later functions using this routine.

+ +

Command type detection function:

+ +
const CommandType = enum { start, add, end, ref, none };
+
+fn command_type(line: []const u8) CommandType {
+    if (std.mem.startsWith(u8, line, k_start)) {
+        return .start;
+    } else if (std.mem.startsWith(u8, line, k_add)) {
+        return .add;
+    } else if (std.mem.eql(u8, line, k_end)) {
+        return .end;
+    } else if (std.mem.startsWith(u8, std.mem.trimLeft(u8, line, " \t"), k_ref)) {
+        return .ref;
+    } else {
+        return .none;
+    }
+}
+
+

We then define the parsing functions, consisting of the main parse function which builds the list of Sections, and its auxiliary parse_code subroutine which builds the contents of each CodeSection.

Parsing functions:

@@ -279,15 +301,20 @@ fn parse_code(lines: [][]const u8, index: u32, alloc: Allocator) !CodeReturn {
var i: u32 = 0;
 while (i < lines.len) {
     const line = lines[i];
-    if (std.mem.startsWith(u8, line, k_start)) {
-        (Add new section)
-    } else if (std.mem.startsWith(u8, line, k_add)) {
-        (Append to section)
-    } else if (std.mem.eql(u8, line, k_end)) {
-        log(.err, "line {d}: unexpected section end", .{i + 1});
-        return error.UnexpectedEnd;
-    } else {
-        i += 1;
+    switch (command_type(line)) {
+        .start  => {
+            (Add new section)
+        },
+        .add    => {
+            (Append to section)
+        },
+        .end    => {
+            log(.err, "line {d}: unexpected section end", .{i + 1});
+            return error.UnexpectedEnd;
+        },
+        else    => {
+            i += 1;
+        },
     }
 }
 
@@ -330,15 +357,20 @@ i = section.index;
var i = index;
 while (i < lines.len) {
     const line = lines[i];
-    if (std.mem.startsWith(u8, line, k_start) or std.mem.startsWith(u8, line, k_add)) {
-        log(.err, "line {d}: unexpected section start", .{i + 1});
-        return error.UnexpectedStart;
-    } else if (std.mem.startsWith(u8, std.mem.trimLeft(u8, line, " \t"), k_ref)) {
-        (Add reference)
-    } else if (std.mem.eql(u8, line, k_end)) {
-        break;
-    } else {
-        (Add literal range)
+    switch (command_type(line)) {
+        .start, .add    => {
+            log(.err, "line {d}: unexpected section start", .{i + 1});
+            return error.UnexpectedStart;
+        },
+        .ref    => {
+            (Add reference)
+        },
+        .end    => {
+            break;
+        },
+        else    => {
+            (Add literal range)
+        },
     }
 }
 
@@ -445,16 +477,22 @@ try buffer.appendSlice(code); or std.mem.startsWith(u8, line, kc_end) or std.mem.startsWith(u8, line, kc_ref)) { continue; - } else if (std.mem.startsWith(u8, line, k_start)) { - (Format starting command) - } else if (std.mem.startsWith(u8, line, k_add)) { - (Format appending command) - } else if (std.mem.startsWith(u8, line, k_end)) { - (Format ending command) - } else if (std.mem.startsWith(u8, std.mem.trimLeft(u8, line, " \t"), k_ref)) { - (Format reference command) - } else { - try buffer.append(line); + } else switch (command_type(line)) { + .start => { + (Format starting command) + }, + .add => { + (Format appending command) + }, + .ref => { + (Format reference command) + }, + .end => { + (Format ending command) + }, + else => { + try buffer.append(line); + }, } } @@ -488,13 +526,6 @@ try buffer.append(try std.mem.join(alloc, current_name, conf_start)); try buffer.append(try std.mem.join(alloc, current_name, conf_add));
-

Processing a section ending command, however, does not require updating the current section name.

- -

Format ending command:

- -
try buffer.append(try std.mem.join(alloc, current_name, conf_end));
-
-

To process a reference command, the index of the reference command keyword is first extracted. Then the formatted reference string is created, to which the reference command line’s leading whitespace is prepended (to preserve indentation).

Format reference command:

@@ -503,6 +534,13 @@ try buffer.append(try std.mem.join(alloc, current_name, conf_add)); const ref = try std.mem.join(alloc, line[(start + k_ref.len)..], conf_ref); try buffer.append(try std.mem.concat(alloc, u8, &[_][]const u8{ line[0..start], ref }));
+ +

Processing a section ending command is performed similarly to the starting and appending commands, however it does not require updating the current section name.

+ +

Format ending command:

+ +
try buffer.append(try std.mem.join(alloc, current_name, conf_end));
+
diff --git a/doc/freestanding/data.html b/doc/freestanding/data.html index a963f99..5217927 100644 --- a/doc/freestanding/data.html +++ b/doc/freestanding/data.html @@ -51,6 +51,8 @@ ul ul,ol ol {margin: 0;} (Section searching function) +(Command type detection function) + (Parsing functions) (Code generation functions) @@ -157,7 +159,7 @@ pub const LineRange = struct {

Error set:

-
pub const Errors = error{
+
pub const Errors = error {
     UnexpectedStart,
     UnexpectedEnd,
     DereferenceLimit,
@@ -250,6 +252,27 @@ while (iterator.next()) |line| {
 
 

Parsing

+

We first define a function which, for a given line, determines whether it consists of a formatting command, and which type of command it contains. This is done in order to enable the use of switch statements in later functions using this routine.

+ +

Command type detection function:

+ +
const CommandType = enum { start, add, end, ref, none };
+
+fn command_type(line: []const u8) CommandType {
+    if (std.mem.startsWith(u8, line, k_start)) {
+        return .start;
+    } else if (std.mem.startsWith(u8, line, k_add)) {
+        return .add;
+    } else if (std.mem.eql(u8, line, k_end)) {
+        return .end;
+    } else if (std.mem.startsWith(u8, std.mem.trimLeft(u8, line, " \t"), k_ref)) {
+        return .ref;
+    } else {
+        return .none;
+    }
+}
+
+

We then define the parsing functions, consisting of the main parse function which builds the list of Sections, and its auxiliary parse_code subroutine which builds the contents of each CodeSection.

Parsing functions:

@@ -290,15 +313,20 @@ fn parse_code(lines: [][]const u8, index: u32, alloc: Allocator) !CodeReturn {
var i: u32 = 0;
 while (i < lines.len) {
     const line = lines[i];
-    if (std.mem.startsWith(u8, line, k_start)) {
-        (Add new section)
-    } else if (std.mem.startsWith(u8, line, k_add)) {
-        (Append to section)
-    } else if (std.mem.eql(u8, line, k_end)) {
-        log(.err, "line {d}: unexpected section end", .{i + 1});
-        return error.UnexpectedEnd;
-    } else {
-        i += 1;
+    switch (command_type(line)) {
+        .start  => {
+            (Add new section)
+        },
+        .add    => {
+            (Append to section)
+        },
+        .end    => {
+            log(.err, "line {d}: unexpected section end", .{i + 1});
+            return error.UnexpectedEnd;
+        },
+        else    => {
+            i += 1;
+        },
     }
 }
 
@@ -341,15 +369,20 @@ i = section.index;
var i = index;
 while (i < lines.len) {
     const line = lines[i];
-    if (std.mem.startsWith(u8, line, k_start) or std.mem.startsWith(u8, line, k_add)) {
-        log(.err, "line {d}: unexpected section start", .{i + 1});
-        return error.UnexpectedStart;
-    } else if (std.mem.startsWith(u8, std.mem.trimLeft(u8, line, " \t"), k_ref)) {
-        (Add reference)
-    } else if (std.mem.eql(u8, line, k_end)) {
-        break;
-    } else {
-        (Add literal range)
+    switch (command_type(line)) {
+        .start, .add    => {
+            log(.err, "line {d}: unexpected section start", .{i + 1});
+            return error.UnexpectedStart;
+        },
+        .ref    => {
+            (Add reference)
+        },
+        .end    => {
+            break;
+        },
+        else    => {
+            (Add literal range)
+        },
     }
 }
 
@@ -456,16 +489,22 @@ try buffer.appendSlice(code); or std.mem.startsWith(u8, line, kc_end) or std.mem.startsWith(u8, line, kc_ref)) { continue; - } else if (std.mem.startsWith(u8, line, k_start)) { - (Format starting command) - } else if (std.mem.startsWith(u8, line, k_add)) { - (Format appending command) - } else if (std.mem.startsWith(u8, line, k_end)) { - (Format ending command) - } else if (std.mem.startsWith(u8, std.mem.trimLeft(u8, line, " \t"), k_ref)) { - (Format reference command) - } else { - try buffer.append(line); + } else switch (command_type(line)) { + .start => { + (Format starting command) + }, + .add => { + (Format appending command) + }, + .ref => { + (Format reference command) + }, + .end => { + (Format ending command) + }, + else => { + try buffer.append(line); + }, } } @@ -499,13 +538,6 @@ try buffer.append(try std.mem.join(alloc, current_name, conf_start)); try buffer.append(try std.mem.join(alloc, current_name, conf_add));
-

Processing a section ending command, however, does not require updating the current section name.

- -

Format ending command:

- -
try buffer.append(try std.mem.join(alloc, current_name, conf_end));
-
-

To process a reference command, the index of the reference command keyword is first extracted. Then the formatted reference string is created, to which the reference command line’s leading whitespace is prepended (to preserve indentation).

Format reference command:

@@ -514,5 +546,12 @@ try buffer.append(try std.mem.join(alloc, current_name, conf_add)); const ref = try std.mem.join(alloc, line[(start + k_ref.len)..], conf_ref); try buffer.append(try std.mem.concat(alloc, u8, &[_][]const u8{ line[0..start], ref }));
+ +

Processing a section ending command is performed similarly to the starting and appending commands, however it does not require updating the current section name.

+ +

Format ending command:

+ +
try buffer.append(try std.mem.join(alloc, current_name, conf_end));
+
\ No newline at end of file diff --git a/doc/log.html b/doc/log.html index bcfeb56..89f861a 100755 --- a/doc/log.html +++ b/doc/log.html @@ -10,7 +10,6 @@ log.lp — DistressNetwork° - diff --git a/doc/tangle.html b/doc/tangle.html index 816fa1b..3fd4c02 100755 --- a/doc/tangle.html +++ b/doc/tangle.html @@ -10,7 +10,6 @@ tangle.lp — DistressNetwork° - diff --git a/doc/weave.html b/doc/weave.html index 69be660..81ef1d6 100755 --- a/doc/weave.html +++ b/doc/weave.html @@ -10,7 +10,6 @@ weave.lp — DistressNetwork° - diff --git a/gen-docs.sh b/gen-docs.sh index 8c7e81e..ed371ff 100755 --- a/gen-docs.sh +++ b/gen-docs.sh @@ -12,12 +12,13 @@ for file in "data" "log" "tangle" "weave" ; do pushd "../web" > "/dev/null" ; sh "./md.sh" "$tmp" "../literary/$out" > "/dev/null" ; popd > "/dev/null" ; + sed "/~\n&~1" -i'' "$out" ; sed 's;\(.*\)@= \(.*\) =@;\1(\2);1' -i'' "$out" ; - sh "./../sync.sh" ; - echo "[ok] generated text '${file}'" ; done +sh "./../sync.sh" + rm "$tmp" diff --git a/src/data.zig b/src/data.zig index f2ee9d9..824d36c 100644 --- a/src/data.zig +++ b/src/data.zig @@ -88,6 +88,22 @@ fn search(list: []Section, name: []const u8) !usize { } // TODO return last match instead? +const CommandType = enum { start, add, end, ref, none }; + +fn command_type(line: []const u8) CommandType { + if (std.mem.startsWith(u8, line, k_start)) { + return .start; + } else if (std.mem.startsWith(u8, line, k_add)) { + return .add; + } else if (std.mem.eql(u8, line, k_end)) { + return .end; + } else if (std.mem.startsWith(u8, std.mem.trimLeft(u8, line, " \t"), k_ref)) { + return .ref; + } else { + return .none; + } +} + pub fn parse(lines: [][]const u8, alloc: Allocator) ![]Section { var sections = std.ArrayList(Section).init(alloc); defer sections.deinit(); @@ -95,32 +111,37 @@ pub fn parse(lines: [][]const u8, alloc: Allocator) ![]Section { var i: u32 = 0; while (i < lines.len) { const line = lines[i]; - if (std.mem.startsWith(u8, line, k_start)) { - const name = line[(k_start.len)..]; - log(.debug, "({d}) starting section '{s}'", .{ i + 1, name }); - - const section = try parse_code(lines, i + 1, alloc); - try sections.append(.{ .name = name, .content = section.content }); - - log(.debug, "({d}) ending section '{s}'", .{ section.index, name }); - i = section.index; - } else if (std.mem.startsWith(u8, line, k_add)) { - const name = line[(k_add.len)..]; - log(.debug, "({d}) appending to section '{s}'", .{ i + 1, name }); - - const section = try parse_code(lines, i + 1, alloc); - const index = try search(sections.items, name); - const old = §ions.items[index]; - const new = try std.mem.concat(alloc, Content, &[_][]const Content{ old.*.content, section.content }); - old.*.content = new; - - log(.debug, "({d}) ending section '{s}'", .{ section.index, name }); - i = section.index; - } else if (std.mem.eql(u8, line, k_end)) { - log(.err, "line {d}: unexpected section end", .{i + 1}); - return error.UnexpectedEnd; - } else { - i += 1; + switch (command_type(line)) { + .start => { + const name = line[(k_start.len)..]; + log(.debug, "({d}) starting section '{s}'", .{ i + 1, name }); + + const section = try parse_code(lines, i + 1, alloc); + try sections.append(.{ .name = name, .content = section.content }); + + log(.debug, "({d}) ending section '{s}'", .{ section.index, name }); + i = section.index; + }, + .add => { + const name = line[(k_add.len)..]; + log(.debug, "({d}) appending to section '{s}'", .{ i + 1, name }); + + const section = try parse_code(lines, i + 1, alloc); + const index = try search(sections.items, name); + const old = §ions.items[index]; + const new = try std.mem.concat(alloc, Content, &[_][]const Content{ old.*.content, section.content }); + old.*.content = new; + + log(.debug, "({d}) ending section '{s}'", .{ section.index, name }); + i = section.index; + }, + .end => { + log(.err, "line {d}: unexpected section end", .{i + 1}); + return error.UnexpectedEnd; + }, + else => { + i += 1; + }, } } @@ -134,32 +155,37 @@ fn parse_code(lines: [][]const u8, index: u32, alloc: Allocator) !CodeReturn { var i = index; while (i < lines.len) { const line = lines[i]; - if (std.mem.startsWith(u8, line, k_start) or std.mem.startsWith(u8, line, k_add)) { - log(.err, "line {d}: unexpected section start", .{i + 1}); - return error.UnexpectedStart; - } else if (std.mem.startsWith(u8, std.mem.trimLeft(u8, line, " \t"), k_ref)) { - const ref_name = std.mem.trimLeft(u8, line, " \t")[(k_ref.len)..]; - try content.append(.{ .reference = ref_name }); - log(.debug, "({d}) \tappended reference '{s}'", .{ i + 1, ref_name }); - i += 1; - } else if (std.mem.eql(u8, line, k_end)) { - break; - } else { - if (content.items.len > 0) { - switch (content.items[content.items.len - 1]) { - .literal => |*range| { - range.*.end = i; - }, - .reference => { - try content.append(.{ .literal = .{ .start = i, .end = i } }); - log(.debug, "({d}) \tappending literal", .{i + 1}); - }, + switch (command_type(line)) { + .start, .add => { + log(.err, "line {d}: unexpected section start", .{i + 1}); + return error.UnexpectedStart; + }, + .ref => { + const ref_name = std.mem.trimLeft(u8, line, " \t")[(k_ref.len)..]; + try content.append(.{ .reference = ref_name }); + log(.debug, "({d}) \tappended reference '{s}'", .{ i + 1, ref_name }); + i += 1; + }, + .end => { + break; + }, + else => { + if (content.items.len > 0) { + switch (content.items[content.items.len - 1]) { + .literal => |*range| { + range.*.end = i; + }, + .reference => { + try content.append(.{ .literal = .{ .start = i, .end = i } }); + log(.debug, "({d}) \tappending literal", .{i + 1}); + }, + } + } else { + try content.append(.{ .literal = .{ .start = i, .end = i } }); + log(.debug, "({d}) \tappending literal", .{i + 1}); } - } else { - try content.append(.{ .literal = .{ .start = i, .end = i } }); - log(.debug, "({d}) \tappending literal", .{i + 1}); - } - i += 1; + i += 1; + }, } } @@ -214,20 +240,26 @@ pub fn textgen(lines: [][]const u8, alloc: Allocator) ![][]const u8 { for (lines) |line| { if (std.mem.startsWith(u8, line, kc_start) or std.mem.startsWith(u8, line, kc_add) or std.mem.startsWith(u8, line, kc_end) or std.mem.startsWith(u8, line, kc_ref)) { continue; - } else if (std.mem.startsWith(u8, line, k_start)) { - current_name = line[(k_start.len)..]; - try buffer.append(try std.mem.join(alloc, current_name, conf_start)); - } else if (std.mem.startsWith(u8, line, k_add)) { - current_name = line[(k_add.len)..]; - try buffer.append(try std.mem.join(alloc, current_name, conf_add)); - } else if (std.mem.startsWith(u8, line, k_end)) { - try buffer.append(try std.mem.join(alloc, current_name, conf_end)); - } else if (std.mem.startsWith(u8, std.mem.trimLeft(u8, line, " \t"), k_ref)) { - const start = std.mem.indexOf(u8, line, k_ref).?; - const ref = try std.mem.join(alloc, line[(start + k_ref.len)..], conf_ref); - try buffer.append(try std.mem.concat(alloc, u8, &[_][]const u8{ line[0..start], ref })); - } else { - try buffer.append(line); + } else switch (command_type(line)) { + .start => { + current_name = line[(k_start.len)..]; + try buffer.append(try std.mem.join(alloc, current_name, conf_start)); + }, + .add => { + current_name = line[(k_add.len)..]; + try buffer.append(try std.mem.join(alloc, current_name, conf_add)); + }, + .ref => { + const start = std.mem.indexOf(u8, line, k_ref).?; + const ref = try std.mem.join(alloc, line[(start + k_ref.len)..], conf_ref); + try buffer.append(try std.mem.concat(alloc, u8, &[_][]const u8{ line[0..start], ref })); + }, + .end => { + try buffer.append(try std.mem.join(alloc, current_name, conf_end)); + }, + else => { + try buffer.append(line); + }, } } diff --git a/tangle b/tangle index e9f3671..9bef0a7 100755 Binary files a/tangle and b/tangle differ diff --git a/weave b/weave index 9bf4fc7..40246dd 100755 Binary files a/weave and b/weave differ -- cgit v1.2.3