Create and share images of your source code
carbon.now.sh
carbon.now.sh
[0] Coinbase : https://news.ycombinator.com/item?id=26816636
I just quickly created a text-based SVG image in Inkscape, and it was a few KB in size and the text was all selectable. I couldn't even open the Carbon SVG export in Inkscape, so I'm not sure what it's doing?
The uncompressed 1.1MB export isn't optimized for size since it repeats basically the same CSS styles over and over for every token. When gzipped (default level) it's 302KB, and when brotli'ed it's 290KB, basically the font takes all the space.
Of course, technically it's possible to optimize the size by creating a custom font with only the glyphs needed, like what people used to do for icon fonts.
If "it is code, not an art project" to you, the only thing I can say is you're not the target audience.
Basically if you have tutorials that need code screenshots it's nice to avoid much / most manual copy/paste/screen capture etc.
So my script takes a filename and line numbers and outputs a syntax highlighted screenshot of that portion of text.
Why arn't I linking to the script? Well the obvious next step is to extend the above to tie into git such that for minor changes you don't have to think about the line numbers and it just does the right thing. But I never got that working :)
https://www.marclittlemore.com/create-pretty-code-screenshot...
If you use VS Code, there are some decent plugins you can use like Polacode. I also like Screely for turning screenshots into browser mockups too.
It's already maxed out.
cmd + shift + f4Ctrl-V
> This is the recommended method for sharing Carbon on your own website or blog. Readers can even copy the code with the click of a button.
Snipping tool can't do that
There's one, can you copy text from an SVG image posted on twitter or do they convert it to PNG themselves?
I think that would be a cool project, if it doesn't already exist: crawl github, gitlab, bitbucket, sourceforge, etc -- and report project name collisions.
That's why a friend and me released a similar product available at snappify.io, maybe someone finds it interesting!
I do this with cmd+shift+4 and it's already on my clipboard for easy pasting into chat or whatever. Plus the line numbers are correct and the highlighting matches my editor.
This could be useful for my project.
What is the best way to import this into wordpress? Is there a to have it as a custom wordpress block?
The only issue I can think of is any usage restrictions on the font.
IANAL.
That being said Carbon does allow you to add watermark to them. I wonder how many actually use that watermark.
I suppose you do need a tool like this when you have code like that.
It's optimised to be terse rather than easily readable, which makes it poor code in my book.
I'd love to see your "easily readable" implementation of both those functions, if you have that at hand, with the same features as the ones in the example. My guess is that your implementation will look more or less the same.
For reference (in case the website changes), this is the code we're talking about:
const pluckDeep = key => obj => key.split('.').reduce((accum, key) => accum[key], obj)
const compose = (...fns) => res => fns.reduce((accum, next) => next(accum), res)
const unfold = (f, seed) => {
const go = (f, seed, acc) => {
const res = f(seed)
return res ? go(f, res[1], acc.concat([res[0]])) : acc
}
return go(f, seed, [])
}You should write comments anyway, of course, but you shouldn't also punish the reader by forcing them to break out a notebook and/or reformat the code just to make it make sense. The alternating `=` and `=>` is ugly and unnecessarily difficult to follow visually. And the lines in the first two functions are too long, like writing a long forum post in one big paragraph.
Here's what I'd rather see, leaving out the mandatory JSDoc comments (caveat: JS is not my main language):
const getPropPath = (keyPath) =>
(obj) => {
return keyPath.split('.').reduce(
(prevResult, nextKey) => prevResult[nextKey],
obj,
)
}
const compose = (...funcs) =>
(x) => {
return funcs.reduce(
(prevResult, nextFunc) => nextFunc(prevResult),
x,
)
}
const unfold = (func, startArg) => {
const unfoldAux = (func, currArg, accum) => {
const result = func(currArg)
if (result) {
const nextArg = result[1]
const nextAccum = accum.concat([result[0]])
return unfoldAux(func, nextArg, nextAccum)
} else {
return accum
}
}
return unfoldAux(func, startArg, [])
}
Note especially how the mostly-identical structures of the first two functions is now visually obvious, whereas before it was obfuscated. Yes, it has more words than before, but it also limits the syntax to one `=>` per line and breaks up the needlessly dense use of the conditional operator in `unfold`. It's less visually noisy specifically because we added structure.The original version might feel elegant and efficient to some people, but to me they look like someone else's shorthand scribbles. If I am writing something for other people to read, I am going to take the time to structure it for the benefit of the reader.
That said, I don't think I've ever needed a function like `unfold` (state machine? parsing?) in a Javascript program, so I'd place extra priority on making sure the doc comment explained what it's used for, ideally with a self-contained and easy-to-understand example.
You could also rewrite `unfoldAux` to remove the explicit `func` parameter and get it from the enclosing scope; that would be fine too IMO. That's a matter of taste, depending on how much you like closures.
"But wait! It would be just as terse in any real functional programming language! You're just a bad functional programmer!"
Yeah, I probably am a bad functional programmer. But here's how I'd write `unfold` in OCaml:
let unfold func start_value =
let rec unfold_aux func curr_arg accumulator =
match func curr_arg with
| None -> accumulator
| Some (result, next_arg) -> unfold_aux func next_arg (accumulator @ [result])
in unfold_aux func start_value []
Obviously this is inefficient because `@` requires a linear scan over the data, so maybe it should be written with cons-and-reverse.But I'd argue that the OCaml version has more or less the same structure and syntactical clarity as the Javascript version, but with the ability to take advantage of pattern matching (and taking a bit of liberty in narrowing down the opaquely truthy-or-not return value to a `None`).
As a bonus, here's a Python implementation, which uses the new structural pattern matching and looks quite a bit like the OCaml version:
def unfold(func, start_value):
def unfold_aux(func, curr_arg, accumulator):
match func(curr_arg):
case None:
return accumulator
case (result, next_arg):
return unfold_aux(func, next_arg, accumulator + [result])
return unfold_aux(func, start_value, [])
Of course, in Python nowadays I'd encourage adding type annotations, but that's another story.> impossible to display nicely styled code as text
E.g. sharing snippets on Twitter, on blogging platforms that don't properly support code, in preview images for social media... Kind of a niche problem, but one that gets disproportionate visible attention because the people who produce lots of content about coding are the ones that have the most need for it. (Similar like how many programmers blogs have a good chunk about content about how they implemented their blog ;))
Apart from the screenshot module, codekeep allows you to store and share code snippets, most of the ui is inspired from google keep and i have added more features on top of that, we named it codekeep (google keep for code snippets).
do checkout and let us know your thought :-) https://codekeep.io/screenshot