VSCode api - get fsPath to current state of file - vscode-extensions

I'm trying to build an extension that uses jq to help parse and jump through large json files. I have the basics setup, the issue I'm running into is since I'm using jq in a child process execute (cp.exec(...)) I'm only able to parse the data that's saved on the file. While I want to be able to parse even that json data in the editor that isn't saved. I know this is possible since vscode does something similar with ripgrep for its search. For example in the vscode source code (src\vs\workbench\services\search\node) you can see ripgrep is launched as a child process and searches the files for matches. It seems to use the fsPath of the file but it gets current editor results but I dont using the activeTextEdtiro.document.uri.fsPath.
I know you can get the entire current contents of the editor with something like
vscode.workspace.openTextDocument(uri).then((document) => {
let text = document.getText();
});
or your can get the uri / fsPath to the file with
vscode.window.activeTextEditor.document.uri.fsPath;
But the problem is the uri is outdated (ie doesnt have the unsaved changes) and I cant pipe or echo all the text into the jq command in a cp.exec using the getText() method. So how do you fetch the uri to the current state of the file.

Related

Can vscode's markdown preview scripts trigger actions directly in an extension?

I'm writing a vscode extension where I'm hoping to squeeze more dynamic functionality out of markdown preview. Effectively the problem I'm trying to solve is:
In markdown preview, there's a checkbox
When user clicks the checkbox in markdown preview, send a message/event to the vscode extension runtime
Vscode extension can listen for this message/event and store the action in local storage
Checkbox state is saved - and subsequent renders of the markdown preview can use this action
Ideally, I'd like to do this while keeping the default markdown preview security (https://code.visualstudio.com/Docs/languages/markdown#_strict). After all, I don't need the extension to or markdown preview script to talk to a remote server - I just want them to be able to talk to one another.
Problem as code
To write the problem as sudo code, I want my markdown preview script to contain something like:
const button = ... // get button element
button.addEventListener('click', () => {
... /*
* Send a message to the vscode extension. Something like:
* `vscode.postMessage('vscode.my-extension.preview-action' + value)`
* (which I can't get to work, I'll discuss why)
*/
});
where then my extension can listen for messages like 'vscode.my-extension.preview-action'.
What I've Tried Already
I have tried acquireVsCodeApi() but because the markdown extension already does that, I can't do it again in the subsequent loaded script. I've also tried registering a uri handler but as far as I can try out the preview script still needs to fetch to that uri, which is still blocked by the default markdown security settings.
Perhaps markdown preview scripts are not the place to do this kind of thing, but I just wanted to leverage as much as possible that's already there with the vscode markdown extension. I want to supplement markdown but not replace it, the functionality I want to add is just icing on markdown documentation.
I've read https://code.visualstudio.com/api/extension-guides/markdown-extension#adding-advanced-functionality-with-scripts and it doesn't tell me much about markdown extension scripts capabilities and limitations.
Thanks to #LexLi I looked at some of the source code in the markdown extension and was able to come up with an ugly hack to make this work in preview scripts. Markdown allows normal clicks. And vscode extensions can handle normal clicks. I've paraphrased the code so there could be small syntax errors.
In the extension I did this:
vscode.window.registerUriHandler({
handleUri(uri: vscode.Uri): vscode.ProviderResult<void> {
console.log(`EXTENSION GOT URL: ${uri.toString()}`);
},
});
Then I made sure my extension/preview script put this in the document
<!-- in the preview script I place a button like this -->
<!-- it even works with hidden :) so I can do more app customization -->
<a
hidden
id="my-extension-messager"
href="vscode://publisher-id.my-extension"
>
cant see me but I'm there
</a>
Then my preview script I can even set href before faking a click:
const aMessager = document.querySelector("#my-extension-messager");
console.log('client is setting attribute and clicking...')
aMessager.setAttribute('href', 'vscode://publisher-id.my-extension?action=do-something');
aMessager.click();
console.log('client clicked');
Logs I saw (trimmed/tweaked from my particular extension to match the contrived example):
client is setting attribute and clicking...
client clicked
[Extension Host] EXTENSION GOT URL: vscode://publisher-id.my-extension?action%3Ddo-something
It's a hack but I can do a lot with this. Within the URL I can encode data back to the extension and kind of pass whatever I want (as long as data is relatively small).

