joshdholtz / DeckUI

Swift DSL for writing slide decks in Xcode
MIT License
601 stars 27 forks source link

Syntax highlighting for code #8

Closed yonomitt closed 1 year ago

yonomitt commented 1 year ago

I was looking at the CodeView and what it would take to do syntax highlighting for code. I think we could utilize parts of John Sundell's Splash repo. It takes Swift code and converts it to HTML, but in the process it tokenizes the code.

If we tap into this tokenization, we could use it to drive the syntax highlighting in DeckUI. I see two options for this:

  1. AttributedString within a Text view
  2. Iterate over the tokenized code and create a Text for each token with proper highlighting based on the token.

I think option number 2 should be easier.

The other nice thing about the Splash-style tokenization is that it's pretty easy to add grammar for other programming languages. For my blog, I'm currently creating one for Python, which then could also be used in DeckUI.

yonomitt commented 1 year ago

I could work on this next, if no one has strong feelings that it should be done another way.

Is there an opinion on pulling in all of Splash as a dependency vs just copying in the parts that are needed? The benefit of depending on the repo directly is getting updates as the rules get improved. The downside is there are several useful internal functions that can't be used when creating custom grammars for other languages.

yonomitt commented 1 year ago

I have a working prototype:

Screen Shot 2022-09-12 at 18 14 40

But I'm a bit unhappy with the API:

Code("""
struct CounterView: View {
    @State var count = 0

    var body: some View {
        Button {
            self.count += 1
        } label: {
            Text("Press me - \\(self.count)")
                .font(.system(size: 60))
                .padding(.horizontal, 40)
                .padding(.vertical, 20)
                .foregroundColor(.white)
                .overlay(
                    RoundedRectangle(cornerRadius: 25)
                    .stroke(Color.white, lineWidth: 2)
                )
        }.buttonStyle(.plain)
    }
}
""", language: .swift)

It feels like the language should come first, otherwise it's kind of lost? Thoughts?

DanielSincere commented 1 year ago

"It feels like the language should come first, otherwise it's kind of lost?" I agree! It could look like this?

Code(.swift, """
print("hello world")
""")
yonomitt commented 1 year ago

I think I like that... let me update my PR

joshdholtz commented 1 year ago

Closing because this is now complete 🙌