Skip to content

Chapter 7: Syntax Highlighting

← Previous: Quick Actions System

Have you ever read a book where all the text was the same color and size? It can be hard to understand what's important. Now, imagine if important phrases were highlighted in red, character names were in blue, and scene settings were in green. That would be much easier to read, right?

This is exactly what Syntax Highlighting does for our code in the Local Gist Manager application!

The Problem: Plain Text is Hard to Read

Let's say you're looking at this JavaScript code without any highlighting:

function calculateTotal(items) {
  let total = 0;
  for (const item of items) {
    total += item.price * (1 - item.discount);
  }
  return total;
}

It's not terrible, but everything blends together. Now compare it to the same code with syntax highlighting:

Code with syntax highlighting

Much better! The keywords, variables, and strings are all different colors, making it easier to understand the code structure at a glance.

What is Syntax Highlighting?

Syntax highlighting is like a smart coloring system for your code. It:

  1. Identifies different parts of your code (keywords, variables, strings, etc.)
  2. Applies specific colors to each part
  3. Makes your code more readable and easier to understand

In our Local Gist Manager, this is crucial because we're all about viewing and editing code snippets!

Meet the SyntaxHighlighter Component

The heart of our syntax highlighting system is the CodeSyntaxHighlighter component:

import { Prism as PrismSyntaxHighlighter } from "react-syntax-highlighter";
import { oneLight } from "react-syntax-highlighter/dist/esm/styles/prism";

This code imports two critical tools: 1. PrismSyntaxHighlighter: A library that handles all the hard work of syntax highlighting 2. oneLight: A light color theme for our highlighted code

Using the Syntax Highlighter

Using our syntax highlighting component is super easy:

<CodeSyntaxHighlighter
  content="const greeting = 'Hello, world!';"
  language="javascript"
/>

Just provide: 1. The content you want to highlight (your code) 2. The language of that code (like "javascript", "python", etc.)

And the component automatically displays beautifully highlighted code!

How Our Component Detects Languages

Sometimes we don't know what programming language a file contains. Our component is smart enough to figure it out based on the filename:

const getLanguage = (lang?: string, filename?: string) => {
  if (!lang && filename) {
    if (filename.endsWith('.ts')) return 'typescript';
    if (filename.endsWith('.js')) return 'javascript';
    if (filename.endsWith('.py')) return 'python';
    // More language mappings...
  }
  // Default fallback
  return lang || 'markdown';
};

This function: 1. Checks if we already know the language 2. If not, it looks at the file extension (.js, .py, etc.) 3. Returns the appropriate language identifier 4. Falls back to 'markdown' if it can't determine the language

Let's See How It Works Behind the Scenes

When you use the syntax highlighter to display a code snippet in our app, here's what happens step by step:

sequenceDiagram participant UI as User Interface participant SH as SyntaxHighlighter participant PL as Prism Library participant ST as Syntax Theme participant DOM as Browser DOM UI->>SH: Render with code & language SH->>PL: Process code with language PL->>PL: Tokenize code elements PL->>ST: Get colors for tokens PL->>SH: Return colored tokens SH->>DOM: Render highlighted code DOM->>UI: Display to user

Let's break down this process:

  1. Your gist content is passed to the CodeSyntaxHighlighter component
  2. The component passes this code to the Prism library along with the language
  3. Prism breaks your code into "tokens" (keywords, strings, variables, etc.)
  4. Each token gets assigned a color based on the selected theme
  5. The highlighted code is rendered to the screen

Making the Highlighting Look Nice

We want our syntax highlighting to look consistent with our application's design. Here's how we customize the appearance:

const customStyle = {
  ...oneLight,
  'pre[class*="language-"]': {
    ...oneLight['pre[class*="language-"]'],
    background: "#fafafa",
    margin: 0,
    padding: "1rem",
    fontSize: "0.875rem",
  },
  // More styling...
};

