Using JavaScript to place the annotation to clipboard first  SOLVED

Forum for the PDF-XChange Editor - Free and Licensed Versions

Moderators: PDF-XChange Support, Daniel - PDF-XChange, Chris - PDF-XChange, Sean - PDF-XChange, Paul - PDF-XChange, Vasyl - PDF-XChange, Ivan - Tracker Software, Stefan - PDF-XChange

JCatsuki
User
Posts: 5
Joined: Wed Apr 01, 2026 3:36 pm

Using JavaScript to place the annotation to clipboard first

Post by JCatsuki »

Hello!
Im a QS who uses PDF-XChange as a takeoff app.
My coding skill is pretty much non existent so I heavily rely on this forum and of course, ai.
Im trying to learn how to code those on my free time to help me understand coding more.

What i want to ask is if there's a way to use JS to place a predefined annotation (oval or rectangle drawing tool) in the clipboard first instead of placing it anywhere on the pdf?
Im trying to make a Counting Tool similar to most takeoff apps (idk know if there's one here already), or something a work around.
Since PDF-XChange has a "paste to where the mouse is pointing" feature, i want that as a work around.

Thanks in advance.
Mathew
User
Posts: 794
Joined: Thu Jun 19, 2014 7:30 pm

Re: Using JavaScript to place the annotation to clipboard first

Post by Mathew »

JCatsuki wrote: Thu Apr 02, 2026 12:25 pm Hello!
Im a QS who uses PDF-XChange as a takeoff app.
My coding skill is pretty much non existent so I heavily rely on this forum and of course, ai.
Im trying to learn how to code those on my free time to help me understand coding more.

What i want to ask is if there's a way to use JS to place a predefined annotation (oval or rectangle drawing tool) in the clipboard first instead of placing it anywhere on the pdf?
Im trying to make a Counting Tool similar to most takeoff apps (idk know if there's one here already), or something a work around.
Since PDF-XChange has a "paste to where the mouse is pointing" feature, i want that as a work around.

Thanks in advance.
Hi JCatsuki,
Javascript does not have access to the clipboard in PXCE. Is this something that can be done with a stamp? If you want javascript to place it, js can add a stamp from your predefined stamps using doc.addAnnot().
- Mathew.
User avatar
Daniel - PDF-XChange
Site Admin
Posts: 12611
Joined: Wed Jan 03, 2018 6:52 pm

Using JavaScript to place the annotation to clipboard first

Post by Daniel - PDF-XChange »

:)
Dan McIntyre - Support Technician
PDF-XChange Co. LTD

+++++++++++++++++++++++++++++++++++
Our Web site domain and email address has changed as of 26/10/2023.
https://www.pdf-xchange.com
Support@pdf-xchange.com
JCatsuki
User
Posts: 5
Joined: Wed Apr 01, 2026 3:36 pm

Re: Using JavaScript to place the annotation to clipboard first

Post by JCatsuki »

Mathew wrote: Thu Apr 02, 2026 9:08 pm Hi JCatsuki,
Javascript does not have access to the clipboard in PXCE. Is this something that can be done with a stamp? If you want javascript to place it, js can add a stamp from your predefined stamps using doc.addAnnot().
- Mathew.
Thanks for the answer, I am somewhat aware of that fact. I just want to be sure since since it's the ai who first told me that.
And yes, the stamp is the closest tool to the counting tool of takeoff apps, but i was told that stamps, by default, bloats the pdf file.
So im looking for ways to simulate the counting tool. I dont need a counting script though, PXCE (or most pdf editors) natively counts the annotations depending on how the user sorts it.
Here what ive been thinking and done so far:
  1. Make a set of very simple stamps so it wont bloat my files too much. [Simplest approach, i think]
  2. Use any stamp for counting, then select all those stamps, use a JS to convert/replace said stamps to simple drawing annot (like oval or rectangle) complete with needed parameter/properties. This one was actually suggested by Gemini. But this isnt a counting tool, this more like a batch correction/revision tool. And so i repurposed this approach into that tool. [REVISED/REPURPOSED]
  3. Next is to make a stamp with a certain tag in one of it parameter. Whenever I place that stamp on the pdf a JS will detect the tag of that stamp then replace that stamp with again a drawing annot of predefined properties. Basically the main idea is just to borrow the stamp's way of placing the annot. But since i lacked expertise on coding, rellying on ai wont really help me that much. [FAILED]
  4. Which led me to this approach. Since PXCE has a feature of pasting to where the mouse is, I decided to try making a JS that lets you create an oval/rect annot then instead of placing it somewhere on the pdf (like what two AIs suggested to me), it will place it in the clipboard instead. This way, it skips to the part were to I need to find the created annot on the pdf then select>copy>delete the annot. But as what you and (2) ai have said, "Javascript does not have access to the clipboard in PXCE". [FAILED]
Do you have any suggestion? Im happy to take even negative responses as long as I learn from it.
.
PS. I never expected you were the one who would reply to my post. Im actually very thankful to one of the JS you've made, the annotation report, the one that counts annotations then consolidates it. I did tweak it to my needs though. I also did try making something of a Region Tool that is based on your JS, it basically just counts all the annots inside an highlighted area. Great if the client wants to determine how many devices are there in a certain area.
Mathew
User
Posts: 794
Joined: Thu Jun 19, 2014 7:30 pm

Re: Using JavaScript to place the annotation to clipboard first  SOLVED

Post by Mathew »

JCatsuki wrote: Fri Apr 03, 2026 6:54 am Do you have any suggestion? Im happy to take even negative responses as long as I learn from it.
Hi Catsuki,

I'm thinking the free highlight tool could be very useful for counting. It has the benefit of being quick to place, customizable (you can set custom subjects and colors to ease counting different types), and is a simple annotation rather than a stamp. Very happy to hear you found one of my tools useful, and it's good to hear that you found ways to customize it. Open Source in action :)

