Skip to content
This repository was archived by the owner on Feb 20, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/ChaosTangent/ASS/Block/Block.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public function removeLine(Line $line)
}

/**
* @return array
* @return Line[]
*/
public function getLines()
{
Expand Down
4 changes: 4 additions & 0 deletions src/ChaosTangent/ASS/Line/Line.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,8 @@ public function getValue()
protected function doParse($value, array $mapping)
{
}

public function toString($mapping = []) {
return $this->key.': '.$this->value;
}
}
27 changes: 27 additions & 0 deletions src/ChaosTangent/ASS/Line/MappedLine.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,25 @@ public function applyMapping($value, array $mapping)
}
}

/**
* With a string value and an array mapping, map values to this class
*
* @param string $value
* @param array $mapping
*/
public function reverseMapping($mapping)
{
$classMapping = $this->getMapping();

$string = '';
foreach ($mapping as $attribute) {
$id = $classMapping[$attribute];
$string .= $this->{$id}.',';
}

return trim($string, ',');
}

/**
* {@inheritDoc}
*/
Expand All @@ -66,4 +85,12 @@ protected function doParse($value, array $mapping)

$this->applyMapping($value, $mapping);
}

public function toString($mapping = []) {
if (count($mapping)) {
return $this->getKey() . ': ' . $this->reverseMapping($mapping);
} else {
return parent::toString();
}
}
}
7 changes: 7 additions & 0 deletions src/ChaosTangent/ASS/Reader.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,12 @@ public function fromFile($filename)