This code: 1. Starts with the base oneLight theme 2. Overrides specific styles to match our application's look and feel 3. Controls things like background color, padding, and font size

Seeing It All Together: The Complete Component

Here's a simplified version of our complete CodeSyntaxHighlighter component:

const CodeSyntaxHighlighter = ({ content, language, filename }) => {
  // Determine the language based on filename or provided language
  const detectedLanguage = getLanguage(language, filename);

  return (
    <div className="syntax-highlighter">
      <PrismSyntaxHighlighter
        language={detectedLanguage}
        style={customStyle}
        showLineNumbers={content.split("\n").length > 5}
      >
        {content}
      </PrismSyntaxHighlighter>
    </div>
  );
};

This component: 1. Takes the code content, language, and optional filename 2. Determines the correct language for highlighting 3. Applies our custom styling 4. Shows line numbers if the code is longer than 5 lines 5. Returns the beautifully highlighted code

Interactive Features

Our syntax highlighter isn't just pretty—it's also interactive! We've added features to make editing easier:

<div 
  onClick={onClick}
  className={`relative group ${className || ''}`}
  title={onClick ? "Click to edit" : undefined}
>
  {/* Highlighting component here */}
</div>

This wrapper allows users to: 1. Click on code to edit it 2. See a helpful tooltip explaining they can click to edit 3. Interact with the code in a natural way

Making It Work with Different File Types

Our application handles many different types of files and programming languages. Here's a small sample of the languages we support:

  • JavaScript/TypeScript
  • Python
  • HTML/CSS
  • JSON
  • Markdown
  • Ruby
  • And many more!

This makes Local Gist Manager extremely versatile for developers who work with different technologies.

Handling Special Cases

Sometimes code has special requirements for display. We handle those too:

<PrismSyntaxHighlighter
  language={language}
  style={customStyle}
  showLineNumbers={content.split("\n").length > 5}
  wrapLines={true}
  // More options...
>
  {content}
</PrismSyntaxHighlighter>

These special features include: 1. Smart line number display (only for longer code blocks) 2. Line wrapping for long lines of code 3. Custom font families for better readability

How the Highlighting Integrates with the Rest of the App

The syntax highlighter is used throughout our application, most prominently in the GistItem component:

// Inside GistItem.tsx
<CodeSyntaxHighlighter
  content={file.content || ""}
  language={file.language}
  onClick={() => handleEditContent(file.filename, file.content || "")}
  className="cursor-pointer hover:bg-slate-50"
  filename={file.filename}
/>

This integration: 1. Shows the content of each file with appropriate highlighting 2. Makes the code block clickable for editing 3. Adds visual feedback when hovering over the code 4. Uses the filename to help determine the language

Benefits of Syntax Highlighting

Our syntax highlighting provides several key benefits:

  1. Readability: Code is much easier to understand at a glance
  2. Error spotting: Syntax errors often stand out visually
  3. Structure recognition: The structure of code becomes obvious
  4. Professional appearance: Your gists look polished and professional
  5. Learning aid: Great for beginners who are learning programming

Real-World Example: Working with Multiple Languages

Let's say you have a gist with three files: 1. A JavaScript file (app.js) 2. A CSS file (style.css) 3. An HTML file (index.html)

Our syntax highlighter will automatically apply the appropriate highlighting to each:

  • JavaScript keywords like const, function, and return might be blue
  • CSS properties might be green, values might be purple
  • HTML tags might be red, attributes might be orange

All of this happens automatically without you having to specify anything!

Conclusion

Syntax highlighting is a seemingly small feature that makes a huge difference in how we interact with code. It transforms plain, monotonous text into a colorful, structured representation that's easier to read, understand, and edit.

In the Local Gist Manager, syntax highlighting is essential for providing a great user experience. It helps you quickly understand the code you're looking at and makes your gists look professional and polished.

Now that you understand how we make your code look beautiful, let's move on to learn about our Styling System and how we create a cohesive visual experience throughout the application.