<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML lang="en">
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
<link href="style.css" rel="stylesheet" type="text/css">
<title>3.8.4. Calculations, strlen and so on</title>
<script src="show_matches.js" type="text/javascript"></script>
</HEAD>
<BODY>
<h3>3.8.4. Calculations, strlen and so on</h3>
<p>NppExec ver. 0.4 introduces built-in calculator abilities provided by Function Parser (fparser). To calculate your math expression, use the special form of the SET command:</p>
<blockquote>
  <pre>set result ~ &lt;math expression&gt;</pre>
</blockquote>
<p>For example:</p>
<blockquote>
  <pre>set result ~ sin(pi/4) + cos(pi/4)</pre>
</blockquote>
<p>If this example gives you an error &quot;- fparser calc error: Syntax error: Unknown identifier at pos 4&quot;, it means you do not have necessary NppExec files in your &quot;Notepad++\plugins\NppExec&quot; folder. In such case, you need to download the latest NppExec package manually and unpack it to your &quot;Notepad++\plugins&quot; folder <a href="2.3.html">[2.3]</a>.</p>
<p>You can find more details regarding fparser's syntax and abilities inside the file &quot;Notepad++\plugins\doc\NppExec\fparser.html&quot;.</p>
<p>By the way, NppExec also uses fparser for its own purposes such as internal implementation of NPP_SENDMSG and SCI_SENDMSG. In particular, fparser is used to calculate and store the values of constants defined inside &quot;Notepad_plus_msgs.h&quot;, &quot;Scintilla.h&quot; and other files in the &quot;Notepad++\plugins\NppExec&quot; folder. But this is just for information; never mind :)</p>
<blockquote>
  <pre> </pre>
</blockquote>
<p>There are two special cases of this form of the SET command which are processed by NppExec itself. I am talking about</p>
<blockquote>
  <pre>set n ~ strlen &lt;string&gt;</pre>
</blockquote>
<p>and</p>
<blockquote>
  <pre>set n ~ strlenutf8 &lt;string&gt;</pre>
</blockquote>
<p>These two functions calculate an ANSI and an UTF-8 string length. For Latin characters, both 'strlen' and 'strlenutf8' will return the same value. But for non-Latin characters (such as Cyrillic), 'strlenutf8' will return a greater value than 'strlen' because each non-Latin character in UTF-8 may be represented by 2 or 3 bytes (unlike Latin characters which are always represented by 1 byte in UTF-8). Actually, 'strlenutf8' returns the number of bytes in an UTF-8 string. This number has to be specified for some Scintilla's messages invoked via SCI_SENDMSG. Type &quot;help sci_sendmsg&quot; in NppExec's Console for more details regarding SCI_SENDMSG.</p>
<p>Here is an example which uses 'strlen' and SCI_SENDMSG:</p>
<blockquote>
  <pre>set s = My string
set n ~ strlen $(s)
SCI_SENDMSG SCI_APPENDTEXT $(n) &quot;$(s)&quot;</pre>
</blockquote>
<p>If you want to add spaces before and after &quot;My string&quot; (e.g. to have &quot; My string &quot;), you should modify the script since NppExec removes leading and trailing spaces around the value:</p>
<blockquote>
  <pre>set s =  My string   // leading/trailing spaces will be removed
set n ~ strlen $(s)  // length without leading/trailing spaces
set n ~ $(n) + 2     // length with additional two spaces
SCI_SENDMSG SCI_APPENDTEXT $(n) &quot; $(s) &quot;  // adding the spaces</pre>
</blockquote>
<p>You will encounter similar problem when calculating 'strlen' of a string which starts or ends with spaces. These spaces will be removed before calculating the string length. To avoid this, you should enclose such string in double quotes:</p>
<blockquote>
  <pre>set n ~ strlen &quot;  ABC &quot;  // n=8: string length with two &quot; symbols
set n ~ $(n) - 2         // n=6: length without the &quot; symbols</pre>
</blockquote>
<p>NppExec ver. 0.5 had introduced several additional functions: strupper, strlower and substr. Even more functions have been added later. Type &quot;help set&quot; for more details.</p>
<p>Here is an example that uses substr to extract a directory name from $(CURRENT_DIRECTORY) :</p>
<blockquote>
  <pre>npp_console local -
set local dirname = $(CURRENT_DIRECTORY)
set local c ~ substr -1 1 $(dirname)  // trailing character
if &quot;$(c)&quot; == &quot;\&quot; then
  set local dirname ~ substr 0 -1 $(dirname)  // removing trailing \
else if &quot;$(c)&quot; == &quot;/&quot; then
  set local dirname ~ substr 0 -1 $(dirname)  // removing trailing /
