diff --git a/BrowseRouter/BrowserService.cs b/BrowseRouter/BrowserService.cs
index 237322f..63a1be8 100644
--- a/BrowseRouter/BrowserService.cs
+++ b/BrowseRouter/BrowserService.cs
@@ -1,4 +1,5 @@
using System.Diagnostics;
+using System.Text;
namespace BrowseRouter;
@@ -35,13 +36,15 @@ public async Task LaunchAsync(string url, string windowTitle)
(string path, string args) = Executable.GetPathAndArgs(pref.Browser.Location);
- Log.Write($"Launching {path} with args \"{args} {uri.OriginalString}\"");
+ args = Executable.FormatArguments(args, uri);
+
+ Log.Write($"Launching {path} with args \"{args}\"");
string name = GetAppName(path);
path = Environment.ExpandEnvironmentVariables(path);
- if (!Actions.TryRun(() => Process.Start(path, $"{args} \"{uri.OriginalString}\"")))
+ if (!Actions.TryRun(() => Process.Start(path, args)))
{
await notifier.NotifyAsync($"Error", $"Could not open {name}. Please check the log for more details.");
return;
diff --git a/BrowseRouter/Executable.cs b/BrowseRouter/Executable.cs
index ae433cf..c375eef 100644
--- a/BrowseRouter/Executable.cs
+++ b/BrowseRouter/Executable.cs
@@ -1,4 +1,6 @@
-namespace BrowseRouter;
+using System.Text;
+
+namespace BrowseRouter;
public static class Executable
{
@@ -23,4 +25,83 @@ public static (string, string) GetPathAndArgs(string s)
// The single executable without any other arguments.
return (s, "");
}
+
+ ///
+ /// Complete the arguments to call the browser with, with the uri requested and according to the recognized tags in them.
+ /// If no tags is recognized the uri is simply added to the end of the arguments.
+ ///
+ /// The unformatted arguments
+ /// The URI to format the arguments with
+ /// The formatted arguments
+ public static string FormatArguments(string originalArgs, Uri uri)
+ {
+ int tagReplacedCount = 0;
+ StringBuilder args = new();
+
+ int nextIndexToAdd = 0;
+ int tagStartIndex = originalArgs.IndexOf('{');
+
+ while (tagStartIndex >= 0)
+ {
+ args.Append(originalArgs.AsSpan(nextIndexToAdd, tagStartIndex - nextIndexToAdd));
+ nextIndexToAdd = tagStartIndex;
+
+ int tagEndIndex = originalArgs.IndexOf('}', tagStartIndex);
+ if (tagEndIndex < 0) // if there's no more '}' in the rest of the args string
+ break;
+
+ bool successfullyReplacedTag = true;
+
+ ReadOnlySpan tagContent = originalArgs.AsSpan(tagStartIndex + 1, tagEndIndex - 1 - tagStartIndex);
+ switch (tagContent)
+ {
+ case "url":
+ args.Append(uri.OriginalString);
+ break;
+ case "userinfo":
+ args.Append(uri.UserInfo);
+ break;
+ case "host":
+ args.Append(uri.Host);
+ break;
+ case "port":
+ args.Append(uri.Port);
+ break;
+ case "authority":
+ args.Append(uri.Authority);
+ break;
+ case "path":
+ args.Append(uri.AbsolutePath);
+ break;
+ case "query":
+ args.Append(uri.Query);
+ break;
+ case "fragment":
+ args.Append(uri.Fragment);
+ break;
+
+ default:
+ successfullyReplacedTag = false;
+ break;
+ }
+
+ if (successfullyReplacedTag)
+ {
+ tagReplacedCount++;
+
+ nextIndexToAdd = tagEndIndex + 1;
+ tagStartIndex = originalArgs.IndexOf('{', tagEndIndex);
+ }
+ else
+ tagStartIndex = originalArgs.IndexOf('{', tagStartIndex + 1);
+ }
+
+ if (nextIndexToAdd < originalArgs.Length)
+ args.Append(originalArgs.AsSpan(nextIndexToAdd));
+
+ if (tagReplacedCount == 0)
+ args.Append($" \"{uri.OriginalString}\"");
+
+ return args.ToString();
+ }
}
\ No newline at end of file
diff --git a/README.md b/README.md
index d1a39ca..627430e 100644
--- a/README.md
+++ b/README.md
@@ -135,6 +135,23 @@ Slack | Test = chrome
- Arguments are optional. However, if you provide arguments the path _must_ be enclosed in quotes. For example, `"chrome.exe" --new-window`
- If there are no arguments, then the paths do not need to be quoted. For example, `chrome.exe` will work.
+By default the URL to open is added as the last argument after the call to the executable.
+But if you want it to be called differently, or only partially, you can use specific tags in the arguments you provide.
+These tag will be replaced by their corresponding value in the URL :
+- `{url}` the full, untruncated URL
+- `{userinfo}` the userinfo part of the URL, might be blank if not present in the URL
+- `{host}` the host of the URL, most often this will be a domain name (subdomain included)
+- `{port}` the specific port of the URL, might be blank if not present in the URL
+- `{authority}` the combination of userinfo, host and port separated by their respective delimiters if needed
+- `{path}` the path of the URL, might be only `/` if the link targets the root of the domain
+- `{query}` the query of the URL with the leading `?`, might be blank if not present in the URL
+- `{fragment}` the fragment of the URL with the leading `#`, might be blank if not present in the URL
+
+For example if you want a browser which strip the query from the opened links, you can add this line:
+`noQueryFF = "firefox.exe" "{authority}{path}{fragment}"`
+
+[More details and example about URI composition is available here!](https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Example_URIs)
+
### Sources
- You can optionally specify a "source preference" which matches the window title of the application used to open the link.