How can I find what line number in the source file the declaration was found on?
Disclaimer: I work for Microsoft on the Roslyn team.
You can use the ISyntaxTree.GetLineSpan() method to convert to a line number. For example, given an ISymbol "symbol", you can get the start location of the first definition with:
var loc = symbol.Locations.First();
var lineSpan = loc.SourceTree.GetLineSpan(loc.SourceSpan,
usePreprocessorDirectives: false);
var line = lineSpan.StartLinePosition.Line;
var character = lineSpan.StartLinePosition.Character;
From the title, it looks like you're starting with a SyntaxNode, so you can just use the Span property directly.
Related
I have the below code which is for modifying a textframe in a word document at runtime.
This is in a .NET Windows Forms app.
var oShapes = oWord.ActiveDocument.Shapes;
var titleShape = oShapes["Title"];
var myWord = new Microsoft.Office.Interop.Word.Application();
titleShape.Height = myWord.InchesToPoints(1.75F);
titleShape.Width = myWord.InchesToPoints(0.45F);
titleShape.RelativeHorizontalPosition = Microsoft.Office.Interop.Word.WdRelativeHorizontalPosition;
titleShape.RelativeVerticalPosition = Microsoft.Office.Interop.Word.WdRelativeVerticalPosition();
titleShape.Left = 4.35F;
titleShape.Top = 17.5F;
titleShape.TextFrame.WordWrap = 0;
titleShape.LockAnchor = 1;
var sTitle =string.Empty;
titleShape.TextFrame.TextRange.Text = DocumentType; // sTitle;
titleShape.TextFrame.AutoSize=-1;
Unfortunately I must have got it wrong because Microsoft.Office.Interop.Word.WdRelativeHorizontalPosition; is showing as an error in VS 2010 (and also on the line below.
What is the correct way to use word enumerated constants like that in c# through Office Interop?
remove the parentheses:
titleShape.RelativeVerticalPosition = Microsoft.Office.Interop.Word.WdRelativeVerticalPosition;
you also don't say what the compilation error is.
The problem is that you are calling the property as if it was a method. Remove the paranthesis at the end and you should be done.
titleShape.RelativeVerticalPosition = Microsoft.Office.Interop.Word.WdRelativeVerticalPosition;
Hope this helps.
I found it, I was calling the enumeration name, rather than the enumerated constant.
So Microsoft.Office.Interop.Word.WdRelativeHorizontalPosition
should be
Microsoft.Office.Interop.Word.WdRelativeHorizontalPosition.wdRelativeHorizontalPositionPage;
(plus I was using brackets thinking that was the problem)
How to solve this?
What i want to change this :
C:\files\team\business\dev\Source\systems\extension\destination\1.0.1.1\
to new value:
value = "1.0.11";
You could just get the Name of the corresponding DirectoryInfo:
string path = #"C:\files\team\business\dev\Source\systems\extension\destination\1.0.1.1\";
string version = new DirectoryInfo(path).Name;
Alternative method:
var path = #"C:\files\team\business\dev\Source\systems\extension\destination\1.0.1.1\";
var value = Path.GetFileName(path.TrimEnd(new[]{'/','\\'}));
// OUTPUT: 1.0.1.1
This basically removes any last directory delimeters and then treats the last directory as a filename, so it returns the last directory.
Based on #JeppeStigNielsen's comments below, here's a better, platform independent alternative.
var value = Path.GetFileName(Path.GetDirectoryName(path));
This will work if there is a file name present as well.
var value = Path.GetFileName(Path.GetDirectoryName(".../1.0.1.1/somefile.etc"));
// returns 1.0.1.1
Darin's answer is great but as an alternative;
string s = #"C:\files\team\business\dev\Source\systems\extension\destination\1.0.1.1\";
string[] array = s.Split('\\');
Console.WriteLine(array[array.Length - 2]);
Output will be;
1.0.1.1
Here a DEMO.
I am currently trying to extract the ID of a YouTube video from the embed url YouTube supplies.
I am currently using this as an example:
<iframe width="560" height="315" src="http://www.youtube.com/embed/aSVpBqOsC7o" frameborder="0" allowfullscreen></iframe>
So far my code currently looks like this,
else if (TB_VideoLink.Text.Trim().Contains("http://www.youtube.com/embed/"))
{
youtube_url = TB_VideoLink.Text.Trim();
int Count = youtube_url.IndexOf("/embed/", 7);
string cutid = youtube_url.Substring(Count,youtube_url.IndexOf("\" frameborder"));
LB_VideoCodeLink.Text = cutid;
}
I Seem to be getting there, however the code falls over on CutID and I am not sure why???
Cheers
I always find it much easier to use regular expressions for this sort of thing, Substringand IndexOf always seem dated to me, but that's just my personal opinion.
Here is how I would solve this problem.
Regex regexPattern = new Regex(#"src=\""\S+/embed/(?<videoId>\w+)");
Match videoIdMatch = regexPattern.Match(TB_VideoLink.Text);
if (videoIdMatch.Success)
{
LB_VideoCodeLink.Text = videoIdMatch.Groups["videoId"].Value;
}
This will perform a regular expression match, locating src=", ignoring all characters up until /embed/ then extracting all the word characters after it as a named group.
You can then get the value of this named group. The advantage is, this will work even if frameborder does not occur directly after the src.
Hope this is useful,
Luke
The second parameter of the Substring method is length, not second index. Subtract the index of the second test from the first to get the required length.
else if (TB_VideoLink.Text.Trim().Contains("http://www.youtube.com/embed/"))
{
youtube_url = TB_VideoLink.Text.Trim();
// Find the start of the embed code
int Count = youtube_url.IndexOf("/embed/", 7);
// From the start of the embed bit, search for the next "
int endIndex = youtube_url.IndexOf("\"", Count);
// The ID is from the 'Count' variable, for the next (endIndex-Count) characters
string cutid = youtube_url.Substring(Count, endIndex - Count);
LB_VideoCodeLink.Text = cutid;
}
You probably should have some more exception handling for when either of the two test strings do not exist.
Similar to answer above, but was beaten to it.. doh
//Regex with YouTube Url and Group () any Word character a-z0-9 and expect 1 or more characters +
var youTubeIdRegex = new Regex(#"http://www.youtube.com/embed/(?<videoId>\w+)",RegexOptions.IgnoreCase|RegexOptions.Compiled);
var youTubeUrl = TB_VideoLink.Text.Trim();
var match = youTubeIdRegex.Match(youTubeUrl);
var youTubeId = match.Groups["videoId"].Value; //Group[1] is (\w+) -- first group ()
LB_VideoCodeLink.Text = youTubeId;
I am looking at http://code.google.com/p/google-diff-match-patch/ and have downloaded the file. When I look at it is 2 files
DiffMatchPatch.cs
DiffMatchPatchTest.cs
When I try to make a new object of DiffMatchPatch.cs I have to pass in some operation and string text.
http://neil.fraser.name/software/diff_match_patch/svn/trunk/demos/demo_diff.html
In the demo they cross out the words that are different and that is what I am trying to achieve.
I am trying to compare 2 blocks of text on the server side finds the differences and send a email to the user with the file block of text to them like the end result is in the demo that I posted above.
So does anyone have a tutorial on how to use the C# version?
For reference, this is really easy:
var dmp = new diff_match_patch();
var diffs = dmp.diff_main(text1, text2);
var html = dmp.diff_prettyHtml(diffs);
Implementation with current version(2.1.0) would look like this
var dmp = DiffMatchPatchModule.Default;
var diffs = dmp.DiffMain(text1, text2);
var html = dmp.DiffPrettyHtml(diffs);
For anyone who came across this thread because of the title and expected an explanation on how to use the Google Diff-Match-Patch algorithm via the https://github.com/pocketberserker/Diff.Match.Patch library found on NuGet, to create a diff string, so he can send the change somewhere (e.g. via websocket) and restore it at the destination based on the old value and the diff string, that would work like this:
var oldValue = "Test old text.";
var newValue = "Test new text.";
// create diff string
var dmp = DiffMatchPatch.DiffMatchPatchModule.Default;
var diffs = dmp.DiffMain(oldValue, newValue);
var srcDelta = dmp.DiffToDelta(diffs);
// restore from diff
var dmp = DiffMatchPatch.DiffMatchPatchModule.Default;
var dstDelta = dmp.DiffFromDelta(oldValue, srcDelta);
var restoredNewValue = dmp.DiffText2(dstDelta);
I guess I need some regex help. I want to find all tags like <?abc?> so that I can replace it with whatever the results are for the code ran inside. I just need help regexing the tag/code string, not parsing the code inside :p.
<b><?abc print 'test' ?></b> would result in <b>test</b>
Edit: Not specifically but in general, matching (<?[chars] (code group) ?>)
This will build up a new copy of the string source, replacing <?abc code?> with the result of process(code)
Regex abcTagRegex = new Regex(#"\<\?abc(?<code>.*?)\?>");
StringBuilder newSource = new StringBuilder();
int curPos = 0;
foreach (Match abcTagMatch in abcTagRegex.Matches(source)) {
string code = abcTagMatch.Groups["code"].Value;
string result = process(code);
newSource.Append(source.Substring(curPos, abcTagMatch.Index));
newSource.Append(result);
curPos = abcTagMatch.Index + abcTagMatch.Length;
}
newSource.Append(source.Substring(curPos));
source = newSource.ToString();
N.B. I've not been able to test this code, so some of the functions may be slightly the wrong name, or there may be some off-by-one errors.
var new Regex(#"<\?(\w+) (\w+) (.+?)\?>")
This will take this source
<b><?abc print 'test' ?></b>
and break it up like this:
Value: <?abc print 'test' ?>
SubMatch: abc
SubMatch: print
SubMatch: 'test'
These can then be sent to a method that can handle it differently depending on what the parts are.
If you need more advanced syntax handling you need to go beyond regex I believe.
I designed a template engine using Antlr but thats way more complex ;)
exp = new Regex(#"<\?abc print'(.+)' \?>");
str = exp.Replace(str, "$1")
Something like this should do the trick. Change the regexes how you see fit