BETA
Uses Agent Ransack to search file content in the source directory. Creates a collection containing every file that surfaced a match. Places an HTML summary of the search results in the collection. Opens the preview pane and focuses the HTML summary to view matches.
This is slower than using the agent ransack GUI, but is handy for saving your searches. Also avoids opening a new window.
Button
<?xml version="1.0"?>
<button backcol="none" display="icon" textcol="none">
<label>New Button</label>
<icon1>#notepadpp</icon1>
<function type="normal">
<instruction>@runmode:hide</instruction>
<instruction>ARContentToCollection QUERY="{dlgstring|Containing text?}" FILEPATTERN="{dlgstring|File pattern?|*.*}"</instruction>
</function>
</button>
Script-Addin
// AgentRansackToCollection.js
// Directory Opus Script Add-in
// J.Fourie
// Adds command:
// ARContentToCollection
//
// Main button:
// ARContentToCollection QUERY="{dlgstring|Containing text?}" FILEPATTERN="{dlgstring|File pattern?|*.*}"
//
// Current-folder-only button:
// ARContentToCollection QUERY="{dlgstring|Containing text?}" FILEPATTERN="{dlgstring|File pattern?|*.*}" NORECURSE
var HTML_CONFIG = {
reportTitle: "Agent Ransack Results",
theme: "dark", // "dark" or "light"
includeRawOutput: true,
includeFullPath: true,
includeFolder: false,
includeModified: true,
includeHitCount: true,
includeQueryMetadata: true,
includeOpenLinks: true,
includeCopyablePath: true,
includeSummaryCards: true,
maxSnippetsPerFile: 5,
highlightQuery: true,
sortBy: "name", // "name", "path", "hits", "modified"
showRowNumbers: true,
compactMode: false,
includeReportInCollection: true
};
function OnInit(initData) {
initData.name = "Agent Ransack To Collection";
initData.version = "1.3";
initData.copyright = "J.Fourie";
initData.desc = "Search current folder with Agent Ransack and import content matches into a Directory Opus collection with an HTML report.";
initData.default_enable = true;
var cmd = initData.AddCommand();
cmd.name = "ARContentToCollection";
cmd.method = "OnARContentToCollection";
cmd.desc = "Run Agent Ransack content search in the current source folder and import matches into a collection.";
cmd.label = "Agent Ransack Content Search";
cmd.template = "QUERY/K,FILEPATTERN/K,COLL/K,NORECURSE/S,NOOPEN/S,KEEPDEBUG/S,THEME/K,MAXSNIPS/N,NORAW/S";
}
function OnARContentToCollection(data) {
var args = data.func.args;
var tab = data.func.sourcetab;
var cmdObj = data.func.command;
var queryText = getArg(args, "QUERY", "");
var filePattern = getArg(args, "FILEPATTERN", "*.*");
var collectionName = getArg(args, "COLL", "");
var noRecurse = hasSwitch(args, "NORECURSE");
var noOpen = hasSwitch(args, "NOOPEN");
var keepDebug = hasSwitch(args, "KEEPDEBUG");
var themeArg = getArg(args, "THEME", "");
if (themeArg) {
HTML_CONFIG.theme = themeArg;
}
var maxSnipsArg = getArg(args, "MAXSNIPS", "");
if (maxSnipsArg) {
var ms = parseInt(maxSnipsArg, 10);
if (!isNaN(ms) && ms >= 0) {
HTML_CONFIG.maxSnippetsPerFile = ms;
}
}
if (hasSwitch(args, "NORAW")) {
HTML_CONFIG.includeRawOutput = false;
}
queryText = clean(queryText);
filePattern = clean(filePattern);
if (!queryText) {
DOpus.Output("ARContentToCollection: missing QUERY.");
return;
}
if (!filePattern) {
filePattern = "*.*";
}
var searchRoot = clean(String(tab.path));
searchRoot = normaliseSlash(searchRoot);
collectionName = clean(collectionName);
if (!collectionName) {
collectionName = makeCollectionName(queryText, searchRoot);
}
var fso = new ActiveXObject("Scripting.FileSystemObject");
var shell = new ActiveXObject("WScript.Shell");
var agentExe = findAgentRansackExe(fso);
var dopusrt = findDOpusRT(fso);
if (!agentExe) {
DOpus.Output("ARContentToCollection: could not find flpsearch.exe.");
return;
}
if (!dopusrt) {
DOpus.Output("ARContentToCollection: could not find dopusrt.exe.");
return;
}
var temp = fso.GetSpecialFolder(2).Path;
var stamp = makeStamp();
var rawOutput = fso.BuildPath(temp, "ar-content-raw-" + stamp + ".txt");
var pathList = fso.BuildPath(temp, "ar-content-paths-" + stamp + ".txt");
var logPath = fso.BuildPath(temp, "ar-content-debug-" + stamp + ".log");
var htmlReport = fso.BuildPath(temp, "AgentRansackResults_Report-" + stamp + ".html");
logToFile(fso, logPath, "SearchRoot=" + searchRoot);
logToFile(fso, logPath, "Query=" + queryText);
logToFile(fso, logPath, "FilePattern=" + filePattern);
logToFile(fso, logPath, "CollectionName=" + collectionName);
logToFile(fso, logPath, "RawOutput=" + rawOutput);
logToFile(fso, logPath, "PathList=" + pathList);
logToFile(fso, logPath, "HtmlReport=" + htmlReport);
var arCmd = quote(agentExe)
+ " -d " + quote(searchRoot)
+ " -f " + quote(filePattern)
+ " -c " + quote(queryText)
+ " -o " + quote(rawOutput)
+ " -oft"
+ " -ofr:contents"
+ " -oc"
+ " -ol 20"
+ " -oe8";
if (!noRecurse) {
arCmd += " -s";
}
DOpus.Output("Running Agent Ransack...");
DOpus.Output(arCmd);
logToFile(fso, logPath, "Command=" + arCmd);
var rc = shell.Run(arCmd, 0, true);
if (rc !== 0) {
DOpus.Output("Agent Ransack returned error code: " + rc);
logToFile(fso, logPath, "Agent Ransack error code=" + rc);
return;
}
if (!fso.FileExists(rawOutput)) {
DOpus.Output("Agent Ransack did not create raw output.");
logToFile(fso, logPath, "Raw output missing.");
return;
}
var raw = readTextUtf8(rawOutput);
logToFile(fso, logPath, "----- RAW OUTPUT START -----");
logToFile(fso, logPath, raw);
logToFile(fso, logPath, "----- RAW OUTPUT END -----");
var records = parseAgentRansackOutput(raw, searchRoot, fso, logPath);
sortRecords(records);
var html = makeHtmlReport(records, raw, searchRoot, queryText);
writeTextUtf8(htmlReport, html);
var paths = [];
if (HTML_CONFIG.includeReportInCollection) {
paths.push(htmlReport);
}
for (var i = 0; i < records.length; i++) {
paths.push(records[i].path);
}
writePathList(pathList, paths);
logToFile(fso, logPath, "Matched file count=" + records.length);
logToFile(fso, logPath, "Collection path count=" + paths.length);
if (paths.length === 0) {
DOpus.Output("No results. Log: " + logPath);
return;
}
var importCmd = quote(dopusrt)
+ " /col import /utf8 /clear /create /nocheck "
+ quote(collectionName)
+ " "
+ quote(pathList);
DOpus.Output("Importing collection: " + collectionName);
logToFile(fso, logPath, "ImportCommand=" + importCmd);
var importRc = shell.Run(importCmd, 0, true);
if (importRc !== 0) {
DOpus.Output("dopusrt import failed: " + importRc);
logToFile(fso, logPath, "dopusrt import failed=" + importRc);
return;
}
if (!noOpen) {
cmdObj.RunCommand('Go PATH="coll://' + collectionName.replace(/"/g, '""') + '"');
shell.Run('cmd.exe /d /c ping -n 2 127.0.0.1 >nul', 0, true);
cmdObj.RunCommand("Set VIEWPANE=on");
cmdObj.RunCommand("Set VIEWPANELOCK=off");
cmdObj.ClearFiles();
cmdObj.AddFile(htmlReport);
cmdObj.RunCommand("Select FROMSCRIPT DESELECTNOMATCH SETFOCUS");
shell.Run('cmd.exe /d /c ping -n 1 127.0.0.1 >nul', 0, true);
cmdObj.RunCommand("Select THIS");
}
DOpus.Output("Agent Ransack collection created: " + collectionName);
DOpus.Output("Matched files: " + records.length);
DOpus.Output("HTML report: " + htmlReport);
DOpus.Output("Debug log: " + logPath);
if (!keepDebug) {
try {
if (fso.FileExists(rawOutput)) {
fso.DeleteFile(rawOutput, true);
}
if (fso.FileExists(pathList)) {
fso.DeleteFile(pathList, true);
}
} catch (e) {
}
}
}
function getArg(args, name, def) {
try {
if (args.got_arg[name]) {
return String(args[name]);
}
} catch (e1) {
}
try {
var lower = name.toLowerCase();
if (args.got_arg[lower]) {
return String(args[lower]);
}
} catch (e2) {
}
try {
if (typeof args[name] !== "undefined" && String(args[name]) !== "") {
return String(args[name]);
}
} catch (e3) {
}
return def;
}
function hasSwitch(args, name) {
try {
if (args.got_arg[name]) {
return true;
}
} catch (e1) {
}
try {
var lower = name.toLowerCase();
if (args.got_arg[lower]) {
return true;
}
} catch (e2) {
}
return false;
}
function makeCollectionName(queryText, searchRoot) {
var q = sanitizeCollectionPart(queryText);
var l = sanitizeLocationPart(searchRoot);
if (!q) {
q = "query";
}
if (!l) {
l = "location";
}
var prefix = "RS-Q_";
var middle = "--L_";
var name = prefix + q + middle + l;
// Keep collection names readable.
if (name.length > 140) {
var maxQueryLen = 50;
var maxLocationLen = 140 - prefix.length - middle.length - maxQueryLen;
if (maxLocationLen < 30) {
maxLocationLen = 30;
}
q = q.substring(0, maxQueryLen);
l = tailString(l, maxLocationLen);
name = prefix + q + middle + l;
}
return name;
}
function sanitizeCollectionPart(s) {
s = String(s);
// Remove characters that can break Opus collection paths or command quoting.
s = s.replace(/[\\\/:*?"<>|^&%;=+,`~!@#$()[\]{}]/g, "_");
// Collapse whitespace and underscores.
s = s.replace(/\s+/g, "_");
s = s.replace(/_+/g, "_");
// Trim edge junk.
s = s.replace(/^_+|_+$/g, "");
return s;
}
function sanitizeLocationPart(s) {
s = String(s);
// Preserve drive letter in a safe way:
// C:\Utilities\Airline_Trader -> C_Utilities_Airline_Trader
s = s.replace(/^([A-Za-z]):\\?/, "$1_");
// Replace path separators and unsafe characters.
s = s.replace(/[\\\/:*?"<>|^&%;=+,`~!@#$()[\]{}]/g, "_");
// Collapse whitespace and underscores.
s = s.replace(/\s+/g, "_");
s = s.replace(/_+/g, "_");
// Trim edge junk.
s = s.replace(/^_+|_+$/g, "");
return s;
}
function tailString(s, maxLen) {
s = String(s);
if (s.length <= maxLen) {
return s;
}
return s.substring(s.length - maxLen);
}
function findAgentRansackExe(fso) {
var candidates = [
"C:\\Program Files\\Mythicsoft\\Agent Ransack\\flpsearch.exe",
"C:\\Program Files\\Mythicsoft\\FileLocator Pro\\flpsearch.exe",
"C:\\Program Files (x86)\\Mythicsoft\\Agent Ransack\\flpsearch.exe",
"C:\\Program Files (x86)\\Mythicsoft\\FileLocator Pro\\flpsearch.exe"
];
for (var i = 0; i < candidates.length; i++) {
if (fso.FileExists(candidates[i])) {
return candidates[i];
}
}
return "";
}
function findDOpusRT(fso) {
var candidates = [
"C:\\Program Files\\GPSoftware\\Directory Opus\\dopusrt.exe",
"C:\\Program Files (x86)\\GPSoftware\\Directory Opus\\dopusrt.exe"
];
for (var i = 0; i < candidates.length; i++) {
if (fso.FileExists(candidates[i])) {
return candidates[i];
}
}
return "";
}
function makeStamp() {
var d = new Date();
return ""
+ d.getFullYear()
+ pad2(d.getMonth() + 1)
+ pad2(d.getDate())
+ "-"
+ pad2(d.getHours())
+ pad2(d.getMinutes())
+ pad2(d.getSeconds())
+ "-"
+ Math.floor(Math.random() * 100000);
}
function pad2(n) {
n = String(n);
return n.length < 2 ? "0" + n : n;
}
function quote(s) {
return '"' + String(s).replace(/"/g, '""') + '"';
}
function logToFile(fso, path, msg) {
try {
var f = fso.OpenTextFile(path, 8, true);
f.WriteLine(msg);
f.Close();
} catch (e) {
}
}
function readTextUtf8(path) {
var stream = new ActiveXObject("ADODB.Stream");
stream.Type = 2;
stream.Charset = "utf-8";
stream.Open();
stream.LoadFromFile(path);
var text = stream.ReadText();
stream.Close();
return text;
}
function writeTextUtf8(path, text) {
var stream = new ActiveXObject("ADODB.Stream");
stream.Type = 2;
stream.Charset = "utf-8";
stream.Open();
stream.WriteText(text);
stream.SaveToFile(path, 2);
stream.Close();
}
function writePathList(path, list) {
var fso = new ActiveXObject("Scripting.FileSystemObject");
var f = fso.CreateTextFile(path, true, false);
for (var i = 0; i < list.length; i++) {
f.WriteLine(list[i]);
}
f.Close();
}
function trim(s) {
return String(s).replace(/^\s+|\s+$/g, "");
}
function clean(s) {
s = trim(s);
s = s.replace(/^\uFEFF/, "");
s = s.replace(/^"+|"+$/g, "");
s = s.replace(/[;,]+$/g, "");
return trim(s);
}
function normaliseSlash(s) {
return String(s).replace(/\//g, "\\");
}
function startsWithIgnoreCase(s, prefix) {
s = String(s).toLowerCase();
prefix = String(prefix).toLowerCase();
return s.indexOf(prefix) === 0;
}
function isRootedPath(s) {
return /^[A-Za-z]:\\/.test(s);
}
function isRealFile(path, fso) {
try {
return fso.FileExists(path) && !fso.FolderExists(path);
} catch (e) {
return false;
}
}
function htmlEscape(s) {
return String(s)
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """);
}
function regexEscape(s) {
return String(s).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
function highlightText(text, query) {
if (!HTML_CONFIG.highlightQuery) {
return htmlEscape(text);
}
query = clean(query);
if (!query) {
return htmlEscape(text);
}
var escaped = htmlEscape(text);
var q = regexEscape(htmlEscape(query));
try {
var re = new RegExp("(" + q + ")", "ig");
return escaped.replace(re, "<mark>$1</mark>");
} catch (e) {
return escaped;
}
}
function fileUrl(path) {
var p = normaliseSlash(path).replace(/\\/g, "/");
return "file:///" + encodeURI(p);
}
function addRecord(path, modified, hitCount, dict, records, searchRoot, fso, logPath, reason) {
path = clean(normaliseSlash(path));
if (!path) {
return null;
}
if (!isRootedPath(path)) {
logToFile(fso, logPath, "SKIP not rooted [" + reason + "]: " + path);
return null;
}
if (!startsWithIgnoreCase(path, searchRoot)) {
logToFile(fso, logPath, "SKIP outside root [" + reason + "]: " + path);
return null;
}
if (!isRealFile(path, fso)) {
logToFile(fso, logPath, "SKIP not real file [" + reason + "]: " + path);
return null;
}
var key = path.toLowerCase();
if (!dict[key]) {
dict[key] = {
path: path,
name: fso.GetFileName(path),
folder: fso.GetParentFolderName(path),
modified: modified || "",
hitCount: hitCount || "",
snippets: []
};
records.push(dict[key]);
logToFile(fso, logPath, "ADD [" + reason + "]: " + path);
} else {
if (modified && !dict[key].modified) {
dict[key].modified = modified;
}
if (hitCount && !dict[key].hitCount) {
dict[key].hitCount = hitCount;
}
}
return dict[key];
}
function parseFullPathDateRow(line) {
var re = /^([A-Za-z]:\\.*)\s+(\d{1,2}\/\d{1,2}\/\d{4}\s+\d{1,2}:\d{2}(?::\d{2})?\s*(?:AM|PM)?)\s+(\d+)\s*$/i;
var m = re.exec(line);
if (!m) {
return null;
}
return {
path: clean(m[1]),
modified: clean(m[2]),
hitCount: clean(m[3])
};
}
function parseFilenameFolderDateRow(line) {
var re = /^(.*?)\s+([A-Za-z]:\\.*\\)\s+(\d{1,2}\/\d{1,2}\/\d{4}\s+\d{1,2}:\d{2}(?::\d{2})?\s*(?:AM|PM)?)(?:\s+(\d+))?\s*$/i;
var m = re.exec(line);
if (!m) {
return null;
}
var filename = clean(m[1]);
var folder = clean(m[2]);
var path = folder + filename;
return {
path: clean(path),
modified: clean(m[3]),
hitCount: clean(m[4] || "")
};
}
function parseSnippetLine(line) {
var re = /^(\d+)\s+(.*)$/;
var m = re.exec(line);
if (!m) {
return null;
}
return {
lineNo: clean(m[1]),
text: clean(m[2])
};
}
function parseAgentRansackOutput(raw, searchRoot, fso, logPath) {
searchRoot = clean(normaliseSlash(searchRoot));
if (searchRoot.length > 0 && !/[\\]$/.test(searchRoot)) {
searchRoot = searchRoot + "\\";
}
var lines = raw.split(/\r?\n/);
var dict = {};
var records = [];
var currentRecord = null;
for (var i = 0; i < lines.length; i++) {
var line = clean(lines[i]);
if (!line) {
continue;
}
var row = parseFullPathDateRow(line);
if (!row) {
row = parseFilenameFolderDateRow(line);
}
if (row) {
currentRecord = addRecord(row.path, row.modified, row.hitCount, dict, records, searchRoot, fso, logPath, "ResultRow");
continue;
}
var snippet = parseSnippetLine(line);
if (snippet && currentRecord) {
currentRecord.snippets.push(snippet);
logToFile(fso, logPath, "SNIPPET " + currentRecord.path + " L" + snippet.lineNo);
}
}
return records;
}
function numericHitCount(record) {
var n = parseInt(record.hitCount, 10);
if (isNaN(n)) {
return 0;
}
return n;
}
function sortRecords(records) {
var mode = String(HTML_CONFIG.sortBy || "name").toLowerCase();
records.sort(function(a, b) {
if (mode === "hits") {
return numericHitCount(b) - numericHitCount(a);
}
if (mode === "path") {
var ap = a.path.toLowerCase();
var bp = b.path.toLowerCase();
if (ap < bp) return -1;
if (ap > bp) return 1;
return 0;
}
if (mode === "modified") {
var am = a.modified.toLowerCase();
var bm = b.modified.toLowerCase();
if (am < bm) return 1;
if (am > bm) return -1;
return 0;
}
var an = a.name.toLowerCase();
var bn = b.name.toLowerCase();
if (an < bn) return -1;
if (an > bn) return 1;
return 0;
});
}
function totalHits(records) {
var total = 0;
for (var i = 0; i < records.length; i++) {
total += numericHitCount(records[i]);
}
return total;
}
function themeCss() {
if (String(HTML_CONFIG.theme).toLowerCase() === "light") {
return ""
+ "body{font-family:Segoe UI,Arial,sans-serif;margin:20px;background:#f7f7f7;color:#111;}\r\n"
+ "h1{font-size:20px;margin:0 0 10px 0;}\r\n"
+ ".meta{color:#333;margin-bottom:18px;font-size:13px;line-height:1.5;}\r\n"
+ ".cards{display:flex;gap:10px;margin:12px 0 18px 0;flex-wrap:wrap;}\r\n"
+ ".card{background:#fff;border:1px solid #ccc;border-radius:8px;padding:10px 12px;min-width:130px;}\r\n"
+ ".card .k{font-size:11px;color:#666;text-transform:uppercase;}\r\n"
+ ".card .v{font-size:18px;font-weight:600;}\r\n"
+ "table{border-collapse:collapse;width:100%;font-size:13px;background:#fff;}\r\n"
+ "th,td{border:1px solid #ddd;padding:7px 8px;vertical-align:top;}\r\n"
+ "th{background:#eee;text-align:left;position:sticky;top:0;}\r\n"
+ "tr:nth-child(even){background:#fafafa;}\r\n"
+ "a{color:#0645ad;text-decoration:none;}\r\n"
+ "a:hover{text-decoration:underline;}\r\n"
+ ".path{color:#555;font-size:12px;word-break:break-all;}\r\n"
+ ".snippet{white-space:pre-wrap;font-family:Consolas,monospace;color:#222;margin-bottom:4px;}\r\n"
+ ".line{color:#8a5a00;font-weight:bold;}\r\n"
+ "mark{background:#fff176;color:#000;padding:0 2px;}\r\n"
+ "details{margin-top:22px;}\r\n"
+ "pre{white-space:pre-wrap;background:#fff;border:1px solid #ccc;padding:10px;overflow:auto;}\r\n";
}
return ""
+ "body{font-family:Segoe UI,Arial,sans-serif;margin:20px;background:#111;color:#eee;}\r\n"
+ "h1{font-size:20px;margin:0 0 10px 0;}\r\n"
+ ".meta{color:#bbb;margin-bottom:18px;font-size:13px;line-height:1.5;}\r\n"
+ ".cards{display:flex;gap:10px;margin:12px 0 18px 0;flex-wrap:wrap;}\r\n"
+ ".card{background:#1b1b1b;border:1px solid #333;border-radius:8px;padding:10px 12px;min-width:130px;}\r\n"
+ ".card .k{font-size:11px;color:#aaa;text-transform:uppercase;}\r\n"
+ ".card .v{font-size:18px;font-weight:600;}\r\n"
+ "table{border-collapse:collapse;width:100%;font-size:13px;}\r\n"
+ "th,td{border:1px solid #333;padding:7px 8px;vertical-align:top;}\r\n"
+ "th{background:#222;text-align:left;position:sticky;top:0;}\r\n"
+ "tr:nth-child(even){background:#181818;}\r\n"
+ "a{color:#8ab4f8;text-decoration:none;}\r\n"
+ "a:hover{text-decoration:underline;}\r\n"
+ ".path{color:#aaa;font-size:12px;word-break:break-all;}\r\n"
+ ".snippet{white-space:pre-wrap;font-family:Consolas,monospace;color:#ddd;margin-bottom:4px;}\r\n"
+ ".line{color:#f0c674;font-weight:bold;}\r\n"
+ "mark{background:#f5fc0c;color:#000;padding:0 2px;}\r\n"
+ "details{margin-top:22px;}\r\n"
+ "pre{white-space:pre-wrap;background:#080808;border:1px solid #333;padding:10px;overflow:auto;}\r\n";
}
function makeHtmlReport(records, rawText, searchRoot, queryText) {
var now = new Date();
var maxSnips = parseInt(HTML_CONFIG.maxSnippetsPerFile, 10);
if (isNaN(maxSnips) || maxSnips < 0) {
maxSnips = 5;
}
var html = "";
html += "<!doctype html>\r\n";
html += "<html><head><meta charset=\"utf-8\">\r\n";
html += "<title>" + htmlEscape(HTML_CONFIG.reportTitle) + "</title>\r\n";
html += "<style>\r\n";
html += themeCss();
if (HTML_CONFIG.compactMode) {
html += "body{margin:10px;} th,td{padding:4px 5px;font-size:12px;} .snippet{font-size:12px;}\r\n";
}
html += "</style>\r\n";
html += "</head><body>\r\n";
html += "<h1>" + htmlEscape(HTML_CONFIG.reportTitle) + "</h1>\r\n";
if (HTML_CONFIG.includeQueryMetadata) {
html += "<div class=\"meta\">";
html += "<div><b>Query:</b> " + htmlEscape(queryText) + "</div>";
html += "<div><b>Search root:</b> " + htmlEscape(searchRoot) + "</div>";
html += "<div><b>Generated:</b> " + htmlEscape(now.toLocaleString()) + "</div>";
html += "</div>\r\n";
}
if (HTML_CONFIG.includeSummaryCards) {
html += "<div class=\"cards\">";
html += "<div class=\"card\"><div class=\"k\">Files</div><div class=\"v\">" + records.length + "</div></div>";
html += "<div class=\"card\"><div class=\"k\">Hits</div><div class=\"v\">" + totalHits(records) + "</div></div>";
html += "<div class=\"card\"><div class=\"k\">Mode</div><div class=\"v\">content</div></div>";
html += "</div>\r\n";
}
html += "<table>\r\n";
html += "<thead><tr>";
if (HTML_CONFIG.showRowNumbers) {
html += "<th>#</th>";
}
html += "<th>File</th>";
if (HTML_CONFIG.includeFolder) {
html += "<th>Folder</th>";
}
if (HTML_CONFIG.includeHitCount) {
html += "<th>Hits</th>";
}
if (HTML_CONFIG.includeModified) {
html += "<th>Modified</th>";
}
html += "<th>Preview</th>";
html += "</tr></thead>\r\n";
html += "<tbody>\r\n";
for (var i = 0; i < records.length; i++) {
var r = records[i];
html += "<tr>";
if (HTML_CONFIG.showRowNumbers) {
html += "<td>" + (i + 1) + "</td>";
}
html += "<td>";
if (HTML_CONFIG.includeOpenLinks) {
html += "<a href=\"" + htmlEscape(fileUrl(r.path)) + "\">" + htmlEscape(r.name) + "</a>";
} else {
html += htmlEscape(r.name);
}
if (HTML_CONFIG.includeFullPath) {
html += "<div class=\"path\">" + htmlEscape(r.path) + "</div>";
}
if (HTML_CONFIG.includeCopyablePath) {
html += "<div class=\"path\"><code>" + htmlEscape(r.path) + "</code></div>";
}
html += "</td>";
if (HTML_CONFIG.includeFolder) {
html += "<td class=\"path\">" + htmlEscape(r.folder) + "</td>";
}
if (HTML_CONFIG.includeHitCount) {
html += "<td>" + htmlEscape(r.hitCount) + "</td>";
}
if (HTML_CONFIG.includeModified) {
html += "<td>" + htmlEscape(r.modified) + "</td>";
}
html += "<td>";
if (r.snippets.length === 0) {
html += "<span class=\"path\">No snippet captured.</span>";
} else {
var limit = r.snippets.length;
if (maxSnips > 0 && limit > maxSnips) {
limit = maxSnips;
}
for (var s = 0; s < limit; s++) {
html += "<div class=\"snippet\">";
html += "<span class=\"line\">L" + htmlEscape(r.snippets[s].lineNo) + "</span> ";
html += highlightText(r.snippets[s].text, queryText);
html += "</div>";
}
if (r.snippets.length > limit) {
html += "<div class=\"path\">+" + (r.snippets.length - limit) + " more snippet(s) hidden by config.</div>";
}
}
html += "</td>";
html += "</tr>\r\n";
}
html += "</tbody></table>\r\n";
if (HTML_CONFIG.includeRawOutput) {
html += "<details><summary>Raw Agent Ransack output</summary>\r\n";
html += "<pre>" + htmlEscape(rawText) + "</pre>\r\n";
html += "</details>\r\n";
}
html += "</body></html>\r\n";
return html;
}
Normal GUI search button:
- Searches in the selected file/folder (if no file/folder is selected, searches in source directory)
<?xml version="1.0"?>
<button backcol="none" display="both" hotkey_label="yes" icon_size="large" textcol="none">
<label>Ransack Search in File/Source</label>
<hotkeys>
<chord>
<key>186,0</key>
<key>R</key>
<key>S</key>
</chord>
</hotkeys>
<icon1>#Ransack_(32px_&_22px):AgentRansack_104</icon1>
<function type="batch">
<instruction>@icon:/DOpusConfig/Icon_toggle/ransack.png</instruction>
<instruction>@runmode:hide</instruction>
<instruction>@ifsel:files</instruction>
<instruction> "C:\Program Files\Mythicsoft\Agent Ransack\AgentRansack.exe" -pa -r -d "{allfilepath|..\|noterm|sep=;}" -c "{dlgstring|Search Within Text:}"</instruction>
<instruction>@ifsel:else</instruction>
<instruction> "C:\Program Files\Mythicsoft\Agent Ransack\AgentRansack.exe" -pa -r -d "{sourcepath|noterm}" -c "{dlgstring|Search Within Text:}"</instruction>
</function>
</button>
