forked from mia/Aegisub
Seemingly working furigana/multi-hl parsing and some untested inline-fx parsing. Still no furigana layouting, and the parsing isn't integrated yet.
Originally committed to SVN as r1180.
This commit is contained in:
parent
2c8c6977d5
commit
9ae7be4443
3 changed files with 152 additions and 3 deletions
|
@ -116,21 +116,118 @@ function karaskel.preproc_line_text(meta, styles, line)
|
||||||
line.kara = { n = 0 }
|
line.kara = { n = 0 }
|
||||||
line.furi = { n = 0 }
|
line.furi = { n = 0 }
|
||||||
|
|
||||||
|
if styles[line.style] then
|
||||||
|
line.styleref = styles[line.style]
|
||||||
|
else
|
||||||
|
aegisub.debug.out(2, "WARNING: Style not found: " .. line.style .. "\n")
|
||||||
|
line.styleref = styles[1]
|
||||||
|
end
|
||||||
|
|
||||||
line.text_stripped = ""
|
line.text_stripped = ""
|
||||||
line.duration = line.end_time - line.start_time
|
line.duration = line.end_time - line.start_time
|
||||||
|
|
||||||
local worksyl = { }
|
local worksyl = { highlights = {n=0} }
|
||||||
local cur_inline_fx = ""
|
local cur_inline_fx = ""
|
||||||
for i = 0, #kara do
|
for i = 0, #kara do
|
||||||
local syl = kara[i]
|
local syl = kara[i]
|
||||||
|
|
||||||
-- Detect any inline-fx tags
|
-- Detect any inline-fx tags
|
||||||
local inline_fx = syl.text:match("%{.*\\%-(.-)[}\\]")
|
local inline_fx = syl.text:match("%{.*\\%-([^}\\]-)")
|
||||||
if inline_fx then
|
if inline_fx then
|
||||||
cur_inline_fx = inline_fx
|
cur_inline_fx = inline_fx
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Strip spaces (only basic ones, no fullwidth etc.)
|
||||||
|
local prespace, syltext, postspace = syl.text_stripped:match("^([ \t]*)(.-)([ \t]*)$")
|
||||||
|
|
||||||
|
-- See if we've broken a (possible) multi-hl stretch
|
||||||
|
-- If we did it's time for a new worksyl (though never for the zero'th syllable)
|
||||||
|
local prefix = syltext:sub(1,unicode.charwidth(syltext,1))
|
||||||
|
if prefix ~= "#" and prefix ~= "#" and i > 0 then
|
||||||
|
line.kara[line.kara.n] = worksyl
|
||||||
|
line.kara.n = line.kara.n + 1
|
||||||
|
worksyl = { highlights = {n=0} }
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Detect furigana (both regular and fullwidth pipes work)
|
||||||
|
-- Furigana is stored independantly from syllables
|
||||||
|
if syltext:find("|") or syltext:find("|") then
|
||||||
|
-- Replace fullwidth pipes, they aren't regex friendly
|
||||||
|
syltext = syltext:gsub("|", "|")
|
||||||
|
-- Get before/after pipe text
|
||||||
|
local maintext, furitext = syltext:match("^(.-)|(.-)$")
|
||||||
|
syltext = maintext
|
||||||
|
|
||||||
|
local furi = { }
|
||||||
|
furi.syl = worksyl
|
||||||
|
|
||||||
|
-- Magic happens here
|
||||||
|
-- isbreak = Don't join this furi visually with previous furi, even if their main texts are adjacent
|
||||||
|
-- spillback = Allow this furi text to spill over the left edge of the main text
|
||||||
|
-- (Furi is always allowed to spill over the right edge of main text.)
|
||||||
|
local prefix = furitext:sub(1,unicode.charwidth(furitext,1))
|
||||||
|
if prefix == "!" or prefix == "!" then
|
||||||
|
furi.isbreak = true -- Don't join with furi in previous syllable
|
||||||
|
furi.spillback = false -- Allow to "spill" furi over the left edge of main text
|
||||||
|
elseif prefix == "<" or prefix == "<" then
|
||||||
|
furi.isbreak = true
|
||||||
|
furi.spillback = true
|
||||||
|
else
|
||||||
|
furi.isbreak = false
|
||||||
|
furi.spillback = false
|
||||||
|
end
|
||||||
|
-- Remove the prefix character from furitext, if there was one
|
||||||
|
if furi.isbreak then
|
||||||
|
furitext = furitext:sub(unicode.charwidth(furitext,1)+1)
|
||||||
|
end
|
||||||
|
|
||||||
|
furi.start_time = syl.start_time
|
||||||
|
furi.end_time = syl.end_time
|
||||||
|
furi.duration = syl.duration
|
||||||
|
furi.text = furitext
|
||||||
|
|
||||||
|
line.furi.n = line.furi.n + 1
|
||||||
|
line.furi[line.furi.n] = furi
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Always add highlight data
|
||||||
|
local hl = {
|
||||||
|
start_time = syl.start_time,
|
||||||
|
end_time = syl.end_time,
|
||||||
|
duration = syl.duration
|
||||||
|
}
|
||||||
|
worksyl.highlights.n = worksyl.highlights.n + 1
|
||||||
|
worksyl.highlights[worksyl.highlights.n] = hl
|
||||||
|
|
||||||
|
-- Syllables that aren't part of a multi-highlight generate a new output-syllable
|
||||||
|
if prefix ~= "#" and prefix ~= "#" then
|
||||||
|
-- Update stripped line-text
|
||||||
|
line.text_stripped = line.text_stripped .. prespace .. syltext .. postspace
|
||||||
|
|
||||||
|
-- Copy data from syl to worksyl
|
||||||
|
worksyl.text = syl.text
|
||||||
|
worksyl.duration = syl.duration
|
||||||
|
worksyl.kdur = syl.duration / 10
|
||||||
|
worksyl.start_time = syl.start_time
|
||||||
|
worksyl.end_time = syl.end_time
|
||||||
|
worksyl.tag = syl.tag
|
||||||
|
worksyl.line = line
|
||||||
|
worksyl.style = line.styleref
|
||||||
|
|
||||||
|
-- And add new data to worksyl
|
||||||
|
worksyl.i = line.kara.n
|
||||||
|
worksyl.text_stripped = syltext
|
||||||
|
worksyl.inline_fx = cur_inline_fx
|
||||||
|
else
|
||||||
|
-- This is just an extra highlight
|
||||||
|
worksyl.duration = worksyl.duration + syl.duration
|
||||||
|
worksyl.end_time = syl.end_time
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Add the last syllable
|
||||||
|
line.kara[line.kara.n] = worksyl
|
||||||
|
-- But don't increment n here, n should be the highest syllable index! (The zero'th syllable doesn't count.)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
10
automation/tests/test-auto3-parsing.auto3
Normal file
10
automation/tests/test-auto3-parsing.auto3
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
name = "Test auto3 parsing"
|
||||||
|
description = "Make sure it works"
|
||||||
|
version, kind = 3, "basic_ass"
|
||||||
|
|
||||||
|
include "karaskel-base.auto3"
|
||||||
|
|
||||||
|
function process_lines(meta, styles, lines, config)
|
||||||
|
karaskel.parse_syllable_data(meta, styles, lines)
|
||||||
|
return lines
|
||||||
|
end
|
42
automation/tests/test-furi.lua
Normal file
42
automation/tests/test-furi.lua
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
script_name = "Test furigana parsing"
|
||||||
|
script_description = "Tests the Auto4/Lua karaskel furigana and multi-highlight parsing code by running it and dumping the result"
|
||||||
|
script_author = "jfs"
|
||||||
|
|
||||||
|
include "karaskel.lua"
|
||||||
|
|
||||||
|
function test_furi(subs)
|
||||||
|
aegisub.progress.task("Collecting header data")
|
||||||
|
local meta, styles = karaskel.collect_head(subs, true) -- make sure to create furigana styles
|
||||||
|
|
||||||
|
aegisub.progress.task("Preprocessing lines")
|
||||||
|
for i = 1, #subs do
|
||||||
|
local l = subs[i]
|
||||||
|
if l.class == "dialogue" then
|
||||||
|
aegisub.progress.task(l.text)
|
||||||
|
karaskel.preproc_line_text(meta, styles, l)
|
||||||
|
|
||||||
|
-- Dump the thing
|
||||||
|
aegisub.debug.out(4, "Line: %s\nStripped: %s\nDuration: %d\n", l.text, l.text_stripped, l.duration)
|
||||||
|
aegisub.debug.out(4, "Karaoke syllables: (%d)\n", l.kara.n)
|
||||||
|
for s = 0, l.kara.n do
|
||||||
|
local syl = l.kara[s]
|
||||||
|
aegisub.debug.out(4, "\tSyllable: text='%s' stripped='%s' duration=%d, start/end_time=%d/%d, inline_fx='%s', highlights=%d\n", syl.text, syl.text_stripped, syl.duration, syl.start_time, syl.end_time, syl.inline_fx, syl.highlights.n)
|
||||||
|
aegisub.debug.out(4, "\t\tHighlights:")
|
||||||
|
for h = 1, syl.highlights.n do
|
||||||
|
local hl = syl.highlights[h]
|
||||||
|
aegisub.debug.out(4, " %d-%d=%d", hl.start_time, hl.end_time, hl.duration)
|
||||||
|
end
|
||||||
|
aegisub.debug.out(4, "\n")
|
||||||
|
end
|
||||||
|
aegisub.debug.out(4, "Furigana parts: (%d)\n", l.furi.n)
|
||||||
|
for f = 1, l.furi.n do
|
||||||
|
local furi = l.furi[f]
|
||||||
|
aegisub.debug.out(4, "\tFurigana: text='%s', duration=%d, start/end_time=%d/%d, flags=%s%s, syl='%s'\n", furi.text, furi.duration, furi.start_time, furi.end_time, furi.isbreak and "b" or "", furi.spillback and "s" or "", furi.syl.text_stripped)
|
||||||
|
end
|
||||||
|
aegisub.debug.out(4, " - - - - - -\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
aegisub.debug.out(4, "Done dumping!")
|
||||||
|
end
|
||||||
|
|
||||||
|
aegisub.register_macro(script_name, script_description, test_furi)
|
Loading…
Reference in a new issue