Convert Scanned PDFs to Markdown
Convert scanned PDFs into markdown with anydoc and time each page's OCR.
Introduction
105 Second Summary
A scanned invoice or a photo of a page looks perfectly readable to you, but to a script it is just an image. Search it, copy from it, or point a program at it, and you get nothing back. hkjhkjhadfasdfasdf
In this project, you will use anydoc to turn a folder of scanned documents into clean text files a script can read. You will also time every conversion, so you know what a whole pile of paper costs you in seconds.
What You'll Build
By the end you will drop a pile of scans into one folder, run a single script, and watch OCR turn each image into words while a table prints out how long every document took.
By the end of this project, you'll have:
- A command that takes a scanned page and prints it straight back to you as readable Markdown, running on your own laptop with no key and no upload.
- A folder script you can point at any pile of documents, so it saves one text file per document and tells you which ones it converted.
- A timing table that shows the pages and milliseconds behind every file, plus the same numbers for the hosted option so you can say which one you would actually use.
- Secret Mission: Teach your folder script to skip documents it has already converted, so a second run only spends time on new scans.
Are there any prerequisites?
You need a terminal, plus a few sample documents including at least one scan and one page with a table in it. Everything here runs locally, so there is no account to create and nothing to pay for.
Before We Start
Before we dive in, let's lock in what you're about to build and why it matters.
Convert a Text PDF and Time It
You have anydoc installed and a folder holding three sample documents. None of that has produced a single line of text a script could read yet.
The easiest document to start with is the one that already contains real text. A PDF exported from a word processor stores its characters inside the file, so there is nothing to recognise and nothing to guess.
In this step you convert that PDF to Markdown and time it. That number is the baseline you compare every scanned page against later.
In this step, get ready to:
- Run anydoc against a PDF that already contains real text.
- Read the markdown it prints and check it against the page.
- Time the conversion and record your baseline.
Convert your text PDF to markdown
- Switch back to the terminal you used to install anydoc.
- Move into your sample documents folder by running this command:
cd [[SAMPLES_FOLDER="path to your sample documents folder"]]
- Confirm all three sample files are there by running:
ls
All three samples are listed: the text PDF, the scanned page, and the document with the table.
Before you run the next command, what do you expect anydoc to do with the result: save a new file, or print it straight back at you?
- Convert your text PDF by running this command:
anydoc [[TEXT_PDF="your text PDF file name"]]
The markdown prints straight into your terminal. Nothing has been written to disk.
What just happened to your PDF?
A text PDF already stores its characters. anydoc reads them directly, so it never has to recognise anything from an image.
The whole conversion ran on your machine. No account, no API key, no upload.
🙋♀️ Seeing a NeedsOcr error?
You pointed anydoc at the scanned page instead of the text PDF. NeedsOcr means those pages hold images rather than characters.
Run ls again and check the file name you typed matches the text PDF exactly. File names are case-sensitive.
Why is anydoc returning NeedsOcr for my PDF?
Check the markdown against the page
Markdown that looks plausible in a terminal can still be missing half the page. The only way to know is to read the two side by side.
- Open your sample documents folder in Finder (macOS) or File Explorer (Windows).
- Double-click your text PDF to open it.
- Compare the first heading on the page against the first # line in your terminal output.
- Check that the paragraphs on the page appear in the same order in the markdown.
Every heading and paragraph on the page has a markdown equivalent in your terminal. That is a document a script can finally read.
Time the conversion and record your baseline
Speed decides whether you can run this over a hundred documents or ten. A page that already contains text is the fastest case anydoc will ever handle, so timing it gives you the floor.
Before you run this, is your guess seconds or milliseconds?
- Time the same conversion by running this command:
time anydoc [[TEXT_PDF="your text PDF file name"]] > /dev/null
Your shell prints a real line under the command. That is the wall-clock time for the whole run.
- Record the real time you saw: your text PDF conversion time
Why is it this fast?
anydoc is pure Rust with no ML models and no external services. Median conversion time is under 5ms per document.
Most of the time on your real line is the command starting up, not the conversion itself.
🙋♀️ No timing line in the output?
Not every shell ships a built-in time. If yours printed an error instead of a timing line, you need your shell's own way of timing a command.
How do I time a single command in my shell?
You have a baseline and proof that anydoc reads a normal PDF. Next up, you point it at a page that is nothing but an image and watch OCR go to work.
OCR a Scanned Page
Last step you watched anydoc turn a text PDF into Markdown almost instantly. Every word was already sitting inside that file, waiting to be read.
A scan is a different animal. It is a photograph of a page, so the words are pixels and there is no text layer underneath them.
Pulling words out of an image takes OCR. In this step you find out what anydoc does when you hand it a page it cannot read on its own.
In this step, get ready to:
- Run anydoc against your scanned page and see what comes back.
- Switch on OCR so the scan converts into readable text.
- Check the converted words against the original page.
Run anydoc on your scanned page
Your scanned page and your text PDF look identical when you open them. The difference only shows up when a script tries to read them.
- Switch back to the terminal you used for the text PDF.
- Confirm you are still inside your sample documents folder by running this command:
ls
You should see your three sample files listed, including the scanned page. Note down exactly how its file name is spelled, because you type it next.
Before you run the next command, do you think anydoc will read the words off your scan, or come back with nothing? Make a guess.
- Convert your scanned page by running this command:
anydoc [[SCAN_FILE="your scanned PDF file name"]]
No markdown comes back. Instead anydoc stops with an error naming NeedsOcr.
Why did anydoc stop?
anydoc reads text-based PDFs locally and does no OCR of its own. A page that is pure image has no text layer for it to pull from.
So it refuses to guess. It returns NeedsOcr rather than handing you a half-empty file you would only trust by accident.
This error is exactly what you want to see here. It proves your sample really is a scan and not a text page in disguise.
Got markdown back instead of an error?
Your file has a hidden text layer, which plenty of scanners add automatically. Swap in a photo of a page you took on your phone and saved as a PDF.
If your scan is a .jpg or .png, anydoc only accepts document formats, so export the image to a .pdf first.
Why did anydoc convert my scan without needing OCR?
Turn on hosted OCR
anydoc will not invent text out of pixels, but it will hand the job to something that can. You opt in with a flag.
- Convert the same page with OCR switched on by running this command:
anydoc [[SCAN_FILE="your scanned PDF file name"]] --ocr hosted
What does --ocr hosted do?
It sends the document to Firecrawl Parse, which runs OCR on the pages and returns the same markdown anydoc would produce locally.
No signup is needed to use it. Setting FIRECRAWL_API_KEY raises your limits, and you do not need one for a handful of sample pages.
Only documents that actually need OCR leave your machine, and the whole document goes, since Parse has no page selection. Keep that in mind for anything confidential.
This time markdown prints to your terminal. Those are the words from your scanned page, now as text a script can read.
It also took noticeably longer than the text PDF did. That wait is the round trip plus the OCR itself, and it is the cost you measure properly in a later step.
Nothing came back, or it seems stuck?
The hosted path needs a working network connection, because your document travels out and the markdown comes back. Check you are online and run the command again.
A large or high resolution scan takes longer to send and process. Give a big file a minute before you assume it failed.
My hosted OCR run is not returning anything. What should I check?
Compare the OCR output against the page
OCR reads shapes and picks the letter it thinks fits best. That makes it a guess, and guesses need checking before you build a pipeline on top of them.
Before you look, which parts of your page do you expect it to get wrong? Pick your bet now, then go and find out.
- Open your scanned page by double-clicking it in Finder (macOS) or File Explorer (Windows).
- Pick three lines from the page, including one that contains numbers or a person's name.
- Find those same three lines in the markdown in your terminal.
- Compare them word for word against the page.
The ordinary sentences should match the page exactly. Numbers, names, and anything printed small or faint are where OCR slips first.
Words coming back garbled?
Skewed or low resolution scans give OCR less shape to work with, so letters get swapped and words run together.
Rescan or rephotograph the page straight on, at a higher resolution and with even lighting. Then run the same command again and compare the two outputs.
Why is the text from my scanned page coming out garbled?
Your scan is text now, and you have a feel for what OCR costs you in waiting time. Next up is a document with a table, where you find out whether the rows and columns survive the trip.
Convert a Table Document
Your scan came back as readable words, which means anydoc already handles the hardest input in your folder. There is one more shape of document sitting in there.
A table holds its meaning in its layout. Markdown is one long stream of characters, so the real question is whether the rows and columns arrive intact.
In this step, get ready to:
- Convert your table document into a markdown file on disk.
- Read the markdown anydoc wrote for that table.
- Compare the rows and columns against the original page.
Convert your table document to a markdown file
So far anydoc has printed its markdown straight into your terminal. A table is wider and denser than a page of prose, so this time you'll send the output to a file you can scroll through.
- Return to the terminal window from the last step, where you're already inside your sample documents folder.
- See what's in the folder by running this command:
ls
- Check the output lists all three of your sample files, including the one with the table.
- Record the file name of your table document exactly as it appears: your table document file name
- Convert that document into a markdown file by running this command:
anydoc [[TABLE_DOC="your table document file name"]] -o table.md
What does the -o flag do?
Without -o, anydoc prints its markdown to the terminal, which is what happened with your first two documents.
-o table.md writes that same markdown into a file instead. A table is far easier to inspect in a file you can scroll than in a wall of terminal output.
- Confirm the file landed by running this command:
ls
- Check that table.md now sits alongside your three sample documents.
No table.md in the list?
- Check the file name you typed matches what ls printed, extension included.
- If your table sits on a scanned page rather than a text document, anydoc stops with NeedsOcr. Add --ocr hosted to the command, the same way you did for your scan.
Why won't anydoc convert my table document?
Check the table survived the conversion
Markdown has no grid to put a table in. It draws one with pipe characters and a single separator line, so a wide table can look nothing like the page it came from.
Before you open the file, do you think every row and column made it across, or do you expect something to have gone missing?
- Print the converted markdown by running this command:
cat table.md
Your table comes back as rows of text split by | characters, with a line of dashes sitting under the header row.
How markdown draws a table
Every | marks a column boundary and every new line is a new row. The dashes under the first row tell a markdown reader that the row above is the header.
Nothing forces the columns to line up in the raw text. A long cell pushes its row out wider than the rest, and the table still renders correctly wherever it gets read.
- Open your original table document next to the terminal.
- Count the rows in the source table.
- Count the rows in table.md, ignoring the line of dashes under the header.
- Check the two counts match.
- Check every column from the original appears in the markdown, in the same left to right order.
Columns look ragged in the terminal?
- Raw markdown does not pad cells to an equal width, so one long cell makes its whole row look longer. Count the | separators per row instead of judging by how the text lines up.
- If the table sat on a scanned page, OCR has to guess where one column ends and the next begins. Read the cell values against the source page before you trust them.
My converted table has the wrong number of rows, what happened?
Three documents, three clean conversions, all typed out one command at a time. Next up, you'll hand the whole folder to a script and let it do the typing.
Write a Batch Conversion Script
You have converted three documents by hand now. Each one told you something useful: a text page comes back almost instantly, a scanned page takes longer because OCR has to read it, and a table survives the trip intact.
A real pile of documents is fifty files, not three. Typing anydoc fifty times is not a pipeline.
So you'll write a script that walks the folder for you and saves one Markdown file per document. It also puts a clock around each conversion, so you finish the step knowing what the whole pile costs in time.
In this step, get ready to:
- Write a script that loops over every document in your sample documents folder.
- Save one markdown file per document into a markdown output folder.
- Print a summary table of file name, page count, and conversion time.
Create your script file
The script will be a Python file, so the first thing to settle is whether your machine can run one.
- Check what you have by running this command:
python3 --version
✔️ I see a version number
Python is ready to go. Carry on to creating the script file below.
ⓧ Command not found
Python isn't on this machine yet, so install it before you write anything.
- Open the Python downloads page in your browser.
- Click the yellow Download Python button near the top of the page.
- Open the installer your browser downloaded.
- Follow the installer prompts, accepting the defaults.
- Close your terminal window, then open it again so it picks up the new install.
- Confirm the install worked by running this command:
python3 --version
You should now see a version number instead of an error.
- Move to your Desktop by running this command:
cd ~/Desktop
- Create the script file and the folder its output will land in by running these commands:
touch convert_folder.py
mkdir markdown
- Confirm they both exist by running:
ls
- You should see convert_folder.py and markdown in the output.
- Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
- Type VS Code and press Enter to open it.
- In VS Code, click File in the top menu bar.
- Click Open File.
- Select convert_folder.py on your Desktop, then click Open.
- Teach the script where to look and where to write by pasting in this code:
from pathlib import Path
DOCS_FOLDER = Path('[[DOCS_FOLDER="path to your sample documents folder"]]')
OUTPUT_FOLDER = Path("markdown")
for document in sorted(DOCS_FOLDER.iterdir()):
# Skip hidden files the operating system leaves behind
if document.name.startswith("."):
continue
print(document.name)
What does this code do?
- DOCS_FOLDER is the folder of scans you built earlier, and OUTPUT_FOLDER is the empty markdown folder you just made.
- sorted() hands the files back in the same order every run, so two runs are comparable.
- The startswith check drops invisible files like .DS_Store, which would otherwise show up as a document.
- Save convert_folder.py.
- Back in your terminal, run the script:
python3 convert_folder.py
- You should see the names of your three sample documents printed, one per line.
Nothing printed, or an error about the folder?
- An empty output usually means DOCS_FOLDER points somewhere real but empty. Check you pasted the path to the folder that holds the scans, not its parent.
- An error naming the directory means the path is wrong. Drag the folder into your terminal window to make it print the exact path, then paste that in.
Why is my Python script not finding my documents folder?
Convert each document and save its markdown
Right now the script only reads out file names. To make it useful, each loop needs to hand its file to anydoc and keep what comes back.
- In convert_folder.py, add this line at the very top, directly above from pathlib import Path:
import subprocess
- Scroll to the bottom of the file and find this line:
print(document.name)
- Replace it with the conversion itself, so anydoc writes a markdown file for every document:
# Send each document's markdown to markdown/<same name>.md
target = OUTPUT_FOLDER / (document.stem + ".md")
result = subprocess.run(["anydoc", str(document), "-o", str(target)], capture_output=True)
# A non-zero return code means anydoc could not convert this file
print(document.name, "ok" if result.returncode == 0 else "failed")
What's happening here?
- document.stem is the file name without its extension, so invoice.pdf becomes invoice.md.
- subprocess.run calls the same anydoc command you ran by hand, with -o sending the output to a file instead of your screen.
- Checking returncode keeps one awkward file from killing the whole run. The loop records it and moves on.
- Save convert_folder.py.
- Run the script again:
python3 convert_folder.py
- Each file name now prints with ok or failed beside it.
- Confirm the markdown actually landed on disk by running:
ls markdown
- You should see one .md file for every document that reported ok.
Seeing failed, or an empty markdown folder?
- A file reporting failed is usually the scanned page. anydoc reads text-based pages on its own and sends scanned ones to hosted OCR, which is exactly what you compare in the next step.
- If every file failed, the anydoc command isn't visible to the script. Run it once on its own in this same terminal to confirm it still works.
- An empty folder with no failures usually means you ran the script from somewhere other than your Desktop, so markdown resolved to a different place.
Why is my subprocess call to anydoc failing?
Time each conversion and print the summary table
Knowing a folder converted is only half the answer. The number that decides whether you point this at a thousand documents is how long each page took.
Time on its own is misleading though, because a twenty page scan and a one page receipt are not comparable. The table needs a page count next to every time.
- Give Python a way to count PDF pages by installing pypdf with this command:
pip3 install pypdf
- The last line of the output should confirm that pypdf was installed successfully.
Did pip refuse to install?
- Some systems protect their built-in Python and block installs into it. Installing just for your own user account usually gets around this:
pip3 install --user pypdf
Why won't pip install this package on my machine?
- Switch back to convert_folder.py and find these two lines at the top:
import subprocess
from pathlib import Path
- Replace them with this, which brings in the clock and the page reader:
import subprocess
import time
from pathlib import Path
from pypdf import PdfReader
- Find this line further down the file:
OUTPUT_FOLDER = Path("markdown")
- Select that line and everything below it, then replace the lot with this:
OUTPUT_FOLDER = Path("markdown")
rows = []
for document in sorted(DOCS_FOLDER.iterdir()):
# Skip hidden files the operating system leaves behind
if document.name.startswith("."):
continue
target = OUTPUT_FOLDER / (document.stem + ".md")
# Start the clock immediately before the conversion
started = time.perf_counter()
result = subprocess.run(["anydoc", str(document), "-o", str(target)], capture_output=True)
elapsed_ms = (time.perf_counter() - started) * 1000
# PdfReader only understands PDFs, so anything else counts as one page
pages = len(PdfReader(document).pages) if document.suffix == ".pdf" else 1
taken = f"{elapsed_ms:.0f} ms" if result.returncode == 0 else "failed"
rows.append((document.name, pages, taken))
# One line per document, so the whole pile fits on one screen
print(f"{'file':<30}{'pages':>7}{'time':>12}")
for name, pages, taken in rows:
print(f"{name:<30}{pages:>7}{taken:>12}")
What does this code do?
- time.perf_counter() is the most precise clock Python offers. Reading it either side of the conversion gives you the cost of that one document.
- Multiplying by 1000 turns seconds into milliseconds, which is the unit anydoc's own numbers are quoted in.
- rows collects one tuple per document, so the table can be printed once at the end rather than dribbling out mid-loop.
- The :<30 and :>7 parts pad each value to a fixed width, which is what keeps the columns lined up.
- Save convert_folder.py.
Before you run it, which of your three documents do you think will come back slowest, and by how much?
- Find out by running the script:
python3 convert_folder.py
You should see a three column table with one line per document, showing the file name, its page count, and the time it took.
Table looks wrong or the script errored?
- An error naming pypdf means the install went to a different Python than the one running your script. Reopen your terminal and install it again.
- Columns that drift out of line mean a file name is longer than 30 characters. Raise the :<30 padding until it fits.
- A page count of 1 on a document you know is longer means that file is not a PDF, so the script counted it as a single page.
Why is my summary table not printing correctly?
✔️ Awesome, I've got everything!
Great, double check you've saved your file and move on.
ⓧ I'd like to double check the full code
Here's the whole script as it should look now.
import subprocess
import time
from pathlib import Path
from pypdf import PdfReader
DOCS_FOLDER = Path('[[DOCS_FOLDER="path to your sample documents folder"]]')
OUTPUT_FOLDER = Path("markdown")
rows = []
for document in sorted(DOCS_FOLDER.iterdir()):
# Skip hidden files the operating system leaves behind
if document.name.startswith("."):
continue
target = OUTPUT_FOLDER / (document.stem + ".md")
# Start the clock immediately before the conversion
started = time.perf_counter()
result = subprocess.run(["anydoc", str(document), "-o", str(target)], capture_output=True)
elapsed_ms = (time.perf_counter() - started) * 1000
# PdfReader only understands PDFs, so anything else counts as one page
pages = len(PdfReader(document).pages) if document.suffix == ".pdf" else 1
taken = f"{elapsed_ms:.0f} ms" if result.returncode == 0 else "failed"
rows.append((document.name, pages, taken))
# One line per document, so the whole pile fits on one screen
print(f"{'file':<30}{'pages':>7}{'time':>12}")
for name, pages, taken in rows:
print(f"{name:<30}{pages:>7}{taken:>12}")
You now have local numbers for the whole folder. Next up, you'll run the same documents through the hosted option and put the two timing tables side by side.
Compare Local and Hosted Conversion Times
Your batch script now walks the whole sample documents folder and prints a local timing table. That table only tells you half the story.
anydoc also has a hosted option that sends a document to Firecrawl Parse instead of doing the work on your laptop. You cannot choose between them until you have run the same folder both ways.
In this step, get ready to:
- Send one scanned page through the hosted option.
- Time your whole sample documents folder through the hosted path.
- Put the local and hosted tables side by side and pick one.
Send one scanned page through the hosted path
Everything you have converted so far stayed on your laptop. The --ocr hosted flag hands a document to Firecrawl Parse instead, so this is the first time a file leaves your machine.
- Move to your sample documents folder by running this command:
cd [[SAMPLE_FOLDER="path to your sample documents folder"]]
Before you run the next command, do you think the hosted conversion comes back faster or slower than the local one? Hold that guess.
- Send your scanned page to the hosted path by running this command:
time anydoc [[SCAN_FILE="your scanned file name"]] --ocr hosted
What does --ocr hosted do?
It sends the document to Firecrawl Parse, which OCRs it and returns the same Markdown. No signup is needed, and you can set FIRECRAWL_API_KEY for higher limits.
Only documents that need OCR leave the machine. The whole document goes, since Parse has no page selection.
- Read the markdown that prints in your terminal and check the words still match the page.
- Read the timing line printed underneath the markdown, which is how long the whole round trip took.
Hosted conversion didn't come back?
This is the one command in the project that needs the internet, so check your connection before anything else.
If the conversion is refused rather than slow, you may be over the keyless limit. Set FIRECRAWL_API_KEY to raise it.
Why did my hosted anydoc conversion fail?
Time the whole folder through the hosted path
One document is an anecdote. To compare fairly, every file in the folder has to go through the hosted path the same way, one after the other.
- Time all three sample documents through the hosted path by running these commands:
for f in [[TEXT_PDF="your text PDF file name"]] [[SCAN_FILE="your scanned file name"]] [[TABLE_DOC="your table document file name"]]; do
echo "== $f"
time anydoc "$f" --ocr hosted > /dev/null
done
What does this loop do?
The loop walks your three sample documents in turn. echo prints the file name first, so every timing underneath has a label.
The > /dev/null part throws the markdown away, because you already have those files from your batch script. The timings are the only thing you want on screen here.
- Record the hosted time for your text PDF: your hosted text PDF time in ms.
- Record the hosted time for your scanned page: your hosted scan time in ms.
- Record the hosted time for your table document: your hosted table time in ms.
Loop stopped partway through?
The most common cause is a file name that does not match what is actually in the folder. Run ls and copy the names straight out of the listing.
A file in an unsupported format also stops that run, so check each name has a document extension anydoc handles.
Why is my anydoc loop failing on one of my files?
Put the two tables side by side
Your local numbers came from an earlier run, and a laptop's state drifts between runs. Print the local table once more so both halves of the comparison describe the same machine right now.
- Move to the folder holding your batch script by running this command:
cd [[SCRIPT_FOLDER="path to the folder holding convert_folder.py"]]
Before you run the script, which of your three documents do you expect to show the biggest gap between its local and hosted time?
- Print your local timing table again by running this command:
python3 convert_folder.py
- Read the summary table and confirm you get one line per document, each with a file name, a page count, and a time in milliseconds.
- Line up each local time against the hosted time you recorded for the same file.
How to read the gap
anydoc's median conversion time is under 5ms per document when it runs on your machine. The hosted path cannot beat that, because every document has to cross the network and come back.
The hosted time buys you Parse's OCR models. It earns those milliseconds on scans and photographs, not on pages that already contain real text.
There is a third column your timings do not show: privacy. The local path never sends a document anywhere, which decides it for anything you would not want uploaded.
Secret mission
Flag the Scans That Came Back Garbled
Your timing table proves every document was processed. It says nothing about whether the words that came back are real. Add a second script that measures how much text each markdown file actually holds, then flags the thin ones before you feed them to anything downstream.
Clean Up Your Resources
Clean Up Your Resources
Decide whether to keep your resources running, pause them to come back later, or delete them entirely. This project runs entirely on your own machine, so nothing here is costing you money while it sits there.
Resources you used:
- Your sample documents folder, holding the text PDF, the scanned page, and the table document.
- Your markdown output folder, holding one markdown file per converted document.
- Your batch conversion script, convert_folder.py.
What about the models anydoc downloaded?
The first OCR run pulled model files onto your machine so anydoc could read images without an API key. Those files stay on disk after this project.
They cost you disk space, not money. Leaving them in place is what makes your next scan convert instantly instead of stalling on a download.
Keep everything running
No action needed. Choose this if you're still actively building on the timing script or have more documents to convert.
- Leave your sample documents folder, your markdown output folder, and convert_folder.py exactly where they are.
- Drop the next pile of scans into your sample documents folder and rerun the script whenever you need it.
What stays on your machine
The anydoc CLI and its downloaded OCR models stay installed until you remove them yourself.
Nothing runs in the background and nothing phones home. Both sit idle until you call anydoc again.
Pause - I'll come back to this later
Shut down anything still running and park your files so you can pick this up in a week without hunting for them.
- Press Ctrl+C in your terminal to stop any conversion still in progress.
- Keep convert_folder.py and your markdown output folder, since those are the parts you reuse on the next batch.
- Confirm your markdown files are still there by running:
ls
You should see one markdown file listed for each document you converted.
Leave yourself a note
Add a line at the top of convert_folder.py recording which option you picked, local or hosted, and the timings that decided it.
Future you will not remember why one won.
Delete - I don't want to use this again
Remove all project resources and start fresh. Choose this if your sample scans contain anything you would not want sitting on disk.
- Move to your Desktop by running this command:
cd ~/Desktop
- Check what you are about to remove by listing the folder contents:
ls [[PROJECT_FOLDER="your anydoc project folder"]]
You should see your sample documents folder, your markdown output folder, and convert_folder.py listed.
- Delete the whole project folder, including the sample scans, the markdown output, and the script, by running this command:
rm -rf [[PROJECT_FOLDER="your anydoc project folder"]]
- On Windows, delete the same folder by running this command instead:
rmdir /s /q [[PROJECT_FOLDER="your anydoc project folder"]]
- Confirm the folder is gone by running:
ls
Your project folder no longer appears in the Desktop listing.
Seeing a permission error?
A conversion still running holds the folder open, so press Ctrl+C in the terminal running it, then try the delete again.
Check the folder name you typed matches what ls printed, since a typo deletes nothing and reports nothing found.
Still stuck? Why can't I delete my project folder?
Nice Work!
Nice Work
You just turned a pile of scans into text a script can actually read. Every document in your sample folder now has a matching markdown file, and you know exactly what each page cost you in milliseconds.
You've learned how to:
- Convert a scanned or photographed page into readable markdown with OCR, then check the words against the original page.
- Preserve tables through conversion by counting rows and columns in the markdown against the source document.
- Batch a whole folder with convert_folder.py, writing one markdown file per input and printing a timing table of pages and milliseconds.
- Take on the Secret Mission and push your document pipeline past the basics.
Ready to quiz yourself?