public function fromString($string)
{
$script = new Script($string);
if (!$script->isASSScript()) {
throw new InvalidScriptException($script, 'Passed string does not look like a script');
}

$script->parse();
return $script;
}
}
2 changes: 1 addition & 1 deletion src/ChaosTangent/ASS/Script.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ public function hasBlock($block)
/**
* Get blocks
*
* @return array An array of blocks
* @return Block[] An array of blocks
*/
public function getBlocks()
{
Expand Down
45 changes: 45 additions & 0 deletions src/ChaosTangent/ASS/Writer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace ChaosTangent\ASS;

use ChaosTangent\ASS\Exception\InvalidScriptException;
use ChaosTangent\ASS\Line\Format;

/**
* Advanced Sub Station Alpha file reader
*
* @author John Noel <john.noel@chaostangent.com>
* @package php-ass
*/
class Writer
{
const VERSION = '1.0.0';

public function toFile($filename, Script $script)
{
if (!file_exists($filename) || !is_writable($filename)) {
throw new \InvalidArgumentException('Unable to write file: '.$filename);
}

file_put_contents($filename, $this->toString($script));
}

public function toString(Script $script)
{
$string = '';

foreach($script->getBlocks() as $block) {
$string .= sprintf("[%s]\n", $block->getId());
foreach($block->getLines() as $line) {
$mapping = [];
if ($line instanceof Format) {
$mapping = $line->getMapping();
}
$value = $line->toString($mapping);
$string .= sprintf("%s\n", $value);
}
}

return $string;
}
}
32 changes: 32 additions & 0 deletions tests/ChaosTangent/ASS/ScriptTest.php
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<?php

use ChaosTangent\ASS\Reader;
use ChaosTangent\ASS\Script;
use ChaosTangent\ASS\Exception\InvalidScriptException;
use ChaosTangent\ASS\Block\ScriptInfo;
use ChaosTangent\ASS\Writer;

/**
* Script test
Expand Down Expand Up @@ -121,4 +123,34 @@ public function testIterator()

$this->assertContains($block, $script);
}

/**
* @dataProvider scriptFiles
*/
public function testReadWrite($file, $expectedResultFile)
{
$outputPath = __DIR__.'/../../scripts/'.$expectedResultFile;
$expectedContent = file_get_contents($outputPath);

$reader = new Reader();
$script = $reader->fromFile(__DIR__.'/../../scripts/'.$file);

$writer = new Writer();
$newcontent = $writer->toString($script);

/*
* Expected output is not exactly the same as input, since we remove
* irrelevant information from the file (e.g. extra line feeds, comments and
* code that might've been added by editors).
*/
$this->assertEquals($expectedContent, $newcontent);
}

public function scriptFiles() {
return [
[ 'utf8.ass', 'utf8_output.ass' ],
[ 'small.ass', 'small_output.ass' ],
[ 'minimal.ass', 'minimal_output.ass' ]
];
}
}
7,702 changes: 7,702 additions & 0 deletions tests/scripts/large_output.ass

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions tests/scripts/minimal_output.ass
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[Script Info]
Title: Minimal script
ScriptType: v4.00+
WrapStyle: 0
ScaledBorderAndShadow: yes
PlayResX: 1280
PlayResY: 720
36 changes: 36 additions & 0 deletions tests/scripts/small_output.ass
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[Script Info]
Title: Default Aegisub file
ScriptType: v4.00+
WrapStyle: 0
ScaledBorderAndShadow: yes
YCbCr Matrix: TV.601
PlayResX: 1280
PlayResY: 720
[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: ED_Romaji,Minion Pro Cond,48,&H00000000,&H000000FF,&H00FFFFFF,&H00000000,-1,0,0,0,100,100,0,0,1,2,0,7,40,40,32,1
Style: ED_English,Minion Pro Cond,48,&H00000000,&H000000FF,&H00FFFFFF,&H00000000,-1,0,0,0,100,100,0,0,1,2,0,1,42,42,28,1
[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:00.98,0:00:05.43,ED_English,,0,0,0,,{\fad(100,200)\blur5\c&H000010&\3c&H80A0C0&}My destiny,
Dialogue: 0,0:00:05.42,0:00:10.56,ED_Romaji,,0,0,0,,{\fad(100,200)\blur5\c&H000010&\3c&H80A0C0&}sotto oshiete hoshii
Dialogue: 0,0:00:05.43,0:00:10.57,ED_English,,0,0,0,,{\fad(100,200)\blur5\c&H000010&\3c&H80A0C0&}won't you tell me?
Dialogue: 0,0:00:12.74,0:00:16.00,ED_Romaji,,0,0,0,,{\fad(100,200)\blur5\c&H000010&\3c&H80A0C0&}aenai
Dialogue: 0,0:00:12.75,0:00:16.01,ED_English,,0,0,0,,{\fad(100,200)\blur5\c&H000010&\3c&H80A0C0&}But you're gone
Dialogue: 0,0:00:17.05,0:00:21.43,ED_Romaji,,0,0,0,,{\fad(100,200)\blur5\c&H000010&\3c&H80A0C0&}ima wa tooi place to be
Dialogue: 0,0:00:17.06,0:00:21.44,ED_English,,0,0,0,,{\fad(100,200)\blur5\c&H000010&\3c&H80A0C0&}in a place so far away
Dialogue: 0,0:00:24.51,0:00:29.40,ED_Romaji,,0,0,0,,{\fad(100,200)\blur5\c&H000010&\3c&H80A0C0&}hitoribocchi todokanai
Dialogue: 0,0:00:24.52,0:00:29.41,ED_English,,0,0,0,,{\fad(100,200)\blur5\c&H000010&\3c&H80A0C0&}Alone and never-reaching
Dialogue: 0,0:00:29.97,0:00:35.55,ED_Romaji,,0,0,0,,{\fad(100,200)\blur5\c&H000010&\3c&H80A0C0&}oshietekureta the truth is free
Dialogue: 0,0:00:29.98,0:00:35.56,ED_English,,0,0,0,,{\fad(100,200)\blur5\c&H000010&\3c&H80A0C0&}Yet you told me the truth is free
Dialogue: 0,0:00:35.56,0:00:38.44,ED_English,,0,0,0,,{\fad(100,200)\blur5\c&H000010&\3c&H80A0C0&}I miss you
Dialogue: 0,0:00:38.44,0:00:41.05,ED_English,,0,0,0,,{\fad(100,200)\blur5\c&H000010&\3c&H80A0C0&}I revere you
Dialogue: 0,0:00:41.05,0:00:48.04,ED_English,,0,0,0,,{\fad(100,200)\blur5\c&H000010&\3c&H80A0C0&\t(0,1500,\c&H281E1D&\3c&HF9CFC2&)}You're my everything
Dialogue: 0,0:00:48.91,0:00:54.27,ED_English,,0,0,0,,{\fad(100,200)\blur5\c&H281E1D&\3c&HF9CFC2&}I will follow you
Dialogue: 0,0:00:54.26,0:01:00.22,ED_Romaji,,0,0,0,,{\fad(100,200)\blur5\c&H281E1D&\3c&HF9CFC2&}subete wa ano toki
Dialogue: 0,0:00:54.27,0:01:00.23,ED_English,,0,0,0,,{\fad(100,200)\blur5\c&H281E1D&\3c&HF9CFC2&}For everything since then
Dialogue: 0,0:01:00.23,0:01:05.89,ED_English,,0,0,0,,{\fad(100,200)\blur5\c&H281E1D&\3c&HF9CFC2&}You're my destiny
Dialogue: 0,0:01:05.88,0:01:10.07,ED_Romaji,,0,0,0,,{\fad(100,200)\blur5\c&H281E1D&\3c&HF9CFC2&}tsuretette
Dialogue: 0,0:01:05.89,0:01:10.08,ED_English,,0,0,0,,{\fad(100,200)\blur5\c&H281E1D&\3c&HF9CFC2&}So take me
Dialogue: 0,0:01:10.07,0:01:16.82,ED_Romaji,,0,0,0,,{\fad(100,200)\blur5\c&H281E1D&\3c&HF9CFC2&}yakusoku no basho e
Dialogue: 0,0:01:10.08,0:01:16.83,ED_English,,0,0,0,,{\fad(100,200)\blur5\c&H281E1D&\3c&HF9CFC2&}to our promised land
Loading