npPasc plugin

About this plugin

This plugin put on your publication a very complete pascal source code interpreter. You can use it (for example) to automate changes on your publications without need to recompile. The interpreter prebuild dozens of Classes, Functions, and more stuff.

Take a look at the interpreter prebuild stuff and get freeze. But not only you can use this complete prebuild stuff, also the Pascal source code can interact with NeoBook and viceversa. You can call NeoBook subroutines, get and set NeoBook variables and more.

The interpreter know a dialect of Pascal language and add some Delphi related stuff too. You can play with Pascal units "on the fly", can use variables, constants from others units or from your main unit. Finally, with a little of Pascal/Delphi knowledge now is possible to use this powerfull language and lot of their resources from your NeoBook publications.

Thirparty

This plugin are imposible without the aid of this people:

Thanks a lot!

Plugin actions index

npPascCreate

Create a new instance of an Pasc object. The result variable store the numeric ID of the new created Pasc object instance. You need this ID on other plugins actions.

↑↑

npPascDestroy

Destroy a previously created instanace of an Pasc object. The result variable store "True" if everything is OK, or "False" if not. In this last case the [LastError] contain information about the error.

↑↑

npPascDestroyAll

Destroy all previously created instances of Pasc objects.

↑↑

npPascRunCode

Run a Pasc object providing the source code to be executed. As you can see in the plugin samples, you can execute code place between a "begin end;" block. Also the executed code can have a result, wich can be set using the pascal way: "result := 123". If your source code are between a simple "begin end;", you dont need to specify what main function must be executed.

When your code are into a unit, for example:

unit MyUnit;

function Main() : integer;
begin
  ShowMessage( 'Hello world!' );
  result := 123;
end;

end.

The plugin call to the "Main" function by default, if you dont specified the name of other function on your code. You can use all the available Pascal interpreter prebuild stuff, plus the functions, variables, NeoBook subroutines and other stuff added by yourself.

The result variable store the code result, provide by the simple "begin end;" block or by the "main" function, if everything is OK, or "False" if not. In this last case the [LastError] contain information about the error.

↑↑

npPascRunFromFile

Run a Pasc object providing a file with the source code to be executed. Same that npPascRunCode but using a file source code instead of provide the code (as a string) directly. The result variable store "True" if everything is OK, or "False" if not. In this last case the [LastError] contain information about the error.

↑↑

npPascAddUnitFile

Add a unit source code from a file to be available on the uses clausule of other units from an Pasc object instance. You can use npOnPascUnitSource to add units on the fly, but this action can add units "statically". The result variable store "True" if everything is OK, or "False" if not. In this last case the [LastError] contain information about the error.

↑↑

npPascAddUnitSrc

Add a unit source code to be available on the uses clausule of other units from an Pasc object instance. See npPascAddUnitFile too. The result variable store "True" if everything is OK, or "False" if not. In this last case the [LastError] contain information about the error.

↑↑

npPascAddSub

Add a subroutine to be available on the Pasc object when run their source code. Provide the subroutine name, and the params types. Use the action properties dialog, double click on the params types list and your choice are automagically added on the needed action argument.

The params types currently available are: varString and varInteger. Note that the function params count is decuded by the plugin from the params types: if you choose two params types, then the function/subroutine need/has two params.

When the subroutine you determine is executed, some variables are available. And, like a NeoPlugins convention, just after the subroutine is executed these variables are clear from memory. This avoid variables flood. You can use this variables on every subroutine you add:

So you can play with this variables and, finally, set the function/subroutine result. For do this just use the [Pasc.Result] variable. So here is a simple sample that supose a subroutine "MySum" with two arguments availables:

:MySum
  .Just sum the arguments and return it
  SetVar "[Pasc.Result]" "[Pasc.Args0] + [Pasc.Args1]"
Return

Of course you can, for example, test if certain argument is into some range, etc. And maybe inform the user of this kind of errors. Finally the result variable store "True" if everything is OK, or "False" if not. In this last case the [LastError] contain information about the error.

↑↑

npOnPascGetValue

Set a subroutine to be execute when a unknow identifier is found on the Pasc object running source code. When this subroutine is execute you can found some variables at your service, so, is easy to found what identifier is not found (by name), what value assign to it, if needed, etc. Here is the list of variables that you can use on this subroutine:

Apart of the above variables, you can set another two variables into the subroutine:

