본문에서는 Rails 애플리케이션에 구문 강조를 적용하는 다양한 접근 방식을 단계별로 설명합니다. 먼저 공통적인 애플리케이션 설정부터 시작하여 각 라이브러리의 특징과 구현 방법을 상세히 다룹니다.
애플리케이션 설정
새로운 Rails 애플리케이션을 생성하고 Post 스캐폴드를 추가합니다. 마크다운 파싱을 위해 commonmarker, redcarpet, kramdown gem을 설치하고, Marksmith Editor를 사용하여 초기 마크다운 콘텐츠 입력을 준비합니다.
Commonmarker Gem 활용
Commonmarker는 구문 강조 스타일을 인라인으로 추가하여 별도의 라이브러리 없이 손쉽게 기능을 구현할 수 있습니다. Post 모델에 formatted_content 메서드를 정의하여 Commonmarker.to_html을 사용하고, syntax_highlighter 플러그인의 theme 옵션을 설정합니다. 기본 제공 테마 외에도 .tmtheme 형식의 사용자 정의 테마 경로를 지정하여 적용할 수 있습니다.
ruby
class Post < ApplicationRecord
def formatted_content
Commonmarker.to_html(content, plugins: { syntax_highlighter: { theme: "ayu-dark", path: Rails.root.join("app", "assets", "themes").to_s } })
end
end
Redcarpet 및 Rouge 활용
Redcarpet과 Rouge는 Rails 개발자들이 구문 강조를 위해 가장 흔히 사용하는 조합입니다. rouge gem을 설치한 후, Redcarpet::Render::HTML을 상속받는 HtmlRenderer 클래스를 생성하고 Rouge::Plugins::Redcarpet 모듈을 포함시킵니다. 이 커스텀 렌더러를 Redcarpet::Markdown에 전달하여 마크다운을 HTML로 변환합니다. Rouge 테마는 <style> 태그 내에 직접 렌더링하거나, rougify 스크립트를 통해 CSS 파일을 생성하여 애플리케이션 레이아웃에 포함할 수 있습니다.
```ruby # app/models/html_renderer.rb require ‘redcarpet’ require ‘rouge’ require ‘rouge/plugins/redcarpet’ class HtmlRenderer < Redcarpet::Render::HTML include Rouge::Plugins::Redcarpet end
Post 모델
class Post < ApplicationRecord def formatted_content Redcarpet::Markdown.new(HtmlRenderer, { fenced_code_blocks: true }).render(content) end end ```
Highlight.js 활용 (프런트엔드)
Highlight.js는 가장 인기 있는 프런트엔드 구문 강조 라이브러리입니다. 마크다운 콘텐츠를 먼저 구문 강조 없이 HTML로 파싱한 후(예: Commonmarker.to_html 사용), Highlight.js를 클라이언트 측에서 실행하여 코드 블록에 구문 강조를 적용합니다. highlight.js를 설치하고 app/javascript/syntax_highlight.js 파일에 초기 설정 및 필요한 언어만 임포트하여 번들 크기를 최적화합니다. CSS 테마는 application.tailwind.css에 @import 하거나, 특정 뷰에서만 javascript_include_tag를 사용하여 로드할 수 있습니다.
Rhino Editor 활용
Rhino Editor는 Action Text와 호환되는 WYSIWYG 에디터로, TipTap 에디터와 Highlight.js를 내부적으로 사용합니다. Action Text 및 Active Storage를 설치하고 Post 모델에 has_rich_text :body를 추가합니다. Rhino Editor를 설치한 후, lowlight 확장 기능을 사용하여 에디터 내에서 실시간 구문 강조를 구현할 수 있습니다. rhino-before-initialize 이벤트 리스너를 통해 starterKitOptions를 확장하고 CodeBlockLowlight를 구성하여 이 기능을 활성화합니다. 최종 게시물에서는 이전에 설정한 Highlight.js가 자동으로 구문 강조를 처리합니다.
적절한 접근 방식 선택
-
서버 측 파싱 (Commonmarker, Redcarpet+Rouge): 대부분의 경우 적합하며, 번들 크기 증가나 하이라이팅 깜빡임이 없습니다. 더 많은 언어를 지원합니다.
-
프런트엔드 라이브러리 (Highlight.js): 실시간 강조가 필요하거나, 혼합된 프런트엔드 환경, 다양한 테마 선택(512개)이 중요할 때 유용합니다. 단, 번들 크기 증가와 초기 로딩 시 깜빡임이 발생할 수 있습니다.