Page 1 of 2

Jeval.bat : command line calculator using native code

Posted: 23 Jan 2015 23:25
by foxidrive
Jeval.bat is able to give calculation results using native batch scripting (utilising jscript).

Dave, you there? :)

I don't know if there is a thread for Jeval.bat but Mr Google couldn't help me - so here's one.

This code for Jeval.bat is from this thread: viewtopic.php?p=27422#p27422



dbenham wrote:
Here is the jEval.bat code:

Code: Select all

@if (@X)==(@Y) @end /* harmless hybrid line that begins a JScrpt comment

::************ Documentation ***********
:::
:::jEval  JScriptExpression  [/N]
:::jEval  /?
:::
:::  Evaluates a JScript expression and writes the result to stdout.
:::
:::  A newline (CR/LF) is not appended to the result unless the /N
:::  option is used.
:::
:::  The JScript expression should be enclosed in double quotes.
:::
:::  JScript string literals within the expression should be enclosed
:::  in single quotes.
:::
:::  Example:
:::
:::    call jEval "'5/4 = ' + 5/4"
:::
:::  Output:
:::
:::    5/4 = 1.25
:::

::************ Batch portion ***********
@echo off

if "%~1" equ "" (
  call :err "Insufficient arguments"
  exit /b
)
if "%~2" neq "" if /i "%~2" neq "/N" (
  call :err "Invalid option"
  exit /b
)
if "%~1" equ "/?" (
  setlocal enableDelayedExpansion
  for /f "delims=" %%A in ('findstr "^:::" "%~f0"') do (
    set "ln=%%A"
    echo(!ln:~3!
  )
  exit /b
)
cscript //E:JScript //nologo "%~f0" %*
exit /b

:err
>&2 echo ERROR: %~1. Use jeval /? to get help.
exit /b 1


************ JScript portion ***********/
if (WScript.Arguments.Named.Exists("n")) {
  WScript.StdOut.WriteLine(eval(WScript.Arguments.Unnamed(0)));
} else {
  WScript.StdOut.Write(eval(WScript.Arguments.Unnamed(0)));
}


Re: Jeval.bat : command line calculator using native code

Posted: 23 Jan 2015 23:43
by foxidrive
I have a question for the mathematically-inclined people here:

Here is a number representing time 1647920000000 and I'd like to get Hour:Minutes so that is what I am trying to do.

I can convert this number representing time to seconds using this:

c:\>call jeval "(1647920000000/1000000000)%60"
27.9200000000001

and I can also get hours using this:

c:\>call jeval "(1647920000000/1000000000)/(60*60)"
0.457755555555556


I can also get the significant digits before the period if I just read a bit more - my question is: can I do this in one command using Jeval?



A related suggestion for Dave: would there be any use in adding an option to Jrepl so that the replace field can be launched as a batch command, and the result inserted in the text file instead of the replace field?

