From ac3f45762d0e3bad5ae913e5221222824aa3525f Mon Sep 17 00:00:00 2001 From: Jacopo Binosi aka bainos Date: Mon, 12 Aug 2024 21:24:24 +0200 Subject: [PATCH 1/8] drumtab first commit --- lua/plugins/b_drumtab.lua | 154 ++++++++++++++++++++++++++++++++++++++ lua/plugins/init.lua | 19 ++--- 2 files changed, 164 insertions(+), 9 deletions(-) create mode 100644 lua/plugins/b_drumtab.lua diff --git a/lua/plugins/b_drumtab.lua b/lua/plugins/b_drumtab.lua new file mode 100644 index 0000000..4ada5b3 --- /dev/null +++ b/lua/plugins/b_drumtab.lua @@ -0,0 +1,154 @@ +local M = {} +-- Define the drum parts +local drum_parts = { + 'CC', + 'HH', + 'SD', + 'BD', +} + +-- Function to draw the drum tablature with dynamic measures and beats +local function draw_drum_tab(args) + -- Parse the arguments: measures, beats per measure, note value, subdivisions + local args_table = {} + for arg in args.args:gmatch '%d+' do + table.insert(args_table, tonumber(arg)) + end + + -- Unpack the arguments into variables + local measures = args_table[1] or 4 + local subdivisions = args_table[2] or 16 + + -- Calculate the number of dashes based on subdivisions + local measure_str = string.rep('-', subdivisions) .. '|' + + -- Construct the tab strings + local tab_lines = { '', } + for _, part in ipairs(drum_parts) do + local line = part .. ' |' + for _ = 1, measures do + line = line .. measure_str + end + table.insert(tab_lines, line) + end + + -- Get the current buffer + local buf = vim.api.nvim_get_current_buf() + + -- Go to the last written line and get the current cursor position + vim.cmd 'normal! G$' + local line = vim.api.nvim_win_get_cursor(0)[1] + + -- Insert the drum tab into the buffer + vim.api.nvim_buf_set_lines(buf, line - 1, line - 1, false, tab_lines) + + local cursor = vim.api.nvim_win_get_cursor(0) + vim.api.nvim_win_set_cursor(0, { cursor[1] - 4, cursor[2] + 4, }) +end + +local function parse_measure_count() + local buf_lines = vim.api.nvim_buf_get_lines(0, 0, -1, false) + local total_pipes = 0 + local tab_lines = 0 + + for _, line in ipairs(buf_lines) do + -- Count the number of '|' characters in the line + local pipe_count = select(2, line:gsub('|', '|')) + total_pipes = total_pipes + pipe_count + + -- Count the line if it has at least 2 pipes + if pipe_count >= 2 then + tab_lines = tab_lines + 1 + end + end + + -- Calculate total measures + if tab_lines > 0 then + local pipes = total_pipes - tab_lines + local total_measures = pipes / #drum_parts + return total_measures .. ' | ' .. pipes + .. ' / ' .. tab_lines + else + return 0 + end +end + + +-- EXPERIMENTAL + +local function merge_drum_tabs(tab1, tab2) + local result = {} + + for i = 1, #tab1 do + local part1 = tab1[i] + local part2 = tab2[i] + + local merged_line = part1:sub(1, 4) .. part1:sub(5) .. part2:sub(5) + merged_line = merged_line:gsub('|', '') + local drum_part = merged_line:sub(1, 2) -- Extract the drum part (e.g., 'CC') + local pattern = merged_line:sub(4) -- Extract the rest of the line (the pattern) + for j = 1, #pattern do + local char = pattern:sub(j, j) + + if char ~= '-' then + if result[j] == nil or result[j] == '-' then + result[j] = drum_part + else + result[j] = result[j] .. ',' .. drum_part + end + else + if result[j] == nil then + result[j] = char + end + end + end + end + + -- return merged_tab + return table.concat(result, ' ') +end + +local function get_buffer_lines(start_line, end_line) + return vim.api.nvim_buf_get_lines(0, start_line, end_line, false) +end + +-- local function set_buffer_lines(start_line, new_lines) +-- vim.api.nvim_buf_set_lines(0, start_line, start_line, false, new_lines) +-- end + +local function show_measure_count() + local measures = parse_measure_count() + local lines = get_buffer_lines(0, -1) + local tab1 = { unpack(lines, 1, 4), } + local tab2 = { unpack(lines, 6, 9), } + + local merged_tab = merge_drum_tabs(tab1, tab2) + + vim.cmd 'new' + + -- Write the number of measures into the buffer + vim.api.nvim_buf_set_lines(0, 0, -1, false, { 'Number of measures: ' .. measures, }) + vim.api.nvim_buf_set_lines(0, 0, -1, false, { 'result: ' .. merged_tab, }) + -- set_buffer_lines(#lines, merged_tab) +end + +-- EXPERIMENTAL END + + +-- Function to draw the empty 4/4 drum tablature +function M.setup() + vim.opt.wrap = true + vim.opt.linebreak = true + vim.opt.showbreak = '| ' + vim.opt.breakindent = true + vim.opt.breakindentopt = 'shift:4,sbr' + vim.opt.breakat = '|' + + -- Create a command to run the function with arguments + vim.api.nvim_create_user_command('DrawDrumTab', draw_drum_tab, { nargs = 1, }) + + -- Create the command to show the measure count + vim.api.nvim_create_user_command('ShowMeasureCount', show_measure_count, {}) +end + +return M diff --git a/lua/plugins/init.lua b/lua/plugins/init.lua index a42e8ae..1369254 100644 --- a/lua/plugins/init.lua +++ b/lua/plugins/init.lua @@ -14,15 +14,15 @@ function M.setup() { 'echasnovski/mini.trailspace', version = '*', lazy = false, }, { 'mg979/vim-visual-multi', lazy = false, }, { 'ellisonleao/gruvbox.nvim', priority = 1000, }, - { - 'folke/which-key.nvim', - lazy = false, - config = function() - vim.o.timeout = true - vim.o.timeoutlen = 300 - require 'which-key'.setup() - end, - }, + -- { + -- 'folke/which-key.nvim', + -- lazy = false, + -- config = function() + -- vim.o.timeout = true + -- vim.o.timeoutlen = 300 + -- require 'which-key'.setup() + -- end, + -- }, -- { 'rcarriga/nvim-notify', }, -- { -- 'folke/noice.nvim', @@ -184,6 +184,7 @@ function M.setup() require 'plugins.b_custom_filetypes'.setup() require 'plugins.b_formatter'.setup() require 'plugins.b_session'.setup() + require 'plugins.b_drumtab'.setup() end return M From 8c251ddf19cfe11ce6cbc1fdaf9c8c2a1b79733a Mon Sep 17 00:00:00 2001 From: Jacopo Binosi aka bainos Date: Wed, 14 Aug 2024 12:50:35 +0200 Subject: [PATCH 2/8] rests and note length --- lua/plugins/b_drumtab.lua | 58 +++++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/lua/plugins/b_drumtab.lua b/lua/plugins/b_drumtab.lua index 4ada5b3..01fd2d2 100644 --- a/lua/plugins/b_drumtab.lua +++ b/lua/plugins/b_drumtab.lua @@ -75,6 +75,33 @@ end -- EXPERIMENTAL +local function parse_drum_table(drum_table) + local result = {} + local current_unit = '' + local current_length = 1 + + for i = 1, #drum_table do + if drum_table[i] == '-' then + if i == 1 then + current_unit = 'R' + else + current_length = current_length + 1 + end + else + if current_unit ~= '' then + table.insert(result, current_unit .. current_length) + end + current_unit = drum_table[i] + current_length = 1 + end + end + + if current_unit ~= '' then + table.insert(result, current_unit .. current_length) + end + + return result +end local function merge_drum_tabs(tab1, tab2) local result = {} @@ -84,13 +111,15 @@ local function merge_drum_tabs(tab1, tab2) local part2 = tab2[i] local merged_line = part1:sub(1, 4) .. part1:sub(5) .. part2:sub(5) - merged_line = merged_line:gsub('|', '') + -- merged_line = merged_line:gsub('|', '') local drum_part = merged_line:sub(1, 2) -- Extract the drum part (e.g., 'CC') local pattern = merged_line:sub(4) -- Extract the rest of the line (the pattern) for j = 1, #pattern do local char = pattern:sub(j, j) - if char ~= '-' then + if char == '|' then + result[j] = char + elseif char ~= '-' then if result[j] == nil or result[j] == '-' then result[j] = drum_part else @@ -104,17 +133,29 @@ local function merge_drum_tabs(tab1, tab2) end end + local drum_table = {} + local line_tmp = {} + for i = 1, #result do + if result[i] == '|' then + table.insert(drum_table, + table.concat( + parse_drum_table(line_tmp))) + line_tmp = {} + else + table.insert(line_tmp, result[i]) + end + end -- return merged_tab - return table.concat(result, ' ') + return drum_table end local function get_buffer_lines(start_line, end_line) return vim.api.nvim_buf_get_lines(0, start_line, end_line, false) end --- local function set_buffer_lines(start_line, new_lines) --- vim.api.nvim_buf_set_lines(0, start_line, start_line, false, new_lines) --- end +local function set_buffer_lines(start_line, new_lines) + vim.api.nvim_buf_set_lines(0, start_line, start_line, false, new_lines) +end local function show_measure_count() local measures = parse_measure_count() @@ -128,8 +169,9 @@ local function show_measure_count() -- Write the number of measures into the buffer vim.api.nvim_buf_set_lines(0, 0, -1, false, { 'Number of measures: ' .. measures, }) - vim.api.nvim_buf_set_lines(0, 0, -1, false, { 'result: ' .. merged_tab, }) - -- set_buffer_lines(#lines, merged_tab) + -- vim.api.nvim_buf_set_lines(0, 0, -1, false, { 'result: ' .. table.concat(merged_tab, ' '), }) + -- vim.api.nvim_buf_set_lines(0, 0, -1, false, merged_tab) + set_buffer_lines(#lines, merged_tab) end -- EXPERIMENTAL END From 66cad4d32b072c0d4a2b41b6322c8baa67d47ecc Mon Sep 17 00:00:00 2001 From: Jacopo Binosi aka bainos Date: Wed, 14 Aug 2024 15:07:44 +0200 Subject: [PATCH 3/8] lilypond style note grouping --- lua/plugins/b_drumtab.lua | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/lua/plugins/b_drumtab.lua b/lua/plugins/b_drumtab.lua index 01fd2d2..00283b9 100644 --- a/lua/plugins/b_drumtab.lua +++ b/lua/plugins/b_drumtab.lua @@ -75,6 +75,15 @@ end -- EXPERIMENTAL +local function add_to_group(part, current_group) + if not current_group:match '^<.*>$' then + return '<' .. current_group .. ' ' .. part .. '>' + else + -- Remove the last '>' and add the new part inside the delimiters + return current_group:sub(1, -2) .. ' ' .. part .. '>' + end +end + local function parse_drum_table(drum_table) local result = {} local current_unit = '' @@ -83,7 +92,7 @@ local function parse_drum_table(drum_table) for i = 1, #drum_table do if drum_table[i] == '-' then if i == 1 then - current_unit = 'R' + current_unit = 'RRr' else current_length = current_length + 1 end @@ -121,9 +130,10 @@ local function merge_drum_tabs(tab1, tab2) result[j] = char elseif char ~= '-' then if result[j] == nil or result[j] == '-' then - result[j] = drum_part + result[j] = drum_part .. char else - result[j] = result[j] .. ',' .. drum_part + -- result[j] = result[j] .. ',' .. drum_part .. char + result[j] = add_to_group(drum_part .. char, result[j]) end else if result[j] == nil then @@ -139,7 +149,7 @@ local function merge_drum_tabs(tab1, tab2) if result[i] == '|' then table.insert(drum_table, table.concat( - parse_drum_table(line_tmp))) + parse_drum_table(line_tmp), ' ')) line_tmp = {} else table.insert(line_tmp, result[i]) From 8d4a02b1c17e1ce2675b8f35b7912e140eac2722 Mon Sep 17 00:00:00 2001 From: Jacopo Binosi aka bainos Date: Wed, 14 Aug 2024 16:41:22 +0200 Subject: [PATCH 4/8] improoved tab identification --- lua/plugins/b_drumtab.lua | 88 +++++++++++++++++++++++++++++++++++---- 1 file changed, 81 insertions(+), 7 deletions(-) diff --git a/lua/plugins/b_drumtab.lua b/lua/plugins/b_drumtab.lua index 00283b9..89c5db6 100644 --- a/lua/plugins/b_drumtab.lua +++ b/lua/plugins/b_drumtab.lua @@ -74,7 +74,6 @@ local function parse_measure_count() end --- EXPERIMENTAL local function add_to_group(part, current_group) if not current_group:match '^<.*>$' then return '<' .. current_group .. ' ' .. part .. '>' @@ -167,13 +166,88 @@ local function set_buffer_lines(start_line, new_lines) vim.api.nvim_buf_set_lines(0, start_line, start_line, false, new_lines) end +-- EXPERIMENTAL +local function identify_tabs(buffer_lines) + local groups = {} + local current_group = {} + local current_tab = {} + local blank_line_count = 0 + + for _, line in ipairs(buffer_lines) do + if line:match '^%u%u ' then -- Line belongs to a drum tab part + blank_line_count = 0 + table.insert(current_tab, line) + elseif line:match '^%s*$' then -- Empty line encountered + blank_line_count = blank_line_count + 1 + if blank_line_count == 1 then + if #current_tab > 0 then + table.insert(current_group, current_tab) + current_tab = {} + end + elseif blank_line_count > 1 then + if #current_group > 0 then + table.insert(groups, current_group) + current_group = {} + end + end + end + end + + -- Add the last tab and group if they exist + if #current_tab > 0 then + table.insert(current_group, current_tab) + end + if #current_group > 0 then + table.insert(groups, current_group) + end + + return groups +end + +local function merge_tabs_within_group(group) + local merged_tabs = {} + + for _, tab in ipairs(group) do + for _, line in ipairs(tab) do + local part_name = line:sub(1, 2) + local part_content = line:sub(4) + + if not merged_tabs[part_name] then + merged_tabs[part_name] = part_content + else + merged_tabs[part_name] = merged_tabs[part_name] .. part_content:gsub('^|', '') + end + end + end + + return merged_tabs +end + +local function print_merged_tabs_and_groups(groups) + for _, group in ipairs(groups) do + local merged_tabs = merge_tabs_within_group(group) + + for part_name, part_content in pairs(merged_tabs) do + vim.api.nvim_buf_set_lines(0, -1, -1, false, { part_name .. ' ' .. part_content, }) + end + vim.api.nvim_buf_set_lines(0, -1, -1, false, { '', }) -- Insert an empty line after each merged tab group + + -- Add separator if there are more groups + if _ < #groups then + vim.api.nvim_buf_set_lines(0, -1, -1, false, { '---', '', }) + end + end +end + +-- EXPERIMENTAL END + local function show_measure_count() local measures = parse_measure_count() local lines = get_buffer_lines(0, -1) - local tab1 = { unpack(lines, 1, 4), } - local tab2 = { unpack(lines, 6, 9), } - local merged_tab = merge_drum_tabs(tab1, tab2) + -- local tab1 = { unpack(lines, 1, 4), } + -- local tab2 = { unpack(lines, 6, 9), } + -- local merged_tab = merge_drum_tabs(tab1, tab2) vim.cmd 'new' @@ -181,11 +255,11 @@ local function show_measure_count() vim.api.nvim_buf_set_lines(0, 0, -1, false, { 'Number of measures: ' .. measures, }) -- vim.api.nvim_buf_set_lines(0, 0, -1, false, { 'result: ' .. table.concat(merged_tab, ' '), }) -- vim.api.nvim_buf_set_lines(0, 0, -1, false, merged_tab) - set_buffer_lines(#lines, merged_tab) + -- set_buffer_lines(#lines, merged_tab) + local groups = identify_tabs(lines) + print_merged_tabs_and_groups(groups) end --- EXPERIMENTAL END - -- Function to draw the empty 4/4 drum tablature function M.setup() From 9b774b7f43ba836cf01cd85293e67f1fe359bd8f Mon Sep 17 00:00:00 2001 From: Jacopo Binosi aka bainos Date: Wed, 14 Aug 2024 21:14:06 +0200 Subject: [PATCH 5/8] lilypondify drumtabs --- lua/plugins/b_drumtab.lua | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/lua/plugins/b_drumtab.lua b/lua/plugins/b_drumtab.lua index 89c5db6..1181296 100644 --- a/lua/plugins/b_drumtab.lua +++ b/lua/plugins/b_drumtab.lua @@ -111,17 +111,12 @@ local function parse_drum_table(drum_table) return result end -local function merge_drum_tabs(tab1, tab2) +local function lilypondify(tab1) local result = {} - for i = 1, #tab1 do - local part1 = tab1[i] - local part2 = tab2[i] - - local merged_line = part1:sub(1, 4) .. part1:sub(5) .. part2:sub(5) - -- merged_line = merged_line:gsub('|', '') - local drum_part = merged_line:sub(1, 2) -- Extract the drum part (e.g., 'CC') - local pattern = merged_line:sub(4) -- Extract the rest of the line (the pattern) + for part_name, part_content in pairs(tab1) do + local drum_part = part_name + local pattern = part_content for j = 1, #pattern do local char = pattern:sub(j, j) @@ -131,7 +126,6 @@ local function merge_drum_tabs(tab1, tab2) if result[j] == nil or result[j] == '-' then result[j] = drum_part .. char else - -- result[j] = result[j] .. ',' .. drum_part .. char result[j] = add_to_group(drum_part .. char, result[j]) end else @@ -162,10 +156,10 @@ local function get_buffer_lines(start_line, end_line) return vim.api.nvim_buf_get_lines(0, start_line, end_line, false) end -local function set_buffer_lines(start_line, new_lines) - vim.api.nvim_buf_set_lines(0, start_line, start_line, false, new_lines) -end - +-- local function set_buffer_lines(start_line, new_lines) +-- vim.api.nvim_buf_set_lines(0, start_line, start_line, false, new_lines) +-- end +-- -- EXPERIMENTAL local function identify_tabs(buffer_lines) local groups = {} @@ -220,15 +214,15 @@ local function merge_tabs_within_group(group) end end - return merged_tabs + return lilypondify(merged_tabs) end local function print_merged_tabs_and_groups(groups) for _, group in ipairs(groups) do local merged_tabs = merge_tabs_within_group(group) - for part_name, part_content in pairs(merged_tabs) do - vim.api.nvim_buf_set_lines(0, -1, -1, false, { part_name .. ' ' .. part_content, }) + for i = 1, #merged_tabs do + vim.api.nvim_buf_set_lines(0, -1, -1, false, { merged_tabs[i], }) end vim.api.nvim_buf_set_lines(0, -1, -1, false, { '', }) -- Insert an empty line after each merged tab group From d5729ed9b773aace7f700d2469edd4c3f85b26dc Mon Sep 17 00:00:00 2001 From: Jacopo Binosi aka bainos Date: Wed, 14 Aug 2024 23:56:45 +0200 Subject: [PATCH 6/8] fix duplicate var --- lua/plugins/b_drumtab.lua | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/lua/plugins/b_drumtab.lua b/lua/plugins/b_drumtab.lua index 1181296..1341eae 100644 --- a/lua/plugins/b_drumtab.lua +++ b/lua/plugins/b_drumtab.lua @@ -66,8 +66,7 @@ local function parse_measure_count() if tab_lines > 0 then local pipes = total_pipes - tab_lines local total_measures = pipes / #drum_parts - return total_measures .. ' | ' .. pipes - .. ' / ' .. tab_lines + return total_measures else return 0 end @@ -115,18 +114,16 @@ local function lilypondify(tab1) local result = {} for part_name, part_content in pairs(tab1) do - local drum_part = part_name - local pattern = part_content - for j = 1, #pattern do - local char = pattern:sub(j, j) + for j = 1, #part_content do + local char = part_content:sub(j, j) if char == '|' then result[j] = char elseif char ~= '-' then if result[j] == nil or result[j] == '-' then - result[j] = drum_part .. char + result[j] = part_name .. char else - result[j] = add_to_group(drum_part .. char, result[j]) + result[j] = add_to_group(part_name .. char, result[j]) end else if result[j] == nil then From 5e7b10b98c8519ef1e2c3009ed820c056f0ca3b2 Mon Sep 17 00:00:00 2001 From: Jacopo Binosi aka bainos Date: Tue, 20 Aug 2024 12:35:02 +0200 Subject: [PATCH 7/8] ful refactoring --- lua/plugins/b_drumtab.lua | 223 ++++++++++++++++++-------------------- 1 file changed, 105 insertions(+), 118 deletions(-) diff --git a/lua/plugins/b_drumtab.lua b/lua/plugins/b_drumtab.lua index 1341eae..fbaff28 100644 --- a/lua/plugins/b_drumtab.lua +++ b/lua/plugins/b_drumtab.lua @@ -7,6 +7,9 @@ local drum_parts = { 'BD', } +-- ---------------- +-- DRAW DRUMTABS +-- ---------------- -- Function to draw the drum tablature with dynamic measures and beats local function draw_drum_tab(args) -- Parse the arguments: measures, beats per measure, note value, subdivisions @@ -46,33 +49,9 @@ local function draw_drum_tab(args) vim.api.nvim_win_set_cursor(0, { cursor[1] - 4, cursor[2] + 4, }) end -local function parse_measure_count() - local buf_lines = vim.api.nvim_buf_get_lines(0, 0, -1, false) - local total_pipes = 0 - local tab_lines = 0 - - for _, line in ipairs(buf_lines) do - -- Count the number of '|' characters in the line - local pipe_count = select(2, line:gsub('|', '|')) - total_pipes = total_pipes + pipe_count - - -- Count the line if it has at least 2 pipes - if pipe_count >= 2 then - tab_lines = tab_lines + 1 - end - end - - -- Calculate total measures - if tab_lines > 0 then - local pipes = total_pipes - tab_lines - local total_measures = pipes / #drum_parts - return total_measures - else - return 0 - end -end - - +-- ---------------- +-- PARSE DRUMTABS +-- ---------------- local function add_to_group(part, current_group) if not current_group:match '^<.*>$' then return '<' .. current_group .. ' ' .. part .. '>' @@ -82,82 +61,139 @@ local function add_to_group(part, current_group) end end -local function parse_drum_table(drum_table) +local function parse_drum_linline(line, time_sig, subdivision) local result = {} local current_unit = '' local current_length = 1 + local beats, beat_unit = time_sig:match '(%d+)/(%d+)' + beats = tonumber(beats) + beat_unit = tonumber(beat_unit) + local dash_length = beat_unit * subdivision + + vim.notify('line: ' .. vim.inspect(line)) + for i = 1, #line do + if line[i] == '-' and line[i - 1] == '|' then + line[i] = 'RRr' + end - for i = 1, #drum_table do - if drum_table[i] == '-' then - if i == 1 then - current_unit = 'RRr' - else - current_length = current_length + 1 - end - else + if line[i] == '|' or line[i] ~= '-' then if current_unit ~= '' then - table.insert(result, current_unit .. current_length) + local note_length = dash_length / current_length + vim.notify('note_length: ' .. tostring(note_length)) + table.insert(result, current_unit .. note_length) end - current_unit = drum_table[i] + current_length = 1 + current_unit = (line[i] == '|' and '') or line[i] + else + current_length = current_length + 1 end - end - if current_unit ~= '' then - table.insert(result, current_unit .. current_length) + vim.notify(line[i] .. ' ' .. tostring(current_length)) end + -- for i = 1, #line do + -- if i % beat_unit == 1 and line[i] == '-' then + -- line[i] = 'RRr' + -- end + -- if line[i] == '-' then + -- current_length = current_length + 1 + -- else + -- if current_unit ~= '' then + -- local note_length = dash_length / current_length + -- table.insert(result, current_unit .. note_length) + -- end + -- current_unit = line[i] + -- current_length = 1 + -- end + -- end + -- + -- if current_unit ~= '' then + -- local note_length = dash_length / current_length + -- table.insert(result, current_unit .. note_length) + -- end + return result end -local function lilypondify(tab1) - local result = {} +local function tab_subdivision(tab_line) + local _, first_pipe_end = tab_line:find '|' + local second_pipe_start = tab_line:find('|', first_pipe_end + 1) + return second_pipe_start - first_pipe_end - 1 +end - for part_name, part_content in pairs(tab1) do - for j = 1, #part_content do - local char = part_content:sub(j, j) +local function collapse_rows(tab) + local time_sig = tab[1]:match '^TS (%d+/%d+)' + if time_sig then + table.remove(tab, 1) + else + time_sig = '4/4' + end + + local subdivision = tab_subdivision(tab[1]) + + local result = {} + for _, line in ipairs(tab) do + local part_name = line:sub(1, 2) + local part_content = line:sub(4) + local j = 1 + for i = 1, #part_content do + local char = part_content:sub(i, i) if char == '|' then result[j] = char + j = j + 1 elseif char ~= '-' then if result[j] == nil or result[j] == '-' then result[j] = part_name .. char + j = j + 1 else result[j] = add_to_group(part_name .. char, result[j]) + j = j + 1 end else if result[j] == nil then result[j] = char end + j = j + 1 end end end - local drum_table = {} - local line_tmp = {} - for i = 1, #result do - if result[i] == '|' then - table.insert(drum_table, - table.concat( - parse_drum_table(line_tmp), ' ')) - line_tmp = {} - else - table.insert(line_tmp, result[i]) + return parse_drum_linline(result, time_sig, subdivision) +end + +local function merge_tabs_within_group(group) + local merged_tabs = {} + + for _, tab in ipairs(group) do + tab = collapse_rows(tab) + vim.notify('collapsed tab: ' .. vim.inspect(tab)) + + for _, v in ipairs(tab) do + table.insert(merged_tabs, v) end end - -- return merged_tab - return drum_table + + return merged_tabs end -local function get_buffer_lines(start_line, end_line) - return vim.api.nvim_buf_get_lines(0, start_line, end_line, false) +local function print_merged_tabs_and_groups(groups) + for _, group in ipairs(groups) do + local merged_tabs = merge_tabs_within_group(group) + + for i = 1, #merged_tabs do + vim.api.nvim_buf_set_lines(0, -1, -1, false, { merged_tabs[i], }) + end + vim.api.nvim_buf_set_lines(0, -1, -1, false, { '', }) -- Insert an empty line after each merged tab group + + -- Add separator if there are more groups + if _ < #groups then + vim.api.nvim_buf_set_lines(0, -1, -1, false, { '---', '', }) + end + end end --- local function set_buffer_lines(start_line, new_lines) --- vim.api.nvim_buf_set_lines(0, start_line, start_line, false, new_lines) --- end --- --- EXPERIMENTAL local function identify_tabs(buffer_lines) local groups = {} local current_group = {} @@ -195,58 +231,11 @@ local function identify_tabs(buffer_lines) return groups end -local function merge_tabs_within_group(group) - local merged_tabs = {} - - for _, tab in ipairs(group) do - for _, line in ipairs(tab) do - local part_name = line:sub(1, 2) - local part_content = line:sub(4) - - if not merged_tabs[part_name] then - merged_tabs[part_name] = part_content - else - merged_tabs[part_name] = merged_tabs[part_name] .. part_content:gsub('^|', '') - end - end - end - - return lilypondify(merged_tabs) -end - -local function print_merged_tabs_and_groups(groups) - for _, group in ipairs(groups) do - local merged_tabs = merge_tabs_within_group(group) - - for i = 1, #merged_tabs do - vim.api.nvim_buf_set_lines(0, -1, -1, false, { merged_tabs[i], }) - end - vim.api.nvim_buf_set_lines(0, -1, -1, false, { '', }) -- Insert an empty line after each merged tab group - - -- Add separator if there are more groups - if _ < #groups then - vim.api.nvim_buf_set_lines(0, -1, -1, false, { '---', '', }) - end - end -end - --- EXPERIMENTAL END - -local function show_measure_count() - local measures = parse_measure_count() - local lines = get_buffer_lines(0, -1) - - -- local tab1 = { unpack(lines, 1, 4), } - -- local tab2 = { unpack(lines, 6, 9), } - -- local merged_tab = merge_drum_tabs(tab1, tab2) +local function lilypondify() + local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false) vim.cmd 'new' - -- Write the number of measures into the buffer - vim.api.nvim_buf_set_lines(0, 0, -1, false, { 'Number of measures: ' .. measures, }) - -- vim.api.nvim_buf_set_lines(0, 0, -1, false, { 'result: ' .. table.concat(merged_tab, ' '), }) - -- vim.api.nvim_buf_set_lines(0, 0, -1, false, merged_tab) - -- set_buffer_lines(#lines, merged_tab) local groups = identify_tabs(lines) print_merged_tabs_and_groups(groups) end @@ -261,11 +250,9 @@ function M.setup() vim.opt.breakindentopt = 'shift:4,sbr' vim.opt.breakat = '|' - -- Create a command to run the function with arguments - vim.api.nvim_create_user_command('DrawDrumTab', draw_drum_tab, { nargs = 1, }) + vim.api.nvim_create_user_command('DrumTabDraw', draw_drum_tab, { nargs = 1, }) - -- Create the command to show the measure count - vim.api.nvim_create_user_command('ShowMeasureCount', show_measure_count, {}) + vim.api.nvim_create_user_command('DrumTabLilypondify', lilypondify, {}) end return M From e47f8af53eded46c5280bae983504cd2a24d6447 Mon Sep 17 00:00:00 2001 From: Jacopo Binosi aka bainos Date: Fri, 23 Aug 2024 00:01:57 +0200 Subject: [PATCH 8/8] it starts working --- lua/plugins/b_drumtab.lua | 98 +++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 56 deletions(-) diff --git a/lua/plugins/b_drumtab.lua b/lua/plugins/b_drumtab.lua index fbaff28..d152d41 100644 --- a/lua/plugins/b_drumtab.lua +++ b/lua/plugins/b_drumtab.lua @@ -61,65 +61,42 @@ local function add_to_group(part, current_group) end end -local function parse_drum_linline(line, time_sig, subdivision) - local result = {} - local current_unit = '' - local current_length = 1 +local function parse_drum_tab(dtab, time_sig) local beats, beat_unit = time_sig:match '(%d+)/(%d+)' beats = tonumber(beats) beat_unit = tonumber(beat_unit) - local dash_length = beat_unit * subdivision - - vim.notify('line: ' .. vim.inspect(line)) - for i = 1, #line do - if line[i] == '-' and line[i - 1] == '|' then - line[i] = 'RRr' - end - if line[i] == '|' or line[i] ~= '-' then - if current_unit ~= '' then - local note_length = dash_length / current_length - vim.notify('note_length: ' .. tostring(note_length)) - table.insert(result, current_unit .. note_length) + local dt = {} + for _, measure in ipairs(dtab) do + local m = {} + local current_unit = '' + local current_length = 1 + local dash_length = beat_unit * #measure + for i = 1, #measure do + if measure[i] == '-' and i == 1 then + measure[i] = 'RRr' end - current_length = 1 - current_unit = (line[i] == '|' and '') or line[i] - else - current_length = current_length + 1 - end + if measure[i] ~= '-' then + if current_unit ~= '' then + local note_length = dash_length / current_length + table.insert(m, current_unit .. note_length) + end - vim.notify(line[i] .. ' ' .. tostring(current_length)) + current_length = 1 + current_unit = measure[i] + else + current_length = current_length + 1 + end + end + if current_unit ~= '' then + local note_length = dash_length / current_length + table.insert(m, current_unit .. note_length) + end + table.insert(dt, m) end - -- for i = 1, #line do - -- if i % beat_unit == 1 and line[i] == '-' then - -- line[i] = 'RRr' - -- end - -- if line[i] == '-' then - -- current_length = current_length + 1 - -- else - -- if current_unit ~= '' then - -- local note_length = dash_length / current_length - -- table.insert(result, current_unit .. note_length) - -- end - -- current_unit = line[i] - -- current_length = 1 - -- end - -- end - -- - -- if current_unit ~= '' then - -- local note_length = dash_length / current_length - -- table.insert(result, current_unit .. note_length) - -- end - - return result -end - -local function tab_subdivision(tab_line) - local _, first_pipe_end = tab_line:find '|' - local second_pipe_start = tab_line:find('|', first_pipe_end + 1) - return second_pipe_start - first_pipe_end - 1 + return dt end local function collapse_rows(tab) @@ -130,8 +107,6 @@ local function collapse_rows(tab) time_sig = '4/4' end - local subdivision = tab_subdivision(tab[1]) - local result = {} for _, line in ipairs(tab) do local part_name = line:sub(1, 2) @@ -160,7 +135,20 @@ local function collapse_rows(tab) end end - return parse_drum_linline(result, time_sig, subdivision) + local dtab = {} + local measure = {} + for _, e in ipairs(result) do + if e == '|' then + if #measure > 0 then + table.insert(dtab, measure) + measure = {} + end + else + table.insert(measure, e) + end + end + + return parse_drum_tab(dtab, time_sig) end local function merge_tabs_within_group(group) @@ -168,8 +156,6 @@ local function merge_tabs_within_group(group) for _, tab in ipairs(group) do tab = collapse_rows(tab) - vim.notify('collapsed tab: ' .. vim.inspect(tab)) - for _, v in ipairs(tab) do table.insert(merged_tabs, v) end @@ -183,7 +169,7 @@ local function print_merged_tabs_and_groups(groups) local merged_tabs = merge_tabs_within_group(group) for i = 1, #merged_tabs do - vim.api.nvim_buf_set_lines(0, -1, -1, false, { merged_tabs[i], }) + vim.api.nvim_buf_set_lines(0, -1, -1, false, { table.concat(merged_tabs[i], ' '), }) end vim.api.nvim_buf_set_lines(0, -1, -1, false, { '', }) -- Insert an empty line after each merged tab group