Handlebars.Net with local File path - c#

I have a configuration value that represents a folder where some files are available for download. This value is a handlebars template:
"D:\{{identifier1}}\{{identifier2}}\SomeFolder\{{version}}"
This value is set per environment by our deploy server.
The problem is that when I run the template through like this:
var template = Handlebars.Compile(_configuration.FilePathFormat);
return template(new
{
identifier1 = 123,
identifier2 = 456,
version = "latest"
});
The result I get back is this:
R:{{identifier1}}{{identifier2}}\SomeFolder{{version}}
What I expect:
R:\123\456\SomeFolder\latest
For some reason it is escaping the handlebars and I don't want that. I have been unable to find anything on disabling escape characters, and no amount of slashes has worked to render the template correctly.
Also, if I put a space between the slash and the handlebar placeholder, it compiles and renders correctly, but then it has a space in the file path.
I found a site that let me test handlebars.js, but it behaves differently than handlebars.net

Update: Fixed in Handlebars.net
Sice version 1.9.3, released right after I reported the bug, this now works just fine. You have to double your slashes in the template to escape them for Handlebars.Net, same as for Handlebars.js,
var templateText = #"D:\\{{identifier1}}\\{{identifier2}}\\SomeFolder\\{{version}}";
var compiledTemplate = Handlebars.Compile(templateText);
var path = compiledTemplate(new
{
identifier1 = 123,
identifier2 = 456,
version = "latest"
});
Original answer:
Yes, it seems Handlebars.net has some weird handling of escape characters.
The simplest workaround is to just invert the slashes in the template string.
var templateText = #"D:/{{identifier1}}/{{identifier2}}/SomeFolder/{{version}}";
var compiledTemplate = Handlebars.Compile(templateText);
var pathWithInvertedSlashes = compiledTemplate(new
{
identifier1 = 123,
identifier2 = 456,
version = "latest"
});
// Inverted slashes normally work fine on Windows, but if you want to
// 'fix' them you can always do
var canonicalPath = Path.GetFullPath(pathWithInvertedSlashes);

Related

Gembox document removes table of contents

I'm using Gembox document to replace some text in a docx document and it works great. However, I have a table of contents field that disappears after saving the document.
I tried doing the following but the field still disappears leaving only the placeholder text:
var toc = (TableOfEntries)document.GetChildElements(true, ElementType.TableOfEntries).First();
toc.Update();
document.GetPaginator(new PaginatorOptions() { UpdateFields = true });
UPDATE (2021-01-15):
Please try again with the latest version from the BugFixes page or from NuGet.
The latest version will work on the machine that uses culture with ';' character as a list separator.
Or you can specify that culture like this:
var toc = (TableOfEntries)document.GetChildElements(true, ElementType.TableOfEntries).First();
CultureInfo.CurrentCulture = new CultureInfo("fr");
toc.Update();
document.GetPaginator(new PaginatorOptions() { UpdateFields = true });
Also, the issue with the missing tab stop should be resolved now as well.
ORIGINAL:
When I tried to update your TOC from MS Word, I got the following:
No table of contents entries found.
After investigating the field's code of your TOC element, I figured out what the problem is.
This is the instruction text that you have:
{ TOC \h \z \t "TitreChapitre;1;SousTitreChapitre;2" }
These semicolon character separators (;) are culture-dependent. In other words, updating this TOC element will work on a machine that has a French region and settings, but it won't work when you have an English region and settings.
I'm currently on vacation, so I can't do anything about this. When I come back I will fix this problem for you.
For now, can you use the following as a workaround (I also noticed an issue with missing TabStop, this workaround will cover that as well):
var toc = (TableOfEntries)document.GetChildElements(true, ElementType.TableOfEntries).First();
var section = toc.Parent as Section;
var tocWidth = section.PageSetup.PageWidth - section.PageSetup.PageMargins.Left - section.PageSetup.PageMargins.Right;
var toc1Style = document.Styles["toc 1"] as ParagraphStyle;
var toc1TabStop = new TabStop(tocWidth - toc1Style.ParagraphFormat.RightIndentation, TabStopAlignment.Right, TabStopLeader.Dot);
toc1Style.ParagraphFormat.Tabs.Add(toc1TabStop);
var toc2Style = document.Styles["toc 2"] as ParagraphStyle;
var toc2TabStop = new TabStop(tocWidth - toc2Style.ParagraphFormat.RightIndentation, TabStopAlignment.Right, TabStopLeader.Dot);
toc2Style.ParagraphFormat.Tabs.Add(toc2TabStop);
toc.InstructionText = toc.InstructionText.Replace(';', ',');
toc.Update();
document.GetPaginator(new PaginatorOptions() { UpdateFields = true });
I hope this works for you.

