forked from mia/Aegisub
Add extradata reading/writing to Auto4 Lua
This commit is contained in:
parent
040b467090
commit
159dfcde39
4 changed files with 43 additions and 8 deletions
|
@ -56,6 +56,7 @@
|
||||||
#include <libaegisub/util.h>
|
#include <libaegisub/util.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <boost/algorithm/string/case_conv.hpp>
|
||||||
#include <boost/algorithm/string/classification.hpp>
|
#include <boost/algorithm/string/classification.hpp>
|
||||||
#include <boost/algorithm/string/join.hpp>
|
#include <boost/algorithm/string/join.hpp>
|
||||||
#include <boost/algorithm/string/predicate.hpp>
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
|
@ -274,6 +275,17 @@ namespace {
|
||||||
luaL_argcheck(L, lua_istable(L, 1), 1, "");
|
luaL_argcheck(L, lua_istable(L, 1), 1, "");
|
||||||
luaL_argcheck(L, lua_isstring(L, 2), 2, "");
|
luaL_argcheck(L, lua_isstring(L, 2), 2, "");
|
||||||
|
|
||||||
|
// have to check that it looks like a style table before actually converting
|
||||||
|
// if it's a dialogue table then an active AssFile object is required
|
||||||
|
{
|
||||||
|
lua_getfield(L, 1, "class");
|
||||||
|
std::string actual_class{lua_tostring(L, -1)};
|
||||||
|
boost::to_lower(actual_class);
|
||||||
|
if (actual_class != "style")
|
||||||
|
return luaL_error(L, "Not a style entry");
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
lua_pushvalue(L, 1);
|
lua_pushvalue(L, 1);
|
||||||
std::unique_ptr<AssEntry> et(Automation4::LuaAssFile::LuaToAssEntry(L));
|
std::unique_ptr<AssEntry> et(Automation4::LuaAssFile::LuaToAssEntry(L));
|
||||||
auto st = dynamic_cast<AssStyle*>(et.get());
|
auto st = dynamic_cast<AssStyle*>(et.get());
|
||||||
|
|
|
@ -124,7 +124,7 @@ namespace Automation4 {
|
||||||
/// makes a Lua representation of AssEntry and places on the top of the stack
|
/// makes a Lua representation of AssEntry and places on the top of the stack
|
||||||
void AssEntryToLua(lua_State *L, size_t idx);
|
void AssEntryToLua(lua_State *L, size_t idx);
|
||||||
/// assumes a Lua representation of AssEntry on the top of the stack, and creates an AssEntry object of it
|
/// assumes a Lua representation of AssEntry on the top of the stack, and creates an AssEntry object of it
|
||||||
static std::unique_ptr<AssEntry> LuaToAssEntry(lua_State *L);
|
static std::unique_ptr<AssEntry> LuaToAssEntry(lua_State *L, AssFile *ass=0);
|
||||||
|
|
||||||
/// @brief Signal that the script using this file is now done running
|
/// @brief Signal that the script using this file is now done running
|
||||||
/// @param set_undo If there's any uncommitted changes to the file,
|
/// @param set_undo If there's any uncommitted changes to the file,
|
||||||
|
|
|
@ -173,6 +173,15 @@ namespace Automation4 {
|
||||||
|
|
||||||
set_field(L, "text", dia->Text);
|
set_field(L, "text", dia->Text);
|
||||||
|
|
||||||
|
// create extradata table
|
||||||
|
lua_newtable(L);
|
||||||
|
for (auto const& ed : ass->GetExtradata(dia->ExtradataIds)) {
|
||||||
|
push_value(L, ed.first);
|
||||||
|
push_value(L, ed.second);
|
||||||
|
lua_settable(L, -3);
|
||||||
|
}
|
||||||
|
lua_setfield(L, -2, "extra");
|
||||||
|
|
||||||
set_field(L, "class", "dialogue");
|
set_field(L, "class", "dialogue");
|
||||||
}
|
}
|
||||||
else if (auto sty = dynamic_cast<const AssStyle*>(e)) {
|
else if (auto sty = dynamic_cast<const AssStyle*>(e)) {
|
||||||
|
@ -221,7 +230,7 @@ namespace Automation4 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<AssEntry> LuaAssFile::LuaToAssEntry(lua_State *L)
|
std::unique_ptr<AssEntry> LuaAssFile::LuaToAssEntry(lua_State *L, AssFile *ass)
|
||||||
{
|
{
|
||||||
// assume an assentry table is on the top of the stack
|
// assume an assentry table is on the top of the stack
|
||||||
// convert it to a real AssEntry object, and pop the table from the stack
|
// convert it to a real AssEntry object, and pop the table from the stack
|
||||||
|
@ -271,6 +280,7 @@ namespace Automation4 {
|
||||||
sty->UpdateData();
|
sty->UpdateData();
|
||||||
}
|
}
|
||||||
else if (lclass == "dialogue") {
|
else if (lclass == "dialogue") {
|
||||||
|
assert(ass != 0); // since we need AssFile::AddExtradata
|
||||||
auto dia = new AssDialogue;
|
auto dia = new AssDialogue;
|
||||||
result.reset(dia);
|
result.reset(dia);
|
||||||
|
|
||||||
|
@ -285,6 +295,18 @@ namespace Automation4 {
|
||||||
dia->Margin[2] = get_int_field(L, "margin_t", "dialogue");
|
dia->Margin[2] = get_int_field(L, "margin_t", "dialogue");
|
||||||
dia->Effect = get_string_field(L, "effect", "dialogue");
|
dia->Effect = get_string_field(L, "effect", "dialogue");
|
||||||
dia->Text = get_string_field(L, "text", "dialogue");
|
dia->Text = get_string_field(L, "text", "dialogue");
|
||||||
|
|
||||||
|
lua_getfield(L, -1, "extra");
|
||||||
|
std::vector<uint32_t> new_ids;
|
||||||
|
lua_pushnil(L);
|
||||||
|
while (lua_next(L, -2)) {
|
||||||
|
auto key = get_string_or_default(L, -2);
|
||||||
|
auto value = get_string_or_default(L, -1);
|
||||||
|
new_ids.push_back(ass->AddExtradata(key, value));
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
dia->ExtradataIds = new_ids;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
luaL_error(L, "Found line with unknown class: %s", lclass.c_str());
|
luaL_error(L, "Found line with unknown class: %s", lclass.c_str());
|
||||||
|
@ -422,7 +444,7 @@ namespace Automation4 {
|
||||||
// insert
|
// insert
|
||||||
CheckBounds(n);
|
CheckBounds(n);
|
||||||
|
|
||||||
auto e = LuaToAssEntry(L);
|
auto e = LuaToAssEntry(L, ass);
|
||||||
modification_type |= modification_mask(e.get());
|
modification_type |= modification_mask(e.get());
|
||||||
QueueLineForDeletion(n - 1);
|
QueueLineForDeletion(n - 1);
|
||||||
AssignLine(n - 1, std::move(e));
|
AssignLine(n - 1, std::move(e));
|
||||||
|
@ -511,7 +533,7 @@ namespace Automation4 {
|
||||||
|
|
||||||
for (int i = 1; i <= n; i++) {
|
for (int i = 1; i <= n; i++) {
|
||||||
lua_pushvalue(L, i);
|
lua_pushvalue(L, i);
|
||||||
auto e = LuaToAssEntry(L);
|
auto e = LuaToAssEntry(L, ass);
|
||||||
modification_type |= modification_mask(e.get());
|
modification_type |= modification_mask(e.get());
|
||||||
|
|
||||||
if (lines.empty()) {
|
if (lines.empty()) {
|
||||||
|
@ -555,7 +577,7 @@ namespace Automation4 {
|
||||||
new_entries.reserve(n - 1);
|
new_entries.reserve(n - 1);
|
||||||
for (int i = 2; i <= n; i++) {
|
for (int i = 2; i <= n; i++) {
|
||||||
lua_pushvalue(L, i);
|
lua_pushvalue(L, i);
|
||||||
auto e = LuaToAssEntry(L);
|
auto e = LuaToAssEntry(L, ass);
|
||||||
modification_type |= modification_mask(e.get());
|
modification_type |= modification_mask(e.get());
|
||||||
InsertLine(new_entries, i - 2, std::move(e));
|
InsertLine(new_entries, i - 2, std::move(e));
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
@ -594,7 +616,7 @@ namespace Automation4 {
|
||||||
|
|
||||||
int LuaAssFile::LuaParseKaraokeData(lua_State *L)
|
int LuaAssFile::LuaParseKaraokeData(lua_State *L)
|
||||||
{
|
{
|
||||||
auto e = LuaToAssEntry(L);
|
auto e = LuaToAssEntry(L, ass);
|
||||||
auto dia = dynamic_cast<AssDialogue*>(e.get());
|
auto dia = dynamic_cast<AssDialogue*>(e.get());
|
||||||
luaL_argcheck(L, dia, 1, "Subtitle line must be a dialogue line");
|
luaL_argcheck(L, dia, 1, "Subtitle line must be a dialogue line");
|
||||||
|
|
||||||
|
|
|
@ -71,10 +71,11 @@ inline wxString check_wxstring(lua_State *L, int idx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string get_string_or_default(lua_State *L, int idx) {
|
inline std::string get_string_or_default(lua_State *L, int idx) {
|
||||||
const char *str = lua_tostring(L, idx);
|
size_t len = 0;
|
||||||
|
const char *str = lua_tolstring(L, idx, &len);
|
||||||
if (!str)
|
if (!str)
|
||||||
str = "<not a string>";
|
str = "<not a string>";
|
||||||
return str;
|
return std::string(str, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string get_global_string(lua_State *L, const char *name) {
|
inline std::string get_global_string(lua_State *L, const char *name) {
|
||||||
|
|
Loading…
Reference in a new issue