Repository: asciidoctor/asciidoctor (Ruby)

Issue:
Wrong `document.options[:to_dir]` when setting `--out-file` (:to_file) and `--destination-dir` (:to_dir) to absolute paths
I am still figuring out the problem, but I could reduce it down to these combinations.
* Windows 10
* asciidoctor + asciidoctor-diagram
* Setting and absolute `--out-file` and any `--destination-dir`

It seems to me the issue is not related to asciidoctor-diagram, but it is through it that I could reproduce it.
Under those conditions the diagram image generation fails with the message 

```
asciidoctor: ERROR: index.adoc: line 3: Failed to generate image: Invalid argument @ dir_s_mkdir - C:/Users/user/asciidoctor/issue_diagrams/dest_dir/C:
```
If I add a "puts" to print the return of the `document.options[key]` in `doc_option` method https://github.com/asciidoctor/asciidoctor-diagram/blob/fd8ab7d9eb9d5de3c55a0e27c4276206c728a917/lib/asciidoctor-diagram/diagram_processor.rb#L317 I get these

```
C:/Users/user/asciidoctor/issue_diagrams/dest_dir/C:/Users/user/asciidoctor/issue_diagram/custom1
```

_env_
asciidoctor 2.0.10
asciidoctor-diagram 2.0.5
ruby 2.7.1p83

**To reproduce**
Create project with these 2 files

index.adoc
```adoc
= Demo Document

plantuml::demo.puml[]

```
demo.puml
````
@startuml

A->B

@enduml
````

And run with
```
asciidoctor -r asciidoctor-diagram -o "C:\$PATH_TO FILE\custom\custom.html" -D dest_dir index.ado
```


The whole history can be seen here 👉  https://github.com/asciidoctor/asciidoctor-diagram/issues/298.



Discussion:
This is a known issue / restriction. The output file, output dir, and base_dir values must be written as a posix path on Windows (meaning it must use forward slashes). Otherwise, Asciidoctor will not recognize it as an absolute path.

I will look into whether we can loosen this restriction.
I think you are also asking it to do something which is invalid. You're setting the the destination dir to a location which is not the parent of the out file. The destination dir must be the directory of the out file (and thus not necessary to set explicitly if you set the out file). (These directories can be different in unsafe mode, but the behavior is undefined).
For the record, the same issue occurs on Linux. If :to_dir (the destination directory) and :to_file (out file) do not agree, the :to_dir option on the document is the directory of :to_file plus the destination directory as entered. In other words, the input is invalid, so the result is invalid. This is an incorrect use of the API / CLI.
Sorry, I was simplifying the case, bad idea on my side.

Full case comes from the maven-plugin where all paths are made absolute, there we have:
* to_dir -> C:/Users/user/asciidoctor/issue_diagrams/dest_dir/
* to_file -> C:/Users/user/asciidoctor/issue_diagrams/dest_dir/my-file.html
Also we run in usafe.

That should work I understand?
I'm investigating.
This does seem like a bug, though it has nothing to do with Windows. If both :to_file and :to_dir are set, the value of :to_dir is wrong.
PR sent.
Awesome! I will generate a local Asciidoctorj with the fix branch versionto run a full test later.
It worked in the full maven-plugin build 🥳 
Thanks for testing!!



Patch:
diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc
index 0a56046a4b..d1019d73d1 100644
--- a/CHANGELOG.adoc
+++ b/CHANGELOG.adoc
@@ -42,6 +42,7 @@ Bug Fixes::
   * Compute highlight line ranges on source block relative to value of start attribute (#3519) (*@mogztter*)
   * Prevent collapsible block from incrementing example number by assigning an empty caption (#3639)
   * Use custom init function for highlight.js to select the correct `code` elements (#3761)
+  * Fix resolved value of :to_dir when both :to_file and :to_dir options are set to absolute paths (#3778)
 
 Compliance::
 
diff --git a/lib/asciidoctor/convert.rb b/lib/asciidoctor/convert.rb
index 39feee6b74..e8d0078392 100644
--- a/lib/asciidoctor/convert.rb
+++ b/lib/asciidoctor/convert.rb
@@ -63,7 +63,7 @@ def convert input, options = {}
       elsif write_to_target
         if to_dir
           if to_file
-            options[:to_dir] = ::File.dirname ::File.expand_path ::File.join to_dir, to_file
+            options[:to_dir] = ::File.dirname ::File.expand_path to_file, to_dir
           else
             options[:to_dir] = ::File.expand_path to_dir
           end


Test patch:
diff --git a/test/api_test.rb b/test/api_test.rb
index f4b8fc26aa..277fb0fc08 100644
--- a/test/api_test.rb
+++ b/test/api_test.rb
@@ -1320,6 +1320,22 @@ def for name
       end
     end
 
+    test 'should resolve :to_dir option correctly when both :to_dir and :to_file options are set to an absolute path' do
+      begin
+        sample_input_path = fixture_path 'sample.adoc' 
+        sample_output_file = Tempfile.new %w(out- .html)
+        sample_output_path = sample_output_file.path
+        sample_output_dir = File.dirname sample_output_path
+        sample_output_file.close
+        doc = Asciidoctor.convert_file sample_input_path, to_file: sample_output_path, to_dir: sample_output_dir, safe: :unsafe
+        assert File.exist? sample_output_path
+        assert_equal sample_output_path, doc.options[:to_file]
+        assert_equal sample_output_dir, doc.options[:to_dir]
+      ensure
+        sample_output_file.close!
+      end
+    end
+
     test 'in_place option is ignored when to_file is specified' do
       sample_input_path = fixture_path('sample.adoc')
       sample_output_path = fixture_path('result.html')