how to get json from passed string via command line c#

I'm doing that for a reason. This is what i need for the next step of my application. I'm creating Visual Studio Extension and i need that for communication between plugin and proj.
I pass json string as argument of command line in visual studio.
When i load that string from the console it's devoid of certain json characters, making it impossible to deserialize.
What i paste as arg to console is:
{"lastModifiedDate":"2020-07-13T08:06:01Z","model":{"softwareSystems":[{"containers":[{"components":[{"location":0,"relationships":[{"sourceId":9,"destinationId":11,"technology":"","id":14,"name":null,"description":"","tags":"Relationship","tagsList":[]}],"id":9,"name":"system1 container1 component1","description":"","tags":"Element,Component","tagsList":[]},{"location":0,"relationships":[{"sourceId":10,"destinationId":9,"technology":"","id":16,"name":null,"description":"","tags":"Relationship","tagsList":[]}],"id":10,"name":"system1 container1 component2","description":"","tags":"Element,Component","tagsList":[]}],"location":0,"relationships":[{"sourceId":5,"destinationId":8,"technology":"","id":13,"name":null,"description":"","tags":"Relationship","tagsList":[]}],"id":5,"name":"system1 container1","description":"","tags":"Element,Container","tagsList":[]},{"components":[{"location":0,"relationships":[],"id":11,"name":"system2 container1 component1","description":"","tags":"Element,Component","tagsList":[]}],"location":0,"relationships":[{"sourceId":6,"destinationId":5,"technology":"","id":15,"name":null,"description":"","tags":"Relationship","tagsList":[]}],"id":6,"name":"system1 container2","description":"","tags":"Element,Container","tagsList":[]}],"location":0,"relationships":[{"sourceId":2,"destinationId":4,"technology":"","id":12,"name":null,"description":"","tags":"Relationship","tagsList":[]},{"sourceId":2,"destinationId":7,"technology":"","id":20,"name":null,"description":"","tags":"Relationship","tagsList":[]}],"id":2,"name":"Software System1","description":"My software system.","tags":"Element,Software System","tagsList":[]},{"containers":[{"components":[],"location":0,"relationships":[{"sourceId":7,"destinationId":6,"technology":"","id":17,"name":null,"description":"","tags":"Relationship","tagsList":[]}],"id":7,"name":"system2 container2","description":"","tags":"Element,Container","tagsList":[]},{"components":[],"location":0,"relationships":[{"sourceId":8,"destinationId":7,"technology":"","id":21,"name":null,"description":"","tags":"Relationship","tagsList":[]}],"id":8,"name":"system2 container1","description":"","tags":"Element,Container","tagsList":[]}],"location":0,"relationships":[],"id":4,"name":"Software System2","description":"","tags":"Element,Software System","tagsList":[]}],"people":[{"location":0,"relationships":[{"sourceId":1,"destinationId":2,"technology":"","id":3,"name":null,"description":"Uses","tags":"Relationship,Synchronous","tagsList":[]},{"sourceId":1,"destinationId":9,"technology":"","id":18,"name":null,"description":"","tags":"Relationship","tagsList":[]},{"sourceId":1,"destinationId":5,"technology":"","id":19,"name":null,"description":"","tags":"Relationship","tagsList":[]}],"id":1,"name":"User","description":"A user of my software system.","tags":"Element,Person","tagsList":[]}],"lastId":0},"views":{"systemContextViews":[{"softwareSystemId":2,"description":"An example of a System Context diagram.","configuration":{"styles":null},"elements":[{"id":4,"x":305,"y":300},{"id":1,"x":1255,"y":-5},{"id":2,"x":1190,"y":935}],"relationships":[{"id":3},{"id":12}]}],"containerViews":[{"softwareSystemId":2,"description":"","elements":[{"id":5,"x":110,"y":215},{"id":6,"x":1875,"y":715}],"relationships":[{"id":15}]},{"softwareSystemId":4,"description":"","elements":[{"id":8,"x":175,"y":224},{"id":7,"x":1845,"y":720}],"relationships":[{"id":21}]}],"componentViews":[{"containerId":5,"description":"","elements":[{"id":9,"x":120,"y":80},{"id":10,"x":1880,"y":1105},{"id":11,"x":130,"y":1000},{"id":1,"x":1760,"y":120}],"relationships":[{"id":14},{"id":16},{"id":18}]}]},"id":0,"name":"Demo workspace","description":"A demo workspace.","tags":"ElementBase,Workspace","tagsList":[]}
and from the console i get
"{lastModifiedDate:2020-07-13T08:06:01Z,model:{softwareSystems:[{containers:[{components:[{location:0,relationships:[{sourceId:9,destinationId:11,technology:,id:14,name:null,description:,tags:Relationship,tagsList:[]}],id:9,name:system1 container1 component1,description:,tags:Element,Component,tagsList:[]},{location:0,relationships:[{sourceId:10,destinationId:9,technology:,id:16,name:null,description:,tags:Relationship,tagsList:[]}],id:10,name:system1 container1 component2,description:,tags:Element,Component,tagsList:[]}],location:0,relationships:[{sourceId:5,destinationId:8,technology:,id:13,name:null,description:,tags:Relationship,tagsList:[]}],id:5,name:system1 container1,description:,tags:Element,Container,tagsList:[]},{components:[{location:0,relationships:[],id:11,name:system2 container1 component1,description:,tags:Element,Component,tagsList:[]}],location:0,relationships:[{sourceId:6,destinationId:5,technology:,id:15,name:null,description:,tags:Relationship,tagsList:[]}],id:6,name:system1 container2,description:,tags:Element,Container,tagsList:[]}],location:0,relationships:[{sourceId:2,destinationId:4,technology:,id:12,name:null,description:,tags:Relationship,tagsList:[]},{sourceId:2,destinationId:7,technology:,id:20,name:null,description:,tags:Relationship,tagsList:[]}],id:2,name:Software System1,description:My software system.,tags:Element,Software System,tagsList:[]},{containers:[{components:[],location:0,relationships:[{sourceId:7,destinationId:6,technology:,id:17,name:null,description:,tags:Relationship,tagsList:[]}],id:7,name:system2 container2,description:,tags:Element,Container,tagsList:[]},{components:[],location:0,relationships:[{sourceId:8,destinationId:7,technology:,id:21,name:null,description:,tags:Relationship,tagsList:[]}],id:8,name:system2 container1,description:,tags:Element,Container,tagsList:[]}],location:0,relationships:[],id:4,name:Software System2,description:,tags:Element,Software System,tagsList:[]}],people:[{location:0,relationships:[{sourceId:1,destinationId:2,technology:,id:3,name:null,description:Uses,tags:Relationship,Synchronous,tagsList:[]},{sourceId:1,destinationId:9,technology:,id:18,name:null,description:,tags:Relationship,tagsList:[]},{sourceId:1,destinationId:5,technology:,id:19,name:null,description:,tags:Relationship,tagsList:[]}],id:1,name:User,description:A user of my software system.,tags:Element,Person,tagsList:[]}],lastId:0},views:{systemContextViews:[{softwareSystemId:2,description:An example of a System Context diagram.,configuration:{styles:null},elements:[{id:4,x:305,y:300},{id:1,x:1255,y:-5},{id:2,x:1190,y:935}],relationships:[{id:3},{id:12}]}],containerViews:[{softwareSystemId:2,description:,elements:[{id:5,x:110,y:215},{id:6,x:1875,y:715}],relationships:[{id:15}]},{softwareSystemId:4,description:,elements:[{id:8,x:175,y:224},{id:7,x:1845,y:720}],relationships:[{id:21}]}],componentViews:[{containerId:5,description:,elements:[{id:9,x:120,y:80},{id:10,x:1880,y:1105},{id:11,x:130,y:1000},{id:1,x:1760,y:120}],relationships:[{id:14},{id:16},{id:18}]}]},id:0,name:Demo workspace,description:A demo workspace.,tags:ElementBase,Workspace,tagsList:[]}"
As you can see "{", double quotes are missing.
How i'm getting strings from console:
string[] commandLineArgs = Environment.GetCommandLineArgs();
I would need method which can convert to the same form because strings will be different
Do you know how to solve my problem?
c:\> myapp.exe "{\"asdf\":\"x yz\", \"xyz\": 3}"
worked for me (on Win10, can't test other versions right now).
Escape all doublequotes that belong to the JSON string with a \. Then enclose the whole json object with double-quotes to enclose the whitespaces, such that the string is not split upon multiple parameters.
EDIT
As an alternative, if you are in charge of creating and receiving the json string, you could use a more "CMD-friendly" format, for instance Base64. This way, you won't have to deal with spaces, quotes or other special characters on the command line
on the generating side:
var someobject = new {key1 = "value1", key2 = 3};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(someobject);
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
var base64 = System.Convert.ToBase64String(plainTextBytes);
// base64 will look something like
// eyJrZXkxIjogInZhbHVlMSIsICJrZXkyIjogM30=
// depending on the formatting of the serialization
then pass that base64 as parameter on your commandline.
C:\>someapp.exe eyJrZXkxIjogInZhbHVlMSIsICJrZXkyIjogM30=
And on the receiving side do
var base64 = Environment.GetCommandlineArgs()[1];
var base64EncodedBytes = System.Convert.FromBase64String(base64);
var json = System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
var someObject = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
to escape double quotation ("), use it twice. so when you pass "" to command it will received as ".
for example pass data as:
ConsoleAppTest.exe "{""lastModifiedDate"":""2020-07-13T08:06:01Z"",""model"":""softwareSystems""}"
please refer to following similar answers:
Escape double quotes in parameter

Parse Line and Break it into Variables

I have a text file that contain only the FULL version number of an application that I need to extract and then parse it into separate Variables.
For example lets say the version.cs contains 19.1.354.6
Code I'm using does not seem to be working:
char[] delimiter = { '.' };
string currentVersion = System.IO.File.ReadAllText(#"C:\Applicaion\version.cs");
string[] partsVersion;
partsVersion = currentVersion.Split(delimiter);
string majorVersion = partsVersion[0];
string minorVersion = partsVersion[1];
string buildVersion = partsVersion[2];
string revisVersion = partsVersion[3];
Altough your problem is with the file, most likely it contains other text than a version, why dont you use Version class which is absolutely for this kind of tasks.
var version = new Version("19.1.354.6");
var major = version.Major; // etc..
What you have works fine with the correct input, so I would suggest making sure there is nothing else in the file you're reading.
In the future, please provide error information, since we can't usually tell exactly what you expect to happen, only what we know should happen.
In light of that, I would also suggest looking into using Regex for parsing in the future. In my opinion, it provides a much more flexible solution for your needs. Here's an example of regex to use:
var regex = new Regex(#"([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9])");
var match = regex.Match("19.1.354.6");
if (match.Success)
{
Console.WriteLine("Match[1]: "+match.Groups[1].Value);
Console.WriteLine("Match[2]: "+match.Groups[2].Value);
Console.WriteLine("Match[3]: "+match.Groups[3].Value);
Console.WriteLine("Match[4]: "+match.Groups[4].Value);
}
else
{
Console.WriteLine("No match found");
}
which outputs the following:
// Match[1]: 19
// Match[2]: 1
// Match[3]: 354
// Match[4]: 6

Build JSON Safely

I'm running a project that is returning dynamically build JSON.
Recently I discovered that carriage returns, and double quotes the JSON string invalid (can't be loaded via an AJAX). I'm now replacing the parameter in question, removing any double quotes, and such, but I feel like I'm playing whack-a-mole.
Is there a better way?
In XML, for example, if I'm building a node, I can just call setAttribute( strMyJunkyString ), and it safely creates an attribute that will never break the XML, even if it has special characters, entities, etc.
Is there some sort of MakeStringJSONSafe() function, to remove anything that would break the array ([{}"\r\n])...
Here's a couple examples of a broken strings that my program is creating...
// String built with " included.
var t1 = [{"requestcomment":"Please complete "Education Provided" for all Medications "}];
// String built with returns embedded included.
var t2 = [{"requestcomment":"Please complete
Education Provided
History
Allergies
"}];
Use JSON.NET.
var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(new { requestcomment = "Please complete \"Education Provided\" for all Medications" });
and...
var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(new { requestcomment = "Please complete\nEducation Provided\nHistory\nAllergies" });

Splitting strings with slashes in C#

I have the following types of strings. One with three slashes and one with two:
a) filepath = "/F00C/Home/About"
b) filepath = "/Administration/Menus"
What I need to do is a function that will allow me to get the values of "home" and "administration" and put into topMenu variable and get the values of "Menus" and "About" and put this into the subMenu variable.
I am familiar with the function slashes = filePath.Split('/'); but my situation is not so simple as there are the two types of variables and in both cases I just need to get the last two words.
Is there a simple way that I could make the Split function work for both without anything to complex?
What's wrong with something like this ?
var splits = filePath.Split('/');
var secondLast = splits[splits.Length-2];
var last = splits[splits.Length-1];
Remarks:
Any check on the length of splits array (that must be >= 2) is missing.
Also, this code works only with forward-slash ('/'). To support both backslash and forward-slash separators, have a look at #Saeed's answer
Am I'm missing something or you just want:
var split = filepath.Split('/');
var last = split[split.Length -1];
var prev = split[split.Length -2];
var items = filePath.Split('/');
first = items[items.Length - 2];
second = items[items.Length - 1];
Also if this is a actual path you can use Path:
var dir = Path.GetDirectoryName(filePath);
dir = Path.GetFileName(dir);
var file = Path.GetFileName(filePath);
Edit: I edited Path version as the way discussed my digEmAll.

Categories

Resources