endif
set local n1 ~ strrfind &quot;$(dirname)&quot; \  // position of last \
set local n2 ~ strrfind &quot;$(dirname)&quot; /  // position of last /
if $(n1) &gt; $(n2) then
  set local n1 ~ $(n1) + 1
  set local dirname ~ substr $(n1) - $(dirname)
else
  set local n2 ~ $(n2) + 1
  set local dirname ~ substr $(n2) - $(dirname)
endif
npp_console local +
echo $(dirname)</pre>
</blockquote>
<blockquote>
  <pre> </pre>
</blockquote>
<p>Now let's discuss something different: pseudo-conditions in NppExec. Pseudo-conditions are available via the NPP_EXEC command plus some variable. The next idea lies behind this: you can form a script name dynamically in order to execute different script basing on some variable's value. Let me explain: a command &quot;NPP_EXEC script$(var)&quot; will execute different script according to the value of $(var). For example, let's assume you want to execute some program and then to have different behaviour depending on successful or unsuccessful execution of that program. Of course, you can use &quot;cmd /c program &amp;&amp; do_something_different&quot; to achieve this, but such approach does not allow to use NppExec-specific functions (since everything is executing under cmd.exe). So, let's assume we have the following script:</p>
<blockquote>
  <pre>program.exe  // execute the program
NPP_EXEC OnProgramEnd_$(EXITCODE)  // pseudo-condition</pre>
</blockquote>
<p>Any program &quot;program.exe&quot; is expected to return 0 in case of its successful execution. Otherwise it returns non-zero value. (This is a common behaviour of executables.) Thus we can create NppExec's script named &quot;OnProgramEnd_0&quot; which will be called only in case of successful execution of &quot;program.exe&quot; -- i.e. when $(EXITCODE) will be 0. Otherwise, in case of -1 or 1 (and so on) we will try to execute non-existing script &quot;OnProgramEnd_-1&quot; or &quot;OnProgramEnd_1&quot; (and so on).</p>
<p>For example, create the following script and name it &quot;OnProgramEnd_0&quot; to test the previous statements (and the pseudo-conditions, actually):</p>
<blockquote>
  <pre>// OnProgramEnd_0
echo The program returned 0: executed successfully!</pre>
</blockquote>
<p>So, we can say that the two above scripts allow us to emulate an IF condition. Here is its meaning: IF (program.exe returns 0) THEN execute &quot;OnProgramEnd_0&quot;. Otherwise we try to execute non-existing script that can be treated as &quot;do nothing&quot;.</p>
<p>Going further, we can implement an IF-THEN-ELSE statement in a similar way. Our script will be changed a little:</p>
<blockquote>
  <pre>program.exe  // execute the program
set N ~ $(EXITCODE) != 0
NPP_EXEC OnProgramEnd_$(N)  // pseudo-condition</pre>
</blockquote>
<p>The value of $(N) will be either 1 (true) when $(EXITCODE) is not 0, or 0 (false) when $(EXITCODE) is 0. So we will execute either &quot;OnProgramEnd_0&quot; or &quot;OnProgramEnd_1&quot;. Now the only remaining thing is to create a script named &quot;OnProgramEnd_1&quot;:</p>
<blockquote>
  <pre>// OnProgramEnd_1
echo The program returned non-zero: execution failed.</pre>
</blockquote>
<p>NppExec ver. 0.5 introduced native support of IF-GOTO commands. Type &quot;help if&quot; for more details.</p>
<blockquote>
  <pre> </pre>
</blockquote>
<p>Finally, let's talk about &quot;special&quot; characters in NppExec. I mean &quot;//&quot; (a comment) and a double quote symbol.</p>
<p>While using a command with a comment, all the text after &quot;//&quot; is being cut from that command.</p>
<p>But what if you want to use &quot;//&quot; as a part of your text? Is it possible to do it?</p>
<p>Yes, it's possible. You can use environment variables for that:</p>
<blockquote>
  <pre>set a = /          //  now $(a) is &quot;/&quot;
echo $(a)$(a)      //  prints &quot;//&quot;
set s = $(a)$(a)   //  now $(s) is &quot;//&quot;</pre>
</blockquote>
<p>The same technique can be used to pass a double quote symbol: </p>
<blockquote>
  <pre>NPP_SENDMSG WM_COMMAND IDM_FILE_NEW
set q = &quot;
sci_sendmsg SCI_SETTEXT 0 &quot;$(q)some text in double quotes$(q)&quot;</pre>
</blockquote>
<p>Not a big trick, actually, but may be useful :)</p>
<p>See also: Calculating <a href="4.6.2.html">[4.6.2]</a>; Passing enquoted strings and special characters <a href="3.8.5.html">[3.8.5]</a>.</p>
</BODY>
</HTML>
