3

THE ISSUE

This may just stem from a lack of deep understanding of Windows batch file coding.

I am trying to write a simple one-line batch file that will process every file in a directory using pandoc to convert all doc or docx (MS Word) files to markdown (.md) files. When I run my batch file I get the following error:

pandoc: C:_ALL\_ALL\accomp\testing-accomp-2017.05\20170505.md: openBinaryFile: does not exist (No such file or directory)

I get one of these errors for each file in the directory (around 25, or so).

The directory I'm running my command in looks like this:

C:\_ALL\!accomp\testing-accomp-2017.05

As you can see, for some reason the _ALL is appearing twice. The path it is showing me isn't right for some reason and I'm not sure if it is a pandoc issue or a CMD batch file programming issue.

MY CODE

Here is the code for my batch file:

@echo OFF

:: [Not sure what this does, but have read that it is necessary]
setlocal enabledelayedexpansion

:: MAIN
FOR /r "." %%i IN (*.doc *.docx) DO pandoc -f rst -t markdown "%%~fi" -o "%%~dpni.md"

:: End with a pause so user can copy any text from screen.
ECHO. Done. Press any key to terminate program
PAUSE>NUL

Now, I'm not certain what all these lines of code do, and they may be entirely unnecessary for all I know. However, the main and most important code here is the one that starts with For ..., which is inspired by this Stack Overflow post:

WHAT I'VE TRIED ALREADY

Basically there are about four variations of the same answer in the above linked post and I've tried each of those variations.

Mofi
  • 46,139
  • 17
  • 80
  • 143
  • [The Windows command prompt is *NOT* a DOS prompt!](https://scalibq.wordpress.com/2012/05/23/the-windows-command-prompt-is-not-a-dos-prompt/) – aschipfl May 28 '18 at 15:47
  • @aschipfl Thanks for the link and I already know that which is why, you will notice, I didn't refer in my text to CMD as DOS. I have tagged the question as "DOS" because those who know about DOS are very likely to understand CMD as well, and thus I don't wish to exclude people that could offer useful answers based on semantics. – Eric Hepperle - CodeSlayer2010 May 28 '18 at 15:51
  • I see your point, but I don't agree, because the DOS command prompt has got *very* limited capabilities compared to CMD (although I have to admit they have got the same root). Tagging a CMD question as DOS appears therefore a bit inadequate to me (it's like asking a C++ question and tagging it as C also)... – aschipfl May 28 '18 at 16:29
  • @aschipfl I see your point and that makes sense with C++ vs C analogy. Assuming the code I'm trying to implement is for CMD can you tell me what is wrong with it? I think it has something to do with variable expansion, but everytime I try to understand that I just get confused. – Eric Hepperle - CodeSlayer2010 May 28 '18 at 16:58

1 Answers1

2

The error is caused by delayed expansion and the exclamation mark ! in directory name !accomp.

The command line to execute by FOR expands during execution with file 20170505.doc to:

pandoc -f rst -t markdown "C:\_ALL\!accomp\testing-accomp-2017.05\20170505.doc" -o "C:\_ALL\!accomp\testing-accomp-2017.05\20170505.md"

This command line is parsed by Windows command processor a second time before execution because of enabled delayed environment variable expansion, searching for !variable! reference and replacing them with value of referenced variables.

The string !accomp\testing-accomp-2017.05\20170505.doc" -o "C:\_ALL\! is completely misinterpreted here because of the exclamation marks. So finally executed is:

pandoc -f rst -t markdown "C:\_ALL\\_ALL\accomp\testing-accomp-2017.05\20170505.md"

And the file C:\_ALL\\_ALL\accomp\testing-accomp-2017.05\20170505.md does not exist.

The solution is removing setlocal enabledelayedexpansion as not needed here because of no environment variable used on FOR command line.

@ECHO OFF

FOR /r "." %%i IN (*.doc *.docx) DO pandoc.exe -f rst -t markdown "%%i" -o "%%~dpni.md"

:: End with a pause so user can copy any text from screen.
ECHO Done. Press any key to terminate program ...
PAUSE>NUL

The loop variable i holds here already the full qualified file name. Therefore "%%~fi" can be replaced by "%%i".

And it is better to use ECHO/ instead of ECHO. although neither . nor / is needed here. See DosTips forum topic ECHO. FAILS to give text or blank line - Instead use ECHO/ for the reason.

Mofi
  • 46,139
  • 17
  • 80
  • 143
  • Thanks Mofi! Delayed expansion was indeed the issue. I removed the `setlocal` line and ended up using this command `FOR /r "." %%i IN (*.doc *.docx) DO pandoc "%%~fi" -o "%%~dpni.md"` which worked perfectly. Marked answer as correct. – Eric Hepperle - CodeSlayer2010 May 29 '18 at 10:44
  • Thanks again for your help! I've posted the resulting file on my GitHub repository here: https://github.com/codewizard13/batch-convert-pandoc/blob/master/batch-convert-pandoc.bat – Eric Hepperle - CodeSlayer2010 May 29 '18 at 11:55