(Insert TipProposed template + manual clean) |
|||
(10 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
+ | {{TipProposed |
||
− | [[File:Placeholder|video|right|300px]] [[File:Placeholder|right|300px]] |
||
+ | |id=0 |
||
+ | |previous=0 |
||
+ | |next=0 |
||
+ | |created=August 23, 2013 |
||
+ | |complexity=basic |
||
+ | |author=Vimsical |
||
+ | |version=7.0 |
||
+ | |subpage=/2013 |
||
+ | |category1= |
||
+ | |category2= |
||
+ | }} |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
+ | *VLC. |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
− | 3. VLC |
||
⚫ | |||
⚫ | |||
− | you save them in. |
||
− | |||
⚫ | |||
<pre> |
<pre> |
||
" VLC setup: $ vlc > tools > prefs > main interface > enable RC, |
" VLC setup: $ vlc > tools > prefs > main interface > enable RC, |
||
− | " Tcp-Input=[localhost:2150] .. ~/ |
+ | " Tcp-Input=[localhost:2150] .. ~/vim/vlc.pl will open this socket. |
− | " Console: [donot_open] console |
+ | " Console: [donot_open] console |
</pre> |
</pre> |
||
+ | |||
− | == |
+ | ==Vim setup== |
<pre> |
<pre> |
||
" VIM Setup: |
" VIM Setup: |
||
− | " c:\> vim happy.lrc |
+ | " c:\> vim c:/atmp/happy.lrc |
" :so % |
" :so % |
||
− | " and cline is '[0:23.10] file:///C:/ |
+ | " and cline is '[0:23.10] file:///C:/atmp/happy.mp3' .. press F9 to play from 23s |
" Music player key: |
" Music player key: |
||
" [F2] Play |
" [F2] Play |
||
Line 30: | Line 40: | ||
" [F4] Pause toggle |
" [F4] Pause toggle |
||
" Lyric editor keys: |
" Lyric editor keys: |
||
− | " [F9] Set filename |
+ | " [F9] Set filename/time from cline to vlc, or get filename/time to cline. |
" [F10] Get file from vlc into cline. |
" [F10] Get file from vlc into cline. |
||
− | " [F11] Get Time from vlc into cline. |
+ | " [F11] Get Time from vlc into cline. |
+ | " Notes: |
||
− | </nowiki> |
||
+ | " To debug: change 'perl ~/vim/vlc.pl' to 'vimrun perl ~/vim/vlc.pl -debug' |
||
− | == Map your VLC controller keys |
||
+ | " Testing: |
||
− | <nowiki> |
||
+ | " Tested gvim73,cygwin perl 5, cygwin,vlc 2, on XP-PRO SP4. |
||
⚫ | |||
+ | " 1. file:///c:/atmp/happy.mp3 .. press F9 play this file in vlc. |
||
⚫ | |||
+ | " 2. [0:1:4] file:///c:/atmp/happy.mp3 .. press F9 play this file from 64 seconds. |
||
⚫ | |||
+ | " 3. 0:1:5 .. press F9 to cue/seek vlc to 65 second. |
||
+ | " 4. press F9, to add [time][filename playing in vlc] to this line. |
||
+ | " TODO: |
||
+ | " o Test Audio filenames with spaces, unicode characters |
||
+ | " o Test on Linux |
||
⚫ | |||
+ | |||
⚫ | |||
⚫ | |||
⚫ | |||
+ | |||
⚫ | |||
⚫ | |||
⚫ | |||
+ | </pre> |
||
+ | ==Source vlc.vim== |
||
⚫ | |||
⚫ | |||
⚫ | |||
− | </pre> |
||
− | == source this file vlc-lrc.vim == |
||
<pre> |
<pre> |
||
+ | " $Header: c:/cvs/repo/mosh/vim/vlc.vim,v 1.1 2013-08-26 17:04:52 a Exp $ |
||
+ | " What: VLC remote control, for editing synchronizing lyrics. |
||
+ | " How: Remote control vlc via tcp socket. |
||
⚫ | |||
" ============================================================================== |
" ============================================================================== |
||
+ | function! Vlc_Set_File_Time() |
||
⚫ | |||
− | function! Mosh_Set_File_Time() |
||
− | " Test [33] file:///c:/tmp/happy.mp3 |
||
" Look for filename on cline |
" Look for filename on cline |
||
let l:matcher_file = matchlist(getline('.'),'\v<(file:///.*[.]\w+)>') |
let l:matcher_file = matchlist(getline('.'),'\v<(file:///.*[.]\w+)>') |
||
+ | let l:absfile = '' |
||
if len(l:matcher_file) > 4 |
if len(l:matcher_file) > 4 |
||
− | + | call system("perl ~/vim/vlc.pl -cmd=set_file=" . l:matcher_file[1]) |
|
+ | else |
||
− | exe ":silent !perl ~/vlc/rc.pl -cmd=set_file=" . l:matcher_file[1] |
||
+ | " Look for cfile (filename under cursor) in PWD |
||
+ | let l:cfile = expand("<cfile>") |
||
+ | " let l:absfile = expand("<cfile>:p") |
||
+ | " if len(l:absfile) > 1 && filereadable('"'.l:absfile.'"') |
||
⚫ | |||
+ | if len(l:cfile) > 4 && filereadable(expand(l:cfile)) |
||
+ | let l:absfile = getcwd()."/".l:cfile |
||
+ | if filereadable(l:absfile) |
||
+ | call system("perl ~/vim/vlc.pl -cmd=set_file=file:///".l:absfile) |
||
⚫ | |||
+ | echo "Cannot read ".l:absfile |
||
+ | return |
||
+ | endif |
||
+ | endif |
||
endif |
endif |
||
Line 61: | Line 99: | ||
let l:matcher_time = matchlist(getline('.'),'\v\[(\d.*)\]') |
let l:matcher_time = matchlist(getline('.'),'\v\[(\d.*)\]') |
||
if len(l:matcher_time) > 0 |
if len(l:matcher_time) > 0 |
||
− | + | call system( "perl ~/vim/vlc.pl -cmd=set_time=" . l:matcher_time[1]) |
|
− | exe ":silent !perl ~/vlc/rc.pl -cmd=set_time=" . l:matcher_time[1] |
||
else |
else |
||
" Look for timestamp colon without brackets on cline, eg. 1:2 for 62 seconds. |
" Look for timestamp colon without brackets on cline, eg. 1:2 for 62 seconds. |
||
let l:matcher_time = matchlist(getline('.'),'\v(\d+:[0-9:.]+)') |
let l:matcher_time = matchlist(getline('.'),'\v(\d+:[0-9:.]+)') |
||
if len(l:matcher_time) > 0 |
if len(l:matcher_time) > 0 |
||
− | + | call system("perl ~/vim/vlc.pl -cmd=set_time=" . l:matcher_time[1]) |
|
− | exe ":silent !perl ~/vlc/rc.pl -cmd=set_time=" . l:matcher_time[1] |
||
endif |
endif |
||
endif |
endif |
||
− | " If neither |
+ | " If neither filename or time on cline, insert them. |
− | if len(l:matcher_time) < 1 && len(l:matcher_file) < 1 |
+ | if len(l:matcher_time) < 1 && len(l:matcher_file) < 1 && !filereadable(l:absfile) |
− | + | call Vlc_Get_Filename() |
|
− | + | call Vlc_Get_Time() |
|
endif |
endif |
||
endfunction |
endfunction |
||
" ============================================================================== |
" ============================================================================== |
||
− | function! |
+ | function! Vlc_Get_Filename() |
− | + | let l:fileis=system("perl ~/vim/vlc.pl -cmd=get_file") |
|
+ | if len(l:fileis) > 0 |
||
− | exe ":r !perl ~/vlc/rc.pl -cmd=get_file" |
||
+ | " relfile=$(basename filename), insert shorter relative path if possible. |
||
+ | " TODO: quote filenames; s/// fails if filename has commas, etc. |
||
+ | let l:relfile=substitute(l:fileis, '^.*/', '', '') |
||
+ | if filereadable(l:relfile) |
||
+ | exe ':s,^, '.l:relfile.',' |
||
+ | else |
||
+ | exe ':s,^,'.l:fileis.',' |
||
+ | endif |
||
+ | endif |
||
endfunction |
endfunction |
||
" ============================================================================== |
" ============================================================================== |
||
− | function! |
+ | function! Vlc_Get_Time() |
− | + | let l:timeis=system("perl ~/vim/vlc.pl -cmd=get_time") |
|
− | let l:timeis=system("perl ~/vlc/rc.pl -cmd=get_time") |
||
if len(l:timeis) > 0 |
if len(l:timeis) > 0 |
||
let l:timeis=substitute(l:timeis, '[^0-9:.]', '', 'g') |
let l:timeis=substitute(l:timeis, '[^0-9:.]', '', 'g') |
||
let l:timeis='['.l:timeis.']' |
let l:timeis='['.l:timeis.']' |
||
exe ':s/^/'.l:timeis.'/' |
exe ':s/^/'.l:timeis.'/' |
||
+ | " TODO: try this: |
||
+ | " :put ='"'.l:timeis.'"' |
||
endif |
endif |
||
endfunction |
endfunction |
||
+ | " ============================================================================== |
||
− | |||
⚫ | |||
</pre> |
</pre> |
||
+ | ==~/vim/vlc.pl== |
||
− | == Keep this perl file in your path == |
||
<pre> |
<pre> |
||
#!/usr/bin/perl -w |
#!/usr/bin/perl -w |
||
− | # |
+ | # telnet.pl from perlmonks, modified to work with vlc remote control. |
− | # GPL(C) |
+ | # AUTHOR: GPL(C) moshahmed/at/gmail 2013-08-22 |
+ | # $Id: vlc.pl,v 1.1 2013-08-26 16:44:44 a Exp $ |
||
use strict; |
use strict; |
||
use IO::Socket; |
use IO::Socket; |
||
− | |||
my ( $host, $port, $kidpid, $handle, $line ); |
my ( $host, $port, $kidpid, $handle, $line ); |
||
( $host, $port ) = ('127.0.0.1', 2150); |
( $host, $port ) = ('127.0.0.1', 2150); |
||
Line 121: | Line 166: | ||
VLC_CMDS: |
VLC_CMDS: |
||
play, pause, pause (toggle), stop, |
play, pause, pause (toggle), stop, |
||
− | get_length .. in seconds |
+ | get_length .. in h:m:seconds |
− | get_time .. in seconds |
+ | get_time .. in h:m:seconds |
get_file .. gets file:///path |
get_file .. gets file:///path |
||
− | set_time=1:2:3.40 .. for 1hour 2minutes 3seconds |
+ | set_time=1:2:3.40 .. for 1hour 2minutes 3seconds (integral seconds only) |
set_file=file:///c:/tmp/happy.mp3 |
set_file=file:///c:/tmp/happy.mp3 |
||
}; |
}; |
||
Line 135: | Line 180: | ||
}elsif( m/^-port=(\d+)$/ ){ $port = $1; |
}elsif( m/^-port=(\d+)$/ ){ $port = $1; |
||
}elsif( m/^-cmd=(set_.+)=(.+)$/ ){ $cmd = $1; $value = $2; |
}elsif( m/^-cmd=(set_.+)=(.+)$/ ){ $cmd = $1; $value = $2; |
||
⚫ | |||
⚫ | |||
− | + | warn "$cmd=$value\n" if $debug; |
|
− | my ($timeis,$factor)=(0,1); |
||
⚫ | |||
⚫ | |||
− | $timeis += $factor * $1; |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
− | die "debug: -cmd=$cmd=$value\n" if $debug; |
||
}elsif( m/^-cmd=(.+)$/ ){ $cmd = $1; |
}elsif( m/^-cmd=(.+)$/ ){ $cmd = $1; |
||
− | }elsif( m/^-linein$/ ){ $linein=1; |
+ | }elsif( m/^-linein$/ ){ $linein=1; # read stdin (unused). |
}else{ die $USAGE,"Unknown option '$_'\n"; } |
}else{ die $USAGE,"Unknown option '$_'\n"; } |
||
} |
} |
||
+ | |||
+ | # foreach(@ARGV) { } .. process leftover args (unused). |
||
# create a tcp connection to the specified host and port |
# create a tcp connection to the specified host and port |
||
Line 165: | Line 203: | ||
DONE: |
DONE: |
||
while ( defined( $line = <$handle> ) ) { |
while ( defined( $line = <$handle> ) ) { |
||
− | if ($cmd eq 'get_length') { |
+ | if ($cmd eq 'get_length') { |
if( $line =~ m,^\d+,) { |
if( $line =~ m,^\d+,) { |
||
− | print STDOUT $line; |
+ | print STDOUT seconds_to_hms($line); |
last DONE; |
last DONE; |
||
} |
} |
||
}elsif($cmd eq 'get_time') { |
}elsif($cmd eq 'get_time') { |
||
if( $line =~ m,^\d+,) { |
if( $line =~ m,^\d+,) { |
||
− | print STDOUT $line; |
+ | print STDOUT seconds_to_hms($line); |
last DONE; |
last DONE; |
||
} |
} |
||
Line 207: | Line 245: | ||
} |
} |
||
exit 0; |
exit 0; |
||
− | } |
+ | } |
+ | |||
+ | sub seconds_to_hms { |
||
+ | my $hourz=int($_[0]/3600); |
||
+ | my $leftover=$_[0] % 3600; |
||
+ | my $minz=int($leftover/60); |
||
+ | my $secz=int($leftover % 60); |
||
+ | if ($hourz > 0){ |
||
+ | return sprintf ("%d:%02d:02%d", $hourz,$minz,$secz) |
||
+ | } |
||
+ | # print 3 seconds as 00:03, so timestamp always has a colon. |
||
+ | return sprintf ("%02d:%02d", $minz,$secz) |
||
+ | } |
||
+ | |||
+ | sub hms_to_seconds { |
||
⚫ | |||
⚫ | |||
+ | if ( $hms =~ m,^(\d+):(\d+):(\d+), ) { # ignore trailing chars. |
||
+ | return $1 * 3600 + $2 * 60 + $3; |
||
⚫ | |||
⚫ | |||
+ | } |
||
+ | return $hms; |
||
+ | } |
||
</pre> |
</pre> |
||
+ | |||
+ | ==Comments== |
||
+ | That's a lot of script for a tip. I have done some quick formatting, but have not thought about the proposed tip yet. One point is that the "Mosh" function names are a bit jarring and should be replaced with <code>s:</code>. [[User:JohnBeckett|JohnBeckett]] ([[User talk:JohnBeckett|talk]]) 05:16, August 24, 2013 (UTC) |
Latest revision as of 10:40, 31 January 2014
Proposed tip Please edit this page to improve it, or add your comments below (do not use the discussion page).
created August 23, 2013 · complexity basic · author Vimsical · version 7.0
You can use Vim to control VLC and edit song lyrics or audio transcripts:
- You can add audio timing information to each line of text transcript.
- You can cue VLC audio to the time/line you are editing.
You will need:
- Vim to edit text.
- Perl to connect gvim to vlc via a socket.
- VLC.
Below: Modify the path to Perl and Vim script according to the directory you save them in.
Setup vlc to listen on a socket[]
" VLC setup: $ vlc > tools > prefs > main interface > enable RC, " Tcp-Input=[localhost:2150] .. ~/vim/vlc.pl will open this socket. " Console: [donot_open] console
Vim setup[]
" VIM Setup: " c:\> vim c:/atmp/happy.lrc " :so % " and cline is '[0:23.10] file:///C:/atmp/happy.mp3' .. press F9 to play from 23s " Music player key: " [F2] Play " [F3] Stop " [F4] Pause toggle " Lyric editor keys: " [F9] Set filename/time from cline to vlc, or get filename/time to cline. " [F10] Get file from vlc into cline. " [F11] Get Time from vlc into cline. " Notes: " To debug: change 'perl ~/vim/vlc.pl' to 'vimrun perl ~/vim/vlc.pl -debug' " Testing: " Tested gvim73,cygwin perl 5, cygwin,vlc 2, on XP-PRO SP4. " 1. file:///c:/atmp/happy.mp3 .. press F9 play this file in vlc. " 2. [0:1:4] file:///c:/atmp/happy.mp3 .. press F9 play this file from 64 seconds. " 3. 0:1:5 .. press F9 to cue/seek vlc to 65 second. " 4. press F9, to add [time][filename playing in vlc] to this line. " TODO: " o Test Audio filenames with spaces, unicode characters " o Test on Linux " ============================================================================== nmap <F2> :call system("perl ~/vim/vlc.pl -cmd=play")<CR> nmap <F3> :call system("perl ~/vim/vlc.pl -cmd=stop")<CR> nmap <F4> :call system("perl ~/vim/vlc.pl -cmd=pause")<CR> nmap <F9> :call Vlc_Set_File_Time()<CR> nmap <F10> :call Vlc_Get_Filename()<CR> nmap <F11> :call Vlc_Get_Time()<CR>
Source vlc.vim[]
" $Header: c:/cvs/repo/mosh/vim/vlc.vim,v 1.1 2013-08-26 17:04:52 a Exp $ " What: VLC remote control, for editing synchronizing lyrics. " How: Remote control vlc via tcp socket. " AUTHOR: GPL(C) moshahmed/at/gmail " ============================================================================== function! Vlc_Set_File_Time() " Look for filename on cline let l:matcher_file = matchlist(getline('.'),'\v<(file:///.*[.]\w+)>') let l:absfile = '' if len(l:matcher_file) > 4 call system("perl ~/vim/vlc.pl -cmd=set_file=" . l:matcher_file[1]) else " Look for cfile (filename under cursor) in PWD let l:cfile = expand("<cfile>") " let l:absfile = expand("<cfile>:p") " if len(l:absfile) > 1 && filereadable('"'.l:absfile.'"') " endif if len(l:cfile) > 4 && filereadable(expand(l:cfile)) let l:absfile = getcwd()."/".l:cfile if filereadable(l:absfile) call system("perl ~/vim/vlc.pl -cmd=set_file=file:///".l:absfile) else echo "Cannot read ".l:absfile return endif endif endif " Look for timestamp on cline, eg. [10] for 10 seconds, [1:1] for 61 seconds. let l:matcher_time = matchlist(getline('.'),'\v\[(\d.*)\]') if len(l:matcher_time) > 0 call system( "perl ~/vim/vlc.pl -cmd=set_time=" . l:matcher_time[1]) else " Look for timestamp colon without brackets on cline, eg. 1:2 for 62 seconds. let l:matcher_time = matchlist(getline('.'),'\v(\d+:[0-9:.]+)') if len(l:matcher_time) > 0 call system("perl ~/vim/vlc.pl -cmd=set_time=" . l:matcher_time[1]) endif endif " If neither filename or time on cline, insert them. if len(l:matcher_time) < 1 && len(l:matcher_file) < 1 && !filereadable(l:absfile) call Vlc_Get_Filename() call Vlc_Get_Time() endif endfunction " ============================================================================== function! Vlc_Get_Filename() let l:fileis=system("perl ~/vim/vlc.pl -cmd=get_file") if len(l:fileis) > 0 " relfile=$(basename filename), insert shorter relative path if possible. " TODO: quote filenames; s/// fails if filename has commas, etc. let l:relfile=substitute(l:fileis, '^.*/', '', '') if filereadable(l:relfile) exe ':s,^, '.l:relfile.',' else exe ':s,^,'.l:fileis.',' endif endif endfunction " ============================================================================== function! Vlc_Get_Time() let l:timeis=system("perl ~/vim/vlc.pl -cmd=get_time") if len(l:timeis) > 0 let l:timeis=substitute(l:timeis, '[^0-9:.]', '', 'g') let l:timeis='['.l:timeis.']' exe ':s/^/'.l:timeis.'/' " TODO: try this: " :put ='"'.l:timeis.'"' endif endfunction " ==============================================================================
~/vim/vlc.pl[]
#!/usr/bin/perl -w # telnet.pl from perlmonks, modified to work with vlc remote control. # AUTHOR: GPL(C) moshahmed/at/gmail 2013-08-22 # $Id: vlc.pl,v 1.1 2013-08-26 16:44:44 a Exp $ use strict; use IO::Socket; my ( $host, $port, $kidpid, $handle, $line ); ( $host, $port ) = ('127.0.0.1', 2150); my ($verbose,$debug,$cmd,$value,$linein) = (0,0,'',,''); my $USAGE=q{ USAGE: $0 [options] -cmd=VLC_CMDS WHAT: control vlc from vim Options: -port=NN .. default ($port) -h .. help. -v .. verbose -debug .. to debug, also use ./telnet.pl to communicate with vlc VLC_CMDS: play, pause, pause (toggle), stop, get_length .. in h:m:seconds get_time .. in h:m:seconds get_file .. gets file:///path set_time=1:2:3.40 .. for 1hour 2minutes 3seconds (integral seconds only) set_file=file:///c:/tmp/happy.mp3 }; # Process args while( $_ = $ARGV[0], defined($_) && m/^-/ ){ shift; last if /^--$/; if(0){ }elsif( m/^-[h?]$/ ){ die $USAGE; }elsif( m/^-v$/ ){ $verbose++; }elsif( m/^-debug$/ ){ $debug++; }elsif( m/^-port=(\d+)$/ ){ $port = $1; }elsif( m/^-cmd=(set_.+)=(.+)$/ ){ $cmd = $1; $value = $2; $value = hms_to_seconds($value); warn "$cmd=$value\n" if $debug; }elsif( m/^-cmd=(.+)$/ ){ $cmd = $1; }elsif( m/^-linein$/ ){ $linein=1; # read stdin (unused). }else{ die $USAGE,"Unknown option '$_'\n"; } } # foreach(@ARGV) { } .. process leftover args (unused). # create a tcp connection to the specified host and port $handle = IO::Socket::INET->new( Proto => "tcp", PeerAddr => $host, PeerPort => $port ) or die "can't connect to port $port on $host: $!"; $handle->autoflush(1); # so output gets there right away print STDERR "[Connected to $host:$port]\n" if $verbose; # split the program into two processes, identical twins die "can't fork: $!" unless defined( $kidpid = fork() ); if ($kidpid) { # In parent, parse reply from vlc. # the if{} part runs only in the parent process DONE: while ( defined( $line = <$handle> ) ) { if ($cmd eq 'get_length') { if( $line =~ m,^\d+,) { print STDOUT seconds_to_hms($line); last DONE; } }elsif($cmd eq 'get_time') { if( $line =~ m,^\d+,) { print STDOUT seconds_to_hms($line); last DONE; } }elsif($cmd eq 'get_file') { if( $line =~ m,(file://.*)\s[()],i ) { my $filename = $1; print STDOUT $filename; last DONE; } }elsif($cmd eq 'status') { print STDOUT $line; last DONE if $line =~ m,returned,; }elsif($cmd eq 'play') { last DONE; }elsif($cmd eq 'pause') { last DONE; }elsif($cmd eq 'stop') { last DONE; }else{ print STDOUT $line; last DONE if $line =~ m,returned,; } } # DONE kill( "TERM", $kidpid ); # send SIGTERM to child exit 0; } else { # In child? send cmd to vlc if( $cmd eq 'status' ){ print $handle "$cmd\n"; }elsif( $cmd eq 'play' ){ print $handle "$cmd\n"; }elsif( $cmd eq 'pause' ){ print $handle "$cmd\n"; }elsif( $cmd eq 'stop' ){ print $handle "$cmd\n"; }elsif( $cmd eq 'get_time' ){ print $handle "$cmd\n"; }elsif( $cmd eq 'get_file' ){ print $handle "pause\nstatus\npause\nstatus\n"; }elsif( $cmd eq 'get_length' ){ print $handle "play\nget_length\n"; }elsif( $cmd eq 'set_time' ){ print $handle "seek $value\n"; }elsif( $cmd eq 'set_file' ){ print $handle "clear\nadd $value\n"; }else{ print $handle "$cmd\n"; } exit 0; } sub seconds_to_hms { my $hourz=int($_[0]/3600); my $leftover=$_[0] % 3600; my $minz=int($leftover/60); my $secz=int($leftover % 60); if ($hourz > 0){ return sprintf ("%d:%02d:02%d", $hourz,$minz,$secz) } # print 3 seconds as 00:03, so timestamp always has a colon. return sprintf ("%02d:%02d", $minz,$secz) } sub hms_to_seconds { # hms_to_seconds(1:2:3.4) => 1h.2m.3.4s = 1*3600+2*60+3 = 3723. my $hms = $_[0]; if ( $hms =~ m,^(\d+):(\d+):(\d+), ) { # ignore trailing chars. return $1 * 3600 + $2 * 60 + $3; }elsif( $hms =~ m,^(\d+):(\d+), ) { return $1 * 60 + $2; } return $hms; }
Comments[]
That's a lot of script for a tip. I have done some quick formatting, but have not thought about the proposed tip yet. One point is that the "Mosh" function names are a bit jarring and should be replaced with s:
. JohnBeckett (talk) 05:16, August 24, 2013 (UTC)