Take a look at this last variables. The "Done" is an important variable, because if you dont set this to true, the interpreter fail with an "Unknow identifier" error. So when you assign "True" to "Done" you want to said: "Ok, I put a value for this identifier, go ahead with the rest of code". I recomend you that play a little with the plugins examples that deal with this.

The current supported value types are: varString and varInteger. You can assign to the value type variable the identifier value type that you set on the value variable. If you dont assign any value the Pasc object take as the default: varInteger. Supose your code is: "A + B", when A = 1 and B = 2. If you chose "varString" types for this identifiers then the operation result is "12", not "3".

Please, note that the object ID variable store the Pasc object instance ID that fire the event. This variable is not on the above list because his name is can be defined by you when edit this action. The result variable store "True" if everything is OK, or "False" if not. In this last case the [LastError] contain information about the error.

↑↑

npOnPascUnitSource

Set a subroutine to be executed when a unknow unit is found on the Pasc object running source. When an unknow unit is found on the uses clause of your source code, this subroutine is executed, allowing you to provide the source for the requested unit. On this subroutine are available this variables:

So you can find if the unit name is that you expected, and if so, set appropiately this other subroutine variables:

Take a look at this last variables. The "Done" is an important variable, because if you dont set this to true, the interpreter fail with an "Unknow identifier" error. So when you assign "True" to "Done" you want to said: "Ok, I put a value for this identifier, go ahead with the rest of code". I recomend you that play a little with the plugins examples that deal with this.

Please, note that the object ID variable store the Pasc object instance ID that fire the event. This variable is not on the above list because his name is can be defined by you when edit this action. The result variable store "True" if everything is OK, or "False" if not. In this last case the [LastError] contain information about the error.

↑↑

 

Interpreter prebuild stuff

The Pascal interpreter used on this plugin is very complete. In fact provide a good interpreter with a acceptable speed using a dialect of the Pascal programming language. I cannot to explain here all the Delphi/Pascal related stuff, so, if you unknow how to write Pascal source code and unknow how to use the stuff provided by the interpreter, I recomend you to search on Internet and read some books around this great language.

For the other hand is not neccesary much experience to begin writing your own code, Pascal is a very affordable and user friendly language, in my opinion. And for the other hand too you can omit the use of Pascal stuff and use only subroutines that you can add using the plugin, to be available in the interpreted code. In any case, here is the list of stuff prebuild on the interpreter an available to use. *

* Never forget that we deal with a Pascal dialect: some of Pascal or Delphi capabilities are not available, and others can be not complete. For example, some classes are available to use, but no all the classes methods can be accesibles. In any case I recommend you to play with the plugin samples.

↑↑

From NeoBook

Actions

↑↑


From System unit

Classes

Functions / Procedures

Constants

↑↑


From SysUtils unit

Exceptions classes

Functions / Procedures

Constants

Records

↑↑


From Classes unit

Constants

Classes

Handlers

↑↑


From Windows unit

Records

Functions / Procedures

Constants

↑↑


From Graphics unit

Classes

Constants

↑↑


From Controls unit

Classes

Handlers

Functions / Procedures

Constants

↑↑


From Buttons unit

Classes

↑↑


From StdCtrls unit

Classes

Handlers

Constants

↑↑


From ComCtrls unit

Classes

Handlers

Constants

↑↑


From ExtCtrls unit

Classes

Constants

↑↑


From Forms unit

Classes

Functions / Procedures

Handlers

Constants

↑↑


From Dialogs unit

Classes

Functions / Procedures

Constants

↑↑


From Menus unit

Classes

Functions / Procedures

↑↑

Action errors subroutine

All the NeoPlugins deal with errors in the same way that NeoBook does: when the plugin found an action error the [LastError] variable store information about the error, so you can take care about this variable when execute an action.

But all the NeoPlugins also incorporate an advanced way to deal with possible action errors. You can define a subroutine named OnNeoPluginActionError in order to be executed when some action error are found and you can use this variables inside:

Note that this error handling subroutine are shared for all the NeoPlugins, so you no need to specify a subroutine for every plugin you use in your publication because the same subroutine are recognized and automagically used by every NeoPlugin. Below you can view a sample of this subroutine code:

:OnNeoPluginActionError
  AlertBox "NeoPlugin Error" "Error [LastError] in plugin: [PluginName]"
Return

Also note that the use of this NeoPlugins error handling subroutine is completelly optional. You can continue using the [LastError] variable as usual and even use the both methods at the same time.

↑↑