I went off on a bit of a tangent with the bloat issue, so apologies in advance for being off-topic:

I was unaware that stamps bloat files. In theory, if they are the same stamp, PXCE should recognize that fact and actually use less space because it can refer to the same stamp instead of duplicating the annotation data. I did a simple test:
  1. copying a very simple annotation (rectangle) and a stamp made of that same rectangle 1000 times (using javascript), and
  2. duplicating the same using the Edit > Duplicate tool (also 1000 times).
image.png
The copied stamp file is (as you said) 30% larger - my guess is because of a larger overhead for storing stamps than annotations(?) The duplicate tool is vastly more efficient for both.

However, IMO, PXCE could keep track of the stamps used in a file, and if that stamp is reused without any changes, it could do the same as it does for the Duplicate command. There may be a feature request related to this floating around somewhere, because I vaguely remember this coming up in the past. (Actually, doing this for the js doc.addAnnot method may be simpler because javascript cannot modify stamps.)

I did also try a brief test just placing the same stamp over and over, but didn't have the patience to do 1000 of them - I did 100 and it seems that the program is adding the same data over and over (similar to test 1 above), rather than the more efficient approach used by Duplicate.

Big picture: If the stamps are small, the amount of bloat is also very small. For 1000 stamps, even in the un-optimized approach, it only added (305k - 237k = 68k using stamps) -- ie only 68 bytes (0.068k) per stamp. I'm constantly dealing with vastly more bloated pdfs (ie from Autocad or Revit where hatch patterns are used at small scales).

Coding: Another approach, that I'm sure you can get AI to expand on, is to use an async function to replace a placed stamp or other annotation. See this post for an example script: viewtopic.php?p=201993#p201993

- Mathew.
You do not have the required permissions to view the files attached to this post.
JCatsuki
User
Posts: 5
Joined: Wed Apr 01, 2026 3:36 pm

Re: Using JavaScript to place the annotation to clipboard first

Post by JCatsuki »

Mathew wrote: Fri Apr 03, 2026 4:12 pm
PXCE JavaScripts 2026.04.05.rar
Hi Catsuki,

I'm thinking the free highlight tool could be very useful for counting. It has the benefit of being quick to place, customizable (you can set custom subjects and colors to ease counting different types), and is a simple annotation rather than a stamp. Very happy to hear you found one of my tools useful, and it's good to hear that you found ways to customize it. Open Source in action :)

I went off on a bit of a tangent with the bloat issue, so apologies in advance for being off-topic:

I was unaware that stamps bloat files. In theory, if they are the same stamp, PXCE should recognize that fact and actually use less space because it can refer to the same stamp instead of duplicating the annotation data.

(.....)