So basically the "%txt%" file contains File 'Airborne.mkv': container: Matroska [duration:1647920000000 and I'd like to replace the 1647920000000 with the Hour:Minutes instead of using much more code.

Code: Select all

    for /f %%b in ('call jrepl  "\[duration:(.*)" "call jevel \q$1\1000000000\q" /x /f "%txt%"') do (
       for /f %%c in ('call jeval "(%%b/1000000000)%60") do echo %%c
    )


Just a suggestion.

Re: Jeval.bat : command line calculator using native code

Posted: 23 Jan 2015 23:44
by foxidrive
foxidrive wrote:I have a question for the mathematically-inclined people here:

Here is a number representing time 1647920000000 and I'd like to get Hour:Minutes so that is what I am trying to do.

I can convert this number representing time to minutes using this:

c:\>call jeval "(1647920000000/1000000000)%60"
27.9200000000001

and I can also get hours using this:

c:\>call jeval "(1647920000000/1000000000)/(60*60)"
0.457755555555556


I can also get the significant digits before the period if I just read a bit more - my question is: can I do this in one command using Jeval?



A related suggestion for Dave: would there be any use in adding an option to Jrepl so that the replace field can be launched as a batch command, and the result inserted in the text file instead of the replace field?

So basically the "%txt%" file contains File 'Airborne.mkv': container: Matroska [duration:1647920000000 and I'd like to replace the 1647920000000 with the Hour:Minutes instead of using much more code and file processing.

Code: Select all

    call jrepl  "\[duration:(.*)" "call jevel \q$1\1000000000\q" /x /f "%txt%"


Just a suggestion.

Re: Jeval.bat : command line calculator using native code

Posted: 24 Jan 2015 01:03
by dbenham
JREPL can already do the replacement in one step. That is the purpose of the /J option - it treats the replacement expression as JScript code that gets evaluated. You can do all the math to get the needed values, and then concatenate them as a string with punctuation, all with a single expression.

Code: Select all

echo File 'Airborne.mkv': container: Matroska [duration:1647920000000|jrepl "\[duration:(\d*)" "var s=$1/1000000000, h=Math.floor(s/60/60), m=Math.floor(s/60-h*60);h+':'+(m+100).toString().slice(-2)" /j

--OUTPUT--

Code: Select all

File 'Airborne.mkv': container: Matroska 0:27


Dave Benham

Re: Jeval.bat : command line calculator using native code

Posted: 24 Jan 2015 05:16
by foxidrive
Thank you Dave. That's doing the job well.

My familiarity with Jscript is on par with my knowledge of what women really want. Nada.
I am so stupid that I failed to think of Jrepl and Jscript which already has the capability.


Examples help me enormously - yet I've just tried a dozen or so different ways to add some plain text before the hour:min figure, and failed every time

For example this doesn't work:

echo File 'Airborne.mkv': container: Matroska [duration:1647920000000|jrepl "\[duration:(\d*)" "'aaa'+var s=$1/1000000000, h=Math.floor(s/60/60), m=Math.floor(s/60-h*60);h+':'+(m+100).toString().slice(-2)" /j

But this works to place a suffix ok:

echo File 'Airborne.mkv': container: Matroska [duration:1647920000000|jrepl "\[duration:(\d*)" "var s=$1/1000000000, h=Math.floor(s/60/60), m=Math.floor(s/60-h*60);h+':'+(m+100).toString().slice(-2)+' zzz'" /j

Do you see where my failure to comprehend is? :)

Re: Jeval.bat : command line calculator using native code

Posted: 24 Jan 2015 08:55
by dbenham
The /J option specifies that the replacement value is JScript code that gets evaluated (executed) by the eval() function. The code must evaluate to a value, which is what is ultimately used as the replacement.

In this case, the code consists of two statements, seperated by the semicolon (;) statement terminator. The first statement is a compound assignment. The second statement is a value expression. The returned value is the value of the last statement (expression).

So you simply need to prepend the string to the final expression:
"var s=$1/1000000000, h=Math.floor(s/60/60), m=Math.floor(s/60-h*60);'aaa'+h+':'+(m+100).toString().slice(-2)"


Dave Benham

Re: Jeval.bat : command line calculator using native code

Posted: 25 Jan 2015 05:03
by foxidrive
dbenham wrote:So you simply need to prepend the string to the final expression:
"var s=$1/1000000000, h=Math.floor(s/60/60), m=Math.floor(s/60-h*60);'aaa'+h+':'+(m+100).toString().slice(-2)"


Gah!

You may choose not to believe (X-Files=Trust No-one!) but that is one of the first things I tried.
Thanks Dave. Something in my CMD session was fubar as it quite rightly works now.

I kept getting NaN in the screen output yesterday, and it's happening now too but in a different situation.

In this question I was going to ask how to get the numeral in the same format that Jeval returns - without the exponent notation.

My ultimate goal is to produce MKV chapter.XML files and they require the time in this format: <ChapterTimeStart>00:00:10.010</ChapterTimeStart>
where I can leave the last three digits as zero but the HH:MM:SS fields needs to accumulate so that each chapter starts at the elapsed time through the video file.

In this test I am providing the set of times and incrementing the number - intending to use the solution you provided yesterday to give me HH:MM:SS

Code: Select all

@echo off
set "chaptertime=0"
set "chaptertime2=0"
for %%a in (
1267720000000
1277400000000
1292405000000
1268108000000
1277756000000
2994983000000
10245792000000
1284500000000
2617460000000
1291960000000
) do call :chapter "%%a"
pause & goto :EOF

:chapter

for /f %%t in (' echo %~1^|jrepl "(.*)" "Math.floor($1+%chaptertime%)" /j /a  ') do set "chaptertime=%%t"
for /f %%t in (' jeval "%~1+%chaptertime2%" ') do set "chaptertime2=%%t"

echo %chaptertime%,%chaptertime2%
goto :EOF


This is what I see on the console at the moment - the first number is ok and then it fails as the exponents are in the mix,
but Jeval continues to produce the incrementing numbers.

Is there a different math method that solves this? I had a look at the WSH help but I'm unsure...

Code: Select all

126772000000000,1267720000000
1.2774000000001267e+27126772000000000,2545120000000
NaNInfinity,3837525000000
JScript runtime error in Replace code: 'NaNInfinity' is undefined
NaNInfinity,5105633000000
JScript runtime error in Replace code: 'NaNInfinity' is undefined
NaNInfinity,6383389000000
JScript runtime error in Replace code: 'NaNInfinity' is undefined
NaNInfinity,9378372000000
JScript runtime error in Replace code: 'NaNInfinity' is undefined
NaNInfinity,19624164000000
JScript runtime error in Replace code: 'NaNInfinity' is undefined
NaNInfinity,20908664000000
JScript runtime error in Replace code: 'NaNInfinity' is undefined
NaNInfinity,23526124000000
JScript runtime error in Replace code: 'NaNInfinity' is undefined
NaNInfinity,24818084000000
Press any key to continue . . .

Re: Jeval.bat : command line calculator using native code

Posted: 25 Jan 2015 08:40
by dbenham
Ouch, this is painful. :twisted:

I don't see why you are using JREPL at all. It seems like everything could be done more conveniently with JEVAL.

But I wouldn't bother trying to figure it out. This is exactly the type of problem that getTimestamp.bat is intended to solve:

Code: Select all

@echo off
setlocal enableDelayedExpansion
set "chapterTime=0"
for %%T in (
  1267720000000
  1277400000000
  1292405000000
  1268108000000
  1277756000000
  2994983000000
  1024579200000
  1284500000000
  2617460000000
  1291960000000
) do for /f "tokens=1,2" %%A in (
  'getTimestamp /d "!chapterTime!+%%T/1000000" /z 0 /f "{ums} <ChapterTimeStart>{hh}:{nn}:{ss}.{fff}</ChapterTimeStart>"'
) do (
  set "chapterTime=%%A"
  echo %%B
)
pause

--OUTPUT--

Code: Select all

<ChapterTimeStart>00:21:07.720</ChapterTimeStart>
<ChapterTimeStart>00:42:25.120</ChapterTimeStart>
<ChapterTimeStart>01:03:57.525</ChapterTimeStart>
<ChapterTimeStart>01:25:05.633</ChapterTimeStart>
<ChapterTimeStart>01:46:23.389</ChapterTimeStart>
<ChapterTimeStart>02:36:18.372</ChapterTimeStart>
<ChapterTimeStart>02:53:22.951</ChapterTimeStart>
<ChapterTimeStart>03:14:47.451</ChapterTimeStart>
<ChapterTimeStart>03:58:24.911</ChapterTimeStart>
<ChapterTimeStart>04:19:56.871</ChapterTimeStart>
Press any key to continue . . .

:D

Dave Benham

Re: Jeval.bat : command line calculator using native code

Posted: 25 Jan 2015 09:32
by foxidrive
That's brilliant Dave, thank you very much - except you diddled me out of 2 1/2 hours of program! That extra 0 wasn't a typo. :D

Code: Select all

<ChapterTimeStart>00:21:07.720</ChapterTimeStart>
<ChapterTimeStart>00:42:25.120</ChapterTimeStart>
<ChapterTimeStart>01:03:57.525</ChapterTimeStart>
<ChapterTimeStart>01:25:05.633</ChapterTimeStart>
<ChapterTimeStart>01:46:23.389</ChapterTimeStart>
<ChapterTimeStart>02:36:18.372</ChapterTimeStart>
<ChapterTimeStart>05:27:04.164</ChapterTimeStart>
<ChapterTimeStart>05:48:28.664</ChapterTimeStart>
<ChapterTimeStart>06:32:06.124</ChapterTimeStart>
<ChapterTimeStart>06:53:38.084</ChapterTimeStart>
Press any key to continue . . .


Much appreciated.

Just adding here that I'll post the solution you provided (adding the mkvtoolnix/mkvmerge.exe code to derive the
source times as shown) to the video forums as this task is not well solved in a google search.
One free chapter creation tool can only create chapters that are placed at a static duration for the length of the file.

The mkvtoolnix programs mkvpropedit.exe and mkvmerge.exe can apply the chapter .xml files and it's all free.

I owe you a beer!

Re: Jeval.bat : command line calculator using native code

Posted: 25 Jan 2015 11:23
by dbenham
Note that the result will be wrong if the time ever exceeds 24 hours. That can be fixed by substituting {uh} for {hh}, but then the hours will not be left padded to 2 digits.


Dave Benham

Re: Jeval.bat : command line calculator using native code

Posted: 25 Jan 2015 17:48
by foxidrive
dbenham wrote:Note that the result will be wrong if the time ever exceeds 24 hours. That can be fixed by substituting {uh} for {hh}, but then the hours will not be left padded to 2 digits.

Noted. Ta.

Re: Jeval.bat : command line calculator using native code

Posted: 27 Jan 2015 17:16
by catalinnc
@Dave thanks a lot for this nice tool

does have an option to output the result as hex number (9+2 = 0xB)?

what is the syntax for logic operations? (and, or, xor)?
_

n.b. for who is interested i noticed that it has 15 digits precision (decimal)
_

Re: Jeval.bat : command line calculator using native code

Posted: 27 Jan 2015 17:46
by Squashman
catalinnc wrote:@foidrive thanks a lot for this nice tool
_

You might want to thank Dave (dbenham). He is the one who wrote it.

Re: Jeval.bat : command line calculator using native code

Posted: 27 Jan 2015 17:48
by catalinnc
sorry. is fixed now.
_

Re: Jeval.bat : command line calculator using native code

Posted: 28 Jan 2015 06:50
by dbenham
@catalinnc - There is a wealth of JScript (javascript) info easily searched and accessed on the internet.

For example, I didn't know how to convert an int to hex notation, but the first link I found searching "jscript convert integer to hex" gave me the answer:

Code: Select all

jeval "'0x'+(9+2).toString(16).toUpperCase()"


I'll leave it up to you to find the mathematical bit operators and, or, xor (negate, left shift, right shift). Note - they only work with numbers within the 32bit signed integer range.


Dave Benham