Some Background:
I've been looking for a way to programmatically create a pdf from a collection of images. It’s possible to do 90% of what I need through Word automation, but the problem is you can’t disable JPEG conversion when exporting to a PDF. Originally, I had hoped there’d be a free command line utility out there, but that’s not the case.
The best thing I could find is the JavaScript library jsPDF. I know almost nothing about Javascript, but library seems easy enough to use from the documentation.
This page has an extremely basic example of using JavaScript with VBA. Sadly there’s very little information out there on doing this kind of thing.
The only relevant thing I could find on Stackoverflow is this one unresolved post. I attempted the same method here and not surprisingly, it didn’t work. I get an error stating saying “syntax error” on the add code line.
Sub PDF1()
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Dim script As String
script = fso.OpenTextFile("***\jsPDF-master\src\jspdf.js", 1, False).ReadAll
‘This requires a reference to Microsoft Script Control 1.0
Dim o As New ScriptControl
o.Language = "JScript"
With o
.AddCode script
End With
End Sub
I really doubt this is the right approach. The entire library is probably 20k+ lines of code. Is what I’m trying to do even possible?
Any help would be greatly appreciated. Any other suggestions of alternate methods creating PDFs would also be helpful.
Related
I recently worked my way through a developer pre-screen via an online candidate testing platform. I've had bad experiences with these platforms in the past - poorly written/structured code, unclear instructions and code comments - but I'd yet to encounter a JavaScript question that (possibly) included C syntax ... until today.
The question was straightforward enough: create a function that took in a single parameter (milliseconds), converted that parameter to a new Date object and then returned only that Date's day-of-the-month.
Here was the boilerplate code I was asked to start with:
function convertMilliseconds(milliseconds) {
var result = -404;
return result;
}
var milliseconds = Number(gets());
console.log(convertMilliseconds(milliseconds));
Edit: To clarify, gets() was not explicitly referenced in the question's prompt, nor were there are any code comments in the web-based code editor asking me to implement it as a custom function. Here is a screen cap to illustrate:
Can someone please confirm for me that gets() is not part of the JavaScript Standard Library?
I've consulted the MDN docs and did not find anything in the entry for Number to indicate this was valid code. I did, however, find references to C library function called gets().
I try and make a point of using these pre-screens to fill any conspicuous gaps in my JavaScript knowledge. I'm pretty sure this is just a glaring error on the testing platform's part; I just want to be doubly sure I'm right before writing this off and moving onto other things.
I'm migrating an install script from js to vb.net and I'm facing the following problem.
I'm having issues as JS is late-binded so I need to research the datatype returned by each method in order to make the strong typed counterpart in vb.net (or C# for the matter)
In the original js install script, I'm getting to a point where I don't know how to port this 2 calls:
var objWMIService = GetObject("winmgmts:\\\\.\\root\\cimv2");
var objAccount = objWMIService.Get("Win32_SID.SID='S-1-1-0'");
If I leave data type inference, I get COMType, so I can't call the Get method from the generated object.
I think I could solve this by using IDispatch, but It's been like 10 years since I used IDispatch and I can't rememeber exactly how to do it.
Also, after further research, I've seen that the internal COM is actually a SWBemServicesEX object, which I don't know what to reference in order to generate a COM interop system.
I would appreciate it a lot, if anyone can provide any ideas or solutions to this issue.
Current vb.NET code is just:
Dim objWMIService = GetObject("winmgmts:\\.\root\cimv2")
not sure how to be able to call the Get method from objWMIService, and how to determine what this method actually returns!
I ended doing what Steve says in his answer and it solved the issue for me. I'm not very happy with runtime late binding, but it gets the job done!
for reference:
Try using Dim objWMIService as Object = GetObject("winmgmts:\.\root\cimv2") instead. Then you can use Dim objAccount as Object = objWMIService.Get("Win32_SID.SID='S-1-1-0'"). When doing late-binding, declare everything as an object. You can then step through the code in debug and sometimes see what the return is. Then search for the methods/properties/etc for that type and write your next line. Takes a little work but you don't need references to any dlls. Theres just an assumption that the dll are registered (COM) or in your path that .Net follows (CLR)
Using the Firefox Web Console (which can be brought up with control shift k ) I can easily access things like flowplayers.
jwplayer().play(), for example
The console even offers autocompletion suggestions for it.
What does the console do to be in that kind of, for my lack of words and knowledge, namespace?
I tried things like
content.document.getElementsByName('flvplayer').item(0)
Using Pentadactyls JS intepreter (accessed with :js)
This does seem to give me the player handle, or at least it prints out a <html:object> which corresponds to it.
Appending a .play() to it doesn't work, though. It's not a function.
What do I need to do to emulate the Web-Consoles way of doing it?
I realize that this might be a very spoonfeedy question, so if that is not acceptable then I'd still appreciate to get pointed into directions where I could possibly discover the solution myself by reading.
I tried searching for it myself but the terms seem to be quite ambiguous and I usually get results with people talking about their own sites, with scripts running inside of that 'namespace', not from outside like I am trying to do.
(Unless I am wrong about the concepts of inside and outside here.)
Cheers~~
The following command works for me; it defines the command ypl which
plays the YouTube video on the page
command! ypl open javascript:(function()
{content.document.getElementById('movie_player').playVideo()})()
Another example: this defines the ytr command which takes an integer argument and moves the current time position of the video by that amount in seconds
command! -nargs=1 ytr open javascript:(function(){var vid =
content.document.getElementById('movie_player'); vid.seekTo(vid.getCurrentTime() +
(<args>), true)})()
I hope that helps a bit. When I wrote those a while ago I may have tried :js and if it didn't work used :open javascript:....
So I'm making a Gnome Shell extension. And I want to be able to run some command. (The command is actually "synclient -m 100", but that is off topic)
So, what I have done so far is
s=GLib.spawn_async_with_pipes(null, ["synclient","-m","100"], null, GLib.SpawnFlags.SEARCH_PATH,null)
c=GLib.IOChannel.unix_new(s[3])
The first line spawns my process. It is definitely working.
s[3] is the file descriptor for the stout of the process. (It has something to do with pipes. Not really sure about the whole pipe thing.)
Anyway, my problem is that I can't seem to read anything from the output of synclient.
This is what I'm using for reference, but it seems that not all of the functions work. For example, I want to use add_watch, but that apperently doesn't work with gnome extensions.
I've tried using a bunch or read functions and specifically read_line_string, but they all have problems. For read_line_string it seems like it should all work except I can't figure out how to create a StringBuilder object to pass as an argument.
So, does anyone know how to get the output of a command?
Edit: also I'm kind of confused about which language the extensions use. I think it's javascript, but the docs I'm using seem to make me think Vala, whatever that is (I'm guessing a variation of java?).
Edit 2:
So, what I've got now is
let [res, pid, in_fd, out_fd, err_fd] =
GLib.spawn_async_with_pipes(
null, ["synclient","-m","100"], null, GLib.SpawnFlags.SEARCH_PATH, null);
out_reader = new Gio.DataInputStream({ base_stream: new Gio.UnixInputStream({fd: out_fd}) });
And to read a line:
let [out, size] = out_reader.read_line(null);
This gives me the output of the command, but it still doesn't give me any way to get some callback whenever the DataInputStream is changed. I need to be able to do something whenever there is a new line in the stream.
Gnome Shell extensions are usually written in JavaScript. They use JavaScript bindings to libraries like GLib that are written in C. There are also Vala bindings to those libraries, and that is the documentation you are looking at. Here is the documentation for the JS bindings, unofficial as yet.
StringBuilder is a Vala language feature that corresponds to GLib.String in JS.
How do you know add_watch() doesn't work? What do you expect and what does it do instead?
I've had some experience with Java and Javascript and searching this forum has helped me tremendously, but haven't been able to find this exact problem explicitly. In a nutshell: I want to call a java class straight from Javascript i.e. use a Java class in Javascript without OBJECT or APPLET.
Here's what what I'm experimenting with:
function screenSize() {
alert("Screen Dimension\n" + " width:"
+ java.awt.Toolkit.getDefaultToolkit().getScreenSize().width
+ " height:" + java.awt.Toolkit.getDefaultToolkit().getScreenSize().height);
}
which is an example given on http://www.rgagnon.com/javadetails/java-0170.html. This is hooked to a button on a page. When clicking the button I (in essence) get:
A Runtime Error has occured at line 35: 'java' is undefined.
I'm assuming that my path is incorrect or missing and there's a PATH or CLASSPATH or something I've overlooked.
I'd eventually like to move the javascript into a bookmarklet so that the user will be able to click a favorite on the appropriate page and have magic happen because of my own java classes manipulating the data from the screen. For various reasons political and technical, I'm stuck using IE6-7 and have to work with scraping the web page in the browser and processing it on the client -- no sever side action for me! I can assume that a JRE 6 will be available.
Is it a path issue? Is what I want even possible and if so, how? And how will packages work with all this?
Any advice or examples will be muchly appreciated.
The tip shown at Real's HowTo used to work, but doesn't anymore. Insert an applet and define public methods to interact with.
In the link you referenced, did you notice this information at the top?
On IE4 or better, you can't call java.* methods directly from Javascript or Jscript.
It goes on to explain that an Applet is needed. Of course, IE4 is rather old, not sure how much of this is still relevant. Good luck!