Gun & Ammo Title Parser
Turn gun and ammo product titles into structured data without leaving the editor: brand, model, generation,
caliber, magazine capacity, barrel length, rounds per box and cost per round. Made for people who build product
feeds, imports and catalogs for gun and ammo stores, and who spend their days in CSV exports, JSON feeds and SQL dumps
full of titles like G19 GEN5 9MM 15RD FS.
Select some lines and run GunsNPrices: Parse Selected Titles from the Command Palette:
Glock 19 Gen 5 MOS 9mm 4.02" 15rd Pistol PA195S203MOS
Federal American Eagle 9mm Luger 115gr FMJ 50 Rounds $18.99
Ruger 10/22 Carbine .22 LR 18.5" 10rd
Winchester 9mm 115gr FMJ 1000 Round Case - $289.99
A new editor opens with the result:
| Line |
Title |
Kind |
Brand |
Model |
Gen |
Caliber |
Capacity |
Barrel, in |
Rounds |
Price |
Per round |
| 1 |
Glock 19 Gen 5 MOS 9mm 4.02" 15rd Pistol PA195S203MOS |
firearm |
Glock |
Glock 19 Gen 5 MOS |
5 |
9×19mm Parabellum |
15 |
4.02 |
|
|
|
| 2 |
Federal American Eagle 9mm Luger 115gr FMJ 50 Rounds |
ammo |
|
|
|
9×19mm Parabellum |
|
|
50 |
$18.99 |
$0.38 |
| 3 |
Ruger 10/22 Carbine .22 LR 18.5" 10rd |
firearm |
Ruger |
Ruger 10/22 Carbine |
|
.22 LR |
10 |
18.5 |
|
|
|
| 4 |
Winchester 9mm 115gr FMJ 1000 Round Case |
ammo |
|
|
|
9×19mm Parabellum |
|
|
1000 |
$289.99 |
$0.29 |
Everything runs on your machine. The extension makes no network requests, collects no telemetry and needs no account
or API key. The parsing is done by gunsnprices, the open source title
parser behind the price comparison site GunsNPrices, so you get the same model and
caliber names the site uses to group listings from 40+ US stores.
Commands
| Command |
What it does |
| GunsNPrices: Parse Selected Titles |
Parses each selected line (or the current line) and opens a Markdown table |
| GunsNPrices: Parse Selected Titles as JSON |
Same, as a JSON array |
| GunsNPrices: Parse Selected Titles as CSV |
Same, as CSV you can paste into a spreadsheet or an import |
| GunsNPrices: Normalize Caliber |
Replaces the selected caliber text with its standard name |
| GunsNPrices: Cost per Round |
Asks for a price and a round count (or a title) and shows the cost per round |
Parse Selected Titles
Each selected line is read according to what it looks like:
| Input |
How the title and price are found |
| Plain list of titles |
The line is the title. A price written as $18.99, $1,299.99 or 18.99 USD is taken out of the title and used for cost per round. |
| CSV / TSV with a header row |
The column named title, name, product_name, item_name, description ... is the title; sale_price, price, our_price ... is the price. The header row itself is skipped. Works for .csv and .tsv files with or without a CSV extension installed, and for untitled files that start with such a header. |
| CSV / TSV without a header |
The text cell that parses best is the title; the first cell that holds only a price (24.99, $24.99) is the price. |
| JSON |
JSON Lines ({"title": "...", "price": 18.99}), arrays on one line, and pretty-printed files: lines like "title": "..." or "name": "..." are read, other properties are skipped. |
| SQL |
INSERT ... VALUES (...), (...) with any number of rows on one line, using the column list when there is one; UPDATE ... SET title = '...'. |
| Markdown tables |
\| ... \| rows; header and separator rows are skipped. |
The JSON output has the fields of the parser's ProductInfo plus the source line and the price that was found:
{
"line": 2,
"title": "Federal American Eagle 9mm Luger 115gr FMJ 50 Rounds",
"kind": "ammo",
"brand": "",
"model": null,
"caliber": { "id": "9x19mmparabellum", "name": "9×19mm Parabellum", "type": "handgun" },
"calibers": [{ "id": "9x19mmparabellum", "name": "9×19mm Parabellum", "type": "handgun" }],
"capacity": null,
"barrelLength": null,
"rounds": 50,
"price": 18.99,
"costPerRound": 0.3798
}
The CSV output has these columns (several values in one cell are separated by ; ):
line,title,kind,brand,model,family,generation,configs,features,caliber,caliber_type,calibers,capacity,barrel_in,rounds,price,cost_per_round
1,"Glock 19 Gen 5 MOS 9mm 4.02"" 15rd Pistol PA195S203MOS",firearm,Glock,Glock 19 Gen 5 MOS,Glock 19,5,MOS,,9×19mm Parabellum,handgun,9×19mm Parabellum,15,4.02,,,
2,Federal American Eagle 9mm Luger 115gr FMJ 50 Rounds,ammo,,,,,,,9×19mm Parabellum,handgun,9×19mm Parabellum,,,50,18.99,0.3798
To parse a whole file, select all (Ctrl+A / Cmd+A) first. Selections over 2,000 lines show a progress
notification and can be cancelled.
Normalize Caliber
Select a caliber, or a column of them (one per line, or with several cursors), and run GunsNPrices: Normalize
Caliber:
| Selected |
Becomes |
9mm Luger, 9x19 |
9×19mm Parabellum |
5.56 NATO |
5.56×45mm NATO |
.223 Remington |
.223 Rem |
12ga |
12 Gauge |
300 BLK |
.300 AAC Blackout |
45 auto |
.45 ACP |
6.5 CM |
6.5mm Creedmoor |
38 Spl |
.38 S&W Special |
The names come from a list of 293 calibers. Quotes and spaces around the value are kept. Text that isn't recognized is
left as it is, and so is text that is more than a caliber (a whole title, or 9mm / .380), so selecting too much
never loses data; a message lists what was left. Turn on gunsnprices.asciiCaliberNames to get 9x19mm Parabellum
instead of 9×19mm Parabellum.
Cost per Round
Asks for the price of the box or case, then for the number of rounds or a title that contains it (50 Rounds,
1000rd case, 20/box). When the cursor is on a line with a title and a price, both are filled in for you. The result
can be copied:
$289.99 for 1000 rounds = $0.29 (29.00¢) per round
Hover
Hover a line, a CSV cell or a JSON string that looks like a gun or ammo title to see what the parser reads from it:
Glock 19 Gen 5 MOS · firearm
- Brand: Glock
- Family: Glock 19
- Generation: 5
- Configuration: MOS
- Caliber: 9×19mm Parabellum (handgun)
- Capacity: 15 rounds
- Barrel: 4.02 in
Ammo with a price in the same line or row also shows the cost per round, and a cell or string that is just a caliber
("caliber": "9mm Luger") shows its standard name. Lines that merely contain a number that could be a caliber
(call me at 308 tomorrow) are ignored.
The hover is on in CSV, TSV, plain text, JSON, JSON Lines and Markdown files, and off in every other language. Change
that with gunsnprices.hover.languages, or turn it off with gunsnprices.hover.enabled.
Settings
| Setting |
Default |
|
gunsnprices.hover.enabled |
true |
Show the hover |
gunsnprices.hover.languages |
["csv", "tsv", "plaintext", "json", "jsonl", "markdown"] |
Language ids where the hover is shown |
gunsnprices.links |
false |
Link caliber names to their price comparison pages on GunsNPrices in hovers, and add the URL to results (url in JSON, caliber_url in CSV, links in Markdown) |
gunsnprices.asciiCaliberNames |
false |
Write × as x in caliber names |
gunsnprices.openResultsBeside |
true |
Open parse results beside the current editor |
What it recognizes
| Field |
Example in a title |
Result |
| Firearm or ammo |
... 150gr ... 20rds |
ammo |
| Brand and model (50 brands) |
G19 Gen5 MOS, Glock part number PA195S203 |
Glock 19 Gen 5 MOS |
| Calibers (293) |
.357 Mag / .38 Spl, 6.5 CM, 12ga, 300 BLK |
.357 Mag, .38 S&W Special, ... |
| Magazine capacity |
15+1, 17RD, 10-shot |
15, 17, 10 |
| Barrel length, inches |
4.02in, 16 1/2", 22 BBL |
4.02, 16.5, 22 |
| Rounds per box |
50/Box, Box of 20, 1,000 Rounds |
50, 20, 1000 |
Brands with model dictionaries include Glock, Sig Sauer, Smith & Wesson, Ruger, Springfield, Taurus, Mossberg,
Remington, Beretta, Benelli, Browning, Winchester, CZ, FN, HK, Henry, Marlin, Savage, Tikka, Walther and 30 more; the
full list is in the gunsnprices README. The same parser is
available for Node.js and browsers and
Python, with identical results, if you want to run it in your feed pipeline.
Privacy
The extension reads only the text you select or hover, in memory. It sends nothing anywhere: there is no telemetry and
no network code. With gunsnprices.links turned on, caliber names become ordinary links that open in your browser
when you click them.
Requirements
VS Code 1.85 or newer. The extension only reads text that is open in the editor, so it also runs in untrusted,
remote and virtual workspaces.
License
MIT. The model and caliber data come from the gunsnprices package (CC BY 4.0, attribution: GunsNPrices).