#!/usr/bin/env python # From http://www.dwerg.net/projects/python/srttool.py # Converts JACOSub Scripts into CMML # More information at http://trac.annodex.net/wiki/CmmlSubtitles ## Copyright (C) 2004- Commonwealth Scientific and Industrial Research ## Organisation (CSIRO) Australia ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## ## - Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## ## - Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## - Neither the name of CSIRO Australia nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A ## PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ## LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ## NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ## SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import re import sys global savecmml global contflag global id timeRe = re.compile('(?P\d):(?P\d\d):(?P\d\d).(?P\d\d)') newlineRe = re.compile('.\\\\n.', re.MULTILINE) contRe = re.compile('.\\\\$') class CorruptJscError(Exception): """ The JacoSub File is incorrectly formatted """ pass def timeformat(times): return "%02d:%02d:%02d.%02d" % tuple(times) def get_times(line, line2): try: time1 = timeRe.match(line.strip()) time2 = timeRe.match(line2.strip()) timear1 = [ int(time1.groupdict()['hours']), int(time1.groupdict()['minutes']), int(time1.groupdict()['seconds']), int(time1.groupdict()['millis']), ] timear2 = [ int(time2.groupdict()['hours']), int(time2.groupdict()['minutes']), int(time2.groupdict()['seconds']), int(time2.groupdict()['millis']), ] return (timeformat(timear1), timeformat(timear2)) except IndexError: raise CorruptJscError("Corrupt Time Format") except Exception: raise CorruptJscError("Ensure time format is in correct syntax.") def convert_block(lines): global savecmml global contflag global id makespace = 1 for array in lines: if timeRe.match(array): parts = array.split(' ', 3) # Match the time sequence for start and end sequences if timeRe.match(parts[0].strip()): (start, end) = get_times(parts[0], parts[1]) savecmml += '\n' % (id, start, end) savecmml += ' \n' lineparts = parts[3].replace('\\n', '\\n!n!') lineparts = lineparts.split('\\n') id += 1 for line in lineparts: # For the first line being parsed if makespace == 1: makespace = 0 savecmml += ' ' # For the occurence of '\' character if contRe.search(line): contflag = 1 message = line.replace('!n!', '') message = message.replace('\\', '') savecmml += message # For a regular escape sequence else: makespace = 1 message = line.replace('!n!', '') savecmml += message + '\n' if not contflag: savecmml += ' \n' savecmml += '\n' else: if contflag: contflag = 0 if not re.search('#.', array): # For a regular escape sequence if newlineRe.search(array): lines = array.replace('\\n', '\\n!n!') lines = lines.split('\\n') for line in lines: # For the first line being parsed if makespace == 1: makespace = 0 savecmml += ' ' # For the occurence of '\' character if contRe.search(line): contflag = 1 message = line.replace('!n!', '') message = message.replace('\\', '') savecmml += message # For a regular escape sequence else: makespace = 1 message = line.replace('!n!', '') savecmml += message + '\n' if not contflag: savecmml += ' \n' savecmml += '\n' # For the occurence of '\' character elif contRe.search(array): contflag = 1 message = array.replace('\\', '') savecmml += message else: savecmml += array + '\n' savecmml += ' \n' savecmml += '\n' def convert_clips(file): global savecmml current = [] for line in file: if not line.strip(): convert_block(current) current = [] else: current.append(line.strip()) def convert_jsc(file): global savecmml global id global contflag contflag = 0 id = 1 savecmml = '\n' savecmml += '\n' savecmml += ' ' + sys.argv[1] + '\n' savecmml += '\n' convert_clips (file) savecmml += '\n' if __name__ == '__main__': global savecmml savecmml = '' try: try: filesave = open(sys.argv[2], 'w') convert_jsc(file(sys.argv[1])) filesave.write(savecmml) filesave.close() except IndexError: convert_jsc(file(sys.argv[1])) print savecmml except IndexError: print "Usage: %s [Input JACOSub File] [Output CMML File]" % sys.argv[0]