Can JSFL be used to set a Global Include script?

We are converting several thousand .FLA files from SWF (Flash CS6) to HTML5 Canvas (Animate CC format). I have already written a JSFL script that automates the process:
Converts Compiled Clips to HTML5-friendly objects
Converts document to HTML5 Canvas format
Associates a new Publish Profile and HTML template with the document
Changes the publish filenames
So, the hard part is done! But I want to optimize it a bit more.
The current HTML template has some shared utility functions. The utility functions add 5-10kb to the file size of each animation, which themselves are probably in the 20-50kb range.
I would rather include these utility functions by setting a Global Include script, going to the top-left of the Actions panel, selecting Include, and adding a script with the + key. (When I'm done, it will show the URI underneath Global Script)
This produces the output I want, and it's perfect! The only downside is, I have to do this manually -- I'd like a way to associate the .JS file as a Global Include when running my JSFL conversion script.
Does anyone know of a JSAPI method to retrieve or set a Global Include script in HTML5 Canvas documents?
I haven't been able to find any documentation on such a function in JSFL/JSAPI. It doesn't seem like setting the scripts leaves a trace in the History pane, so I'm at a loss here.

Render HTML or GSP as a PDF and save it on server

I have an html template which I need to render as a .PDF and then save that pdf file on server. I'm using "rendering" plugin of grails. I'm able to render file as PDF but I don't understand how to save it on server location and not on user's system. Can anybody please help me ?
The pdfRenderingService provided by the plugin allows you to call render and get back an OutputStream. Using that output stream you can write that to a file on your server. The documentation explains the basics of using the service.
Your code may look something like this:
new File("report.pdf").withOutputStream { outputStream ->
outputStream << pdfRenderingService.render(template: '/report/report', model: [serial: 12345])
}
Well, actually I changed my plugin. Got Wkhtmltopdf plugin of grails more helpful. you can find it here --
https://github.com/quorak/grails-wkhtmltopdf
Also instructions regarding using this plugin you can find on the same link or here --
[https://github.com/quorak/grails-wkhtmltopdf]
Using this you can get "bytes" which you can write to file system.

how to dump dom and render tree with webkit on command line

I had built webkit with qt.
Now I want to write a program
input : an url or a html file.
output: the input page's dom tree and render tree, without the effect
of js.
I knew that the built-in program "dumprendertree" suits for me, but I want to get the output on command line because I worked on an OS without X-windows. I don't know how to switch the dumprendertree'output to stdout.
Thank you very much for any suggestions.

Saving pdf in the background using html2pdf

Am tryng to automatically generate pdfs using html2pdf class. I got the following code which is working fine, only that someone has to save the pdf manually. However, Whenever a new product is added, I would like to automatically save the pdf to some folder without user intervention, and store this value in a database for future reference.
How do I go about saving the pdf 'silently' i.e. in the background without showing any popups or requiring the user to intervene?
Thanks in advance.
include('pdf_content.php');
$content = ob_get_clean();
// convert to PDF
require_once('html2pdf/html2pdf.class.php');
try
{
$html2pdf = new HTML2PDF('P', 'A4', 'en');
$html2pdf->pdf->SetDisplayMode('fullpage');
$html2pdf->setDefaultFont('Arial');
$html2pdf->writeHTML($content, isset($_GET['vuehtml']));
//$html2pdf->Output($file_name.'_'.date("dmY").'.pdf');
$html2pdf->Output($product_id.'_'.$file_name.'_'.date("dmY").'.pdf');
You can try calling this script everytime a new product is added, although then you wouldn't really do it in the "background"...
For more information, please note the question "How can I run a PHP script in the background after a form is submitted?"
EDIT:
If you wish to save the file on the server instead of outputting it to the browser, you can use different parameters. See also the html2pdf-wiki. Be aware that you cannot save the file on the user's computer unnoticed!
$html2pdf->Output('directory/file_xxxx.pdf', 'F');