Big picture: If the stamps are small, the amount of bloat is also very small. For 1000 stamps, even in the un-optimized approach, it only added (305k - 237k = 68k using stamps) -- ie only 68 bytes (0.068k) per stamp. I'm constantly dealing with vastly more bloated pdfs (ie from Autocad or Revit where hatch patterns are used at small scales).

Coding: Another approach, that I'm sure you can get AI to expand on, is to use an async function to replace a placed stamp or other annotation. See this post for an example script: viewtopic.php?p=201993#p201993

- Mathew.
Hi Mathew,

Good News!!! You're suggestion works!
I've noticed it's similar to my failed 3rd approach, but still it worked thanks to you!
Well, I honestly cant explain it in detail how the JS went, but iv'e instead uploaded all my JS custom tools that "I've" made together with the slightly tweaked JS that you had made so you can see it for yourself, and of course to share it to all users here too.
One last request (it's off topic by now), can you teach me how to use custom icons inside the JS? The AI was able to use one but it messes up the colors.
Or may be just post the link here if it's already discussed in other threads/posts.
Thanks Again!

PS. Here's the list of what the attachment contains:
PXCE JavaScripts 2026.04.05.rar
  1. annotReport, Mathew's JS. Basically counts or sums up all annotations depending how the user's want to sort it. Slightly tweaked the output only. Select first the annot that you needed to counted or just select count all in the dialog box.
  2. autoLayout, draws a polyline(Perimeter Line) along the selected drawing annotations thru its center. This is to simulate Electrical Layouts, hence the name. I was surprised that PXCE or JS was able to determine the sequence of which annot ive selected first up to the last annot. It also has a crude feature, the "priority wireway", basically it checks if you had selected a line annot that has "WIREWAY" as a tag then draws a polyline along that line. This is to simulate a literal wireway.
    1. Select the annot that you needed to be "connected" then click the autoLayout tool. Becareful which you select first as the line follow the sequence of your selection.
    2. If you have a priority wirewar, say a cable tray, include it in the sequence of your selection.
    3. Now click the autoLayout tool and there's your "layout".
    First annot will be the origin of the line then goes to the next annot up to your last annot. As to how it traces the "priority wireway", it first goes to the nearest vertex of the "wireway"/line (I suggest you add a control point on the said wireway so the layout will catch it). It will check which is nearer, the next device/annot or the next vertex. If the device is closer then it will exit immediately from the wireway and onto the device. If the next vertex is closer then it will go to that vertex and then checks again which is nearest up until it reaches the end vertex. If let's say, you didnt like the layout, you can edit it like everyone does with pdf editors.
    This is the very tool im looking in takeoff apps it generally saves you time drawing lines all through out the plan/pdf.
  3. calcMarkups, the heavily tweaked version of Mathew's annotReport. What I mainly tweaked here is the choices of what to compute. I've removed Mat's 3 options and replaced it "smart computing", basically means all line (measurements) annotations w/ similar parameters will be summed up and all drawing annotations w/ similar parameter will be counted. I also removed most of the parameters used for sorting and retained the parameters that were most likely used by quantity estimators. Why I made a separate one instead of just totally replacing Mat's? Because this one mainly caters estimators, I want Mathew's to be for general users.
  4. countingTool, it simulates the counting tool by known dedicated takeoff apps. It uses the stamp tool, and I would recommend you to create a dedicated custom stamp for this.
    Here are the steps:
    1. Create a custom stamp. Make it small enough to not block your view when marking up. Add it to your stamp pallete and remember what name you gave to it, that should match the tag which will be explained next
    2. Click the counting tool, it's located in the Manage Comments section under the Comment Ribbon (all of my custom tools are there). You can see a text box that says stamp tag. That should match the name of your stamp.
    3. Set everything else you need and click ok. The stamp tool will be activated and a bar below will appear, make sure you've selected the Counting stamp that you've made.
    4. Start click/counting. If you're done, close the bar that appeared below.
    5. I would sugget that you should select first the counting stamp before click the counting tool. PXCE remembers the last stamp used, this means that the counting stamp will be automatically selected upon going thru the counting tool diaglog box and you can start click immediately.
    Upon clicking the JS would replace that stamp with the drawing annot you've set.
    What I've shared here is just the base version. I've already updated this so i can have dedicated stamps for each type of markup (electircal loads vs wiring devices vs boxes vs panels vs etc). Max of 7 tags.
  5. regionTool, also simulates the tool of a similar same from takeoff softwares. Inspired again from Mat's annotReport. It uses Rectangle or Polygon annotations. Rectangle for block shaped areas/rooms and Polygon for irregular shaped areas/rooms. You just need to draw the rectangle or polygon then change its Author parameter to "REGION". Then click the region report and click ok. It will count all the annots within that "region". Remember that it only counts the annots with their centers inside the region or else it will be counted to the other region or no-region at all.
  6. revisionTool, a repurposed counting tool. It's one of the failed approach to make a counting tool. I've noticed it's a good tool for changing/revising multiple annots at once. Just selec all the annot that needs to be replaced. Click the Revision Tool, set your annot then click ok.
You do not have the required permissions to view the files attached to this post.
Last edited by JCatsuki on Sun Apr 05, 2026 1:27 am, edited 1 time in total.
Mathew
User
Posts: 794
Joined: Thu Jun 19, 2014 7:30 pm

Re: Using JavaScript to place the annotation to clipboard first

Post by Mathew »

JCatsuki wrote: Sat Apr 04, 2026 9:29 am Good News!!! You're suggestion works!
...
One last request (it's off topic by now), can you teach me how to use custom icons inside the JS? The AI was able to use one but it messes up the colors.
Oh wow. Spectacular. Thanks for sharing. Can I suggest you don't include GlobData because that's your settings (the file is generated by PXCE), and maybe post the above in PDF XCE Javascript Index so that other people can find it easier? viewtopic.php?t=42190

I tried using AI for debugging and I find myself going round in circles with the AI making suggested revised code that doesn't solve the problem. Your approach seems to be much better: modifying code that's already working.

Custom icons are discussed in many topics on this forum. Here's one that I posted:
viewtopic.php?t=44829
here's the tool I made to encode a png into the script:
viewtopic.php?t=42029
Last edited by Mathew on Sat Apr 04, 2026 4:33 pm, edited 4 times in total.
Mathew
User
Posts: 794
Joined: Thu Jun 19, 2014 7:30 pm

Re: Using JavaScript to place the annotation to clipboard first

Post by Mathew »

...by the way, I was having trouble with the getNewAnn function when rapid clicks were missing markups. The reason I found was that annotation creationDate and modDate is rounded to the nearest second, which caused two problems:
  1. The ANSB_ModDate sorting would not necessarily get the annotations into the correct order. I recommend changing line 125 in countingTool to sort by seqNum instead:

    Code: Select all

    var annots = (doc.getAnnots(doc.pageNum) || []).sort((a,b) => b.seqNum - a.seqNum);
  2. There will still be cases where the creationDate rounds down, and the startTime appears to be later because of a few milliseconds. If you're still getting uncaught markups, maybe something like this on line 112 to round the start time down also -- I've not tried it:

    Code: Select all

    var startTime = new Date(Math.floor( Date.now() / 1000) * 1000);
JCatsuki
User
Posts: 5
Joined: Wed Apr 01, 2026 3:36 pm

Re: Using JavaScript to place the annotation to clipboard first

Post by JCatsuki »

Mathew wrote: Sat Apr 04, 2026 3:30 pm Oh wow. Spectacular. Thanks for sharing. Can I suggest you don't include GlobData because that's your settings (the file is generated by PXCE), and maybe post the above in PDF XCE Javascript Index so that other people can find it easier? viewtopic.php?t=42190
Oh thanks for the concern, i've reuploaded the attachment now.
I will be posting this too in PDF XCE Javascript Index
Mathew wrote: Sat Apr 04, 2026 3:30 pm I tried using AI for debugging and I find myself going round in circles with the AI making suggested revised code that doesn't solve the problem. Your approach seems to be much better: modifying code that's already working.
I'm actually using 3, well 4, AIs for general info with 2 of it for coding (and as well as learning to code). You're right, they're pretty much stubborn. It's also evident with my icons. Told it to fix the color and they always end up somewhat purple, worse is sometimes they even make it smaller. 🤣
I've asked them sometimes about some engr'g formulas that ive already forgotten, and i immediately noticed that they occassionally mix up constants that should belong to the imperial/english units when you want the answers to be in metric, and vice-versa.
That's why I decided to learn coding myself so i know what the f that ai is talking about. My experience using them since 2023 tells me never to trust them immediately.
Mathew wrote: Sat Apr 04, 2026 3:30 pm Custom icons are discussed in many topics on this forum. Here's one that I posted:
viewtopic.php?t=44829
here's the tool I made to encode a png into the script:
viewtopic.php?t=42029
Thanks again for this.
Mathew wrote: Sat Apr 04, 2026 4:03 pm ...by the way, I was having trouble with the getNewAnn function when rapid clicks were missing markups. The reason I found was that annotation creationDate and modDate is rounded to the nearest second, which caused two problems:
  1. The ANSB_ModDate sorting would not necessarily get the annotations into the correct order. I recommend changing line 125 in countingTool to sort by seqNum instead:

    Code: Select all

    var annots = (doc.getAnnots(doc.pageNum) || []).sort((a,b) => b.seqNum - a.seqNum);
  2. There will still be cases where the creationDate rounds down, and the startTime appears to be later because of a few milliseconds. If you're still getting uncaught markups, maybe something like this on line 112 to round the start time down also -- I've not tried it:

    Code: Select all

    var startTime = new Date(Math.floor( Date.now() / 1000) * 1000);
I've noticed this one too, and Im not even clicking super fast or something. I tried "debuging" it using ai and it suggested doing this:
The fast-clicking miss is a known async timing issue. The getNewAnn loop is checking every 100ms, so if you click faster than that, the second note appears before the first one's replacement cycle completes, and it gets missed.
Two fixes needed:
  1. Increase polling rate — check every 30ms instead of 100ms
  2. Process ALL new annotations since startWait, not just the first one — so rapid clicks don't get skipped
Two architectural changes:
  1. (...)
  2. Batch scan loop — instead of one-at-a-time recursion, continuously scan for ALL unprocessed stamps every 30ms. Fast clicks just accumulate and get processed in the next scan cycle
Single continuous loop:
every 30ms → scan ALL new stamps → process any unprocessed ones

vs old approach:
process 1 → loop → process 1 → loop (misses overlapping clicks)Viewed 2 filesViewed 2 filesNow I have the full picture. Let me rewrite the core loop and add the stamp trigger setting:
It worked, as far as Im concerened.
Here's what it did (and also the updated verion of countingTool i mentioned earlier):
countingTool 4.1.rar
But maybe i wasnt clicking fast enough.
So asked it again regarding your suggestion:
Yes, exactly — Mathew is addressing the same rapid-click miss issue! And he found the root cause we only worked around: creationDate is rounded to the nearest second, so our date comparison was unreliable.
His two fixes:
  1. Sort by seqNum instead of ANSB_ModDate — sequence number is exact, not rounded
  2. Round startTime down to the nearest second — so annotations created in the same second as session start aren't missed
Let me find the exact lines in our file:
Find the relevant lines>
Lines 198, 210, and 213. Applying both of Mathew's fixes:
Yes, his code snippets are suggestions — they're not from our file directly. He was pointing at the concept and showing example code for us to adapt.
What we actually changed in our file:
His suggestion #1:

Code: Select all

Mathew's example:
var annots = (doc.getAnnots(doc.pageNum) || []).sort((a,b) => b.seqNum - a.seqNum);

// What we had before:
var annots = doc.getAnnots(doc.pageNum, ANSB_ModDate) || [];
His suggestion #2:

Code: Select all

Mathew's example:
var startTime = new Date(Math.floor( Date.now() / 1000) * 1000);

// What we had before:
var startTime = new Date();
Both are now in our file at lines 201 and 216. You can verify:
Here's the JS with you fix included for your reference:
countingTool 4.2.rar
You do not have the required permissions to view the files attached to this post.
Mathew
User
Posts: 794
Joined: Thu Jun 19, 2014 7:30 pm

Re: Using JavaScript to place the annotation to clipboard first

Post by Mathew »

:D Hah! I’m surprised: AI found the third thing I changed but thought it was too complicated to describe here: multiple clicks within a single loop. I figured you already had it set to 30ms so anyone clicking faster than that is just trying to break things.

Obsequious AI. That’s the challenge: it throws me off how certain and fawning the response is, yet the response is always a guess ( the whole thing is a probability model AFIK). Maybe they’ll figure out how to attach a probability to that guess at some point.

Well I’m not a programmer either and only got into this because I, like you, had specific use cases that I needed to solve. I think most of my scripts lean upon finding creative workarounds. Nice to meet a fellow tinkerer :)