Posted in:

One of the motivations for moving my blog to Markdown was to stop relying on Windows Live Writer which is no longer supported and has a number of bugs. But one thing it was convenient for was pasting images into posts. I could just use the Windows clipping tool and paste the image directly into a post. In Markdown, I need to save the image to a file, and to generate some markup to refer to that file.

For small automated tasks like this, my goto tool is the amazing LINQPad. I have hundreds of scripts in there for doing all kinds of useful things.

Generating a File Name

First of all, my script needs to work out where to save the image on the clipboard to. This depends what computer I'm running on as my GitHub repository is cloned to different paths. Here's a quick and dirty LINQ trick to pick the correct folder whichever computer I'm on:

var path = new[] { @"C:\Users\markh\code\web\markblog\wwwroot\posts\2018",
@"C:\code\soundcode\MarkBlog\wwwroot\posts\2018" }.First(p => Directory.Exists(p));

Next, I need to generate a filename. I use the "slug" of the post as a prefix, plus an incrementing number. Again, I use a quick bit of LINQ to find the first suffix that hasn't been used.

var prefix = "css-social-media-icon-list";
var fileName = Enumerable.Range(1,100)
                .Select(n => Path.Combine(path,$"{prefix}-{n}.png"))
                .First(p => !File.Exists(p));

Saving images from the clipboard

Now we know where we want to save the image to, we can use the System.Windows.Forms.Clipboard class to access the image and save it to a PNG file. Don't be put off by "Windows Forms" in the name - this class is the easiest way to access the clipboard and can be used from a console or WPF app if you want.

I also update the contents of the clipboard with the Markdown I want to paste into my blog post. So now all I need to do after using the Windows clip tool to take a screenshot is run this script and then paste the Markdown in my text editor.

if(Clipboard.ContainsImage())
{
    Clipboard.GetImage().Save(fileName, ImageFormat.Png);
    Clipboard.SetText($"![image](/posts/2018/{Path.GetFileName(fileName)})");
}

Taking it further?

So I've got pasting an image into my markdown posts almost to as easy as it was with Windows Live Writer, but the next step would be to incorporate a similar process into Visual Studio Code which I use as my editor. I think this could be turned into a Visual Studio Code extension, but I suspect that means a rewrite in node.js and learning how VS Code extensions work. If I manage it I'll post about how I did it.

But hopefully this is useful for anyone who needs clipboard access in C#, and also gives you some ideas of how LINQPad scripts can be used to automate manual tasks.

Want to learn more about LINQ? Be sure to check out my Pluralsight course LINQ Best Practices.

Comments

Comment by Paul

I'm the same, use LinqPad for all kinds of scripting tasks, it's the best!

Paul
Comment by LiZeC

Wow, this code solves exactly the problem I want to solve. amazing.

LiZeC