From 02a2f97a593b0735af02532d206b34f9988c734d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 15 Feb 2016 08:39:50 +0000 Subject: [PATCH] Basic support for parsing in-line markup in SSA. --- src/ssa_reader.cc | 63 +++++++++++++++++++++++++++++++++++++++++ src/ssa_reader.h | 2 ++ test/ssa_reader_test.cc | 38 +++++++++++++++++++++++++ 3 files changed, 103 insertions(+) diff --git a/src/ssa_reader.cc b/src/ssa_reader.cc index d4908a2..703ed26 100644 --- a/src/ssa_reader.cc +++ b/src/ssa_reader.cc @@ -34,6 +34,7 @@ using std::stringstream; using std::vector; using std::map; using std::cout; +using std::list; using boost::optional; using boost::function; using namespace boost::algorithm; @@ -137,6 +138,68 @@ SSAReader::parse_time (string t) const ); } +list +SSAReader::parse_line (RawSubtitle base, string line) +{ + enum { + TEXT, + STYLE, + BACKSLASH + } state = TEXT; + + list subs; + RawSubtitle current = base; + string style; + + current.vertical_position.line = 0; + + for (size_t i = 0; i < line.length(); ++i) { + char const c = line[i]; + switch (state) { + case TEXT: + if (c == '{') { + state = STYLE; + } else if (c == '\\') { + state = BACKSLASH; + } else { + current.text += c; + } + break; + case STYLE: + if (c == '}') { + if (!current.text.empty ()) { + subs.push_back (current); + current.text = ""; + } + if (style == "i1") { + current.italic = true; + } else if (style == "i0") { + current.italic = false; + } + style = ""; + state = TEXT; + } else { + style += c; + } + break; + case BACKSLASH: + if (c == 'n' && !current.text.empty ()) { + subs.push_back (current); + current.text = ""; + current.vertical_position.line = current.vertical_position.line.get() + 1; + } + state = TEXT; + break; + } + } + + if (!current.text.empty ()) { + subs.push_back (current); + } + + return subs; +} + void SSAReader::read (function ()> get_line) { diff --git a/src/ssa_reader.h b/src/ssa_reader.h index 0f575ff..1fe64f3 100644 --- a/src/ssa_reader.h +++ b/src/ssa_reader.h @@ -35,6 +35,8 @@ public: SSAReader (FILE* f); SSAReader (std::string const & subs); + static std::list parse_line (RawSubtitle base, std::string line); + private: void read (boost::function ()> get_line); Time parse_time (std::string t) const; diff --git a/test/ssa_reader_test.cc b/test/ssa_reader_test.cc index c7594d7..97626a6 100644 --- a/test/ssa_reader_test.cc +++ b/test/ssa_reader_test.cc @@ -69,3 +69,41 @@ BOOST_AUTO_TEST_CASE (ssa_reader_test) BOOST_CHECK (i == subs.end()); } + +BOOST_AUTO_TEST_CASE (ssa_reader_line_test1) +{ + sub::RawSubtitle base; + list r = sub::SSAReader::parse_line (base, "This is a line with some {i1}italics{i0} and then\\nthere is a new line."); + + list::const_iterator i = r.begin (); + BOOST_CHECK_EQUAL (i->text, "This is a line with some "); + BOOST_CHECK_EQUAL (i->italic, false); + ++i; + BOOST_REQUIRE (i != r.end ()); + + BOOST_CHECK_EQUAL (i->text, "italics"); + BOOST_CHECK_EQUAL (i->italic, true); + ++i; + BOOST_REQUIRE (i != r.end ()); + + BOOST_CHECK_EQUAL (i->text, " and then"); + BOOST_CHECK_EQUAL (i->italic, false); + ++i; + BOOST_REQUIRE (i != r.end ()); + + BOOST_CHECK_EQUAL (i->text, "there is a new line."); + ++i; + BOOST_REQUIRE (i == r.end ()); +} + +BOOST_AUTO_TEST_CASE (ssa_reader_line_test2) +{ + sub::RawSubtitle base; + list r = sub::SSAReader::parse_line (base, "{i1}It's all just italics{i0}"); + + list::const_iterator i = r.begin (); + BOOST_CHECK_EQUAL (i->text, "It's all just italics"); + BOOST_CHECK_EQUAL (i->italic, true); + ++i; + BOOST_REQUIRE (i == r.end ()); +} -- 2.30.2