Post

[Blog] Custom: Embed Code-Runner (Last Update: 2025.08.29)

[Blog] Custom: Embed Code-Runner (Last Update: 2025.08.29)
  • 2025-08-08: 최초 구현
  • 2025-08-10: 중복 렌더링 버그 fix
  • 2025-08-20:
    1. Editor 코드 하이라이팅 Shiki 적용
    2. Editor 좌우 스크롤 허용
    3. Console 하이라이팅 추가
    4. code payload를 URL에서 제외하고 postMessage(init)/동일 출처 DOM Json으로 전달
  • 2025-08-29:
    1. C/C++ 다중 컴파일 지원 (proxy가 번들 처리)
    2. code runner 정규식 변경
    3. 에디터 상한 제거 및 내부 세로 스크롤 제거

Abstract

포스트 소개에 앞서, GitHub Pages 설정 및 커스텀 관련 포스트는 국내 독자와 추후 문제 해결을 위해 한글로 작성하기로 하였다.
이번 포스트에서는 블로그 내에 Embed Code-Runner를 삽입하고 사용하는 방법을 정리한다. Jekyll의 Chirpy 테마를 기준으로, 별도 컴파일/실행 과정 없이 코드 예제를 바로 실행할 수 있는 환경을 구축한다.

1. Introduction

C/C++ 포스트 등에서 코드 블럭을 작성할 때, 예제 코드를 실행하려면 복사 → 컴파일 → 실행 과정을 거쳐야 한다. 이 과정이 반복되면 불필요한 시간이 소요되고 독자 역시 직접 에디터(ex. Vscode)에 코드를 옮겨야 하는 번거로움이 있다.
이를 해소하기 위해 블로그에 Emebed Code-Runner를 추가하면 포스트 내에서 바로 코드 수정 및 실행이 가능하다. 이를 통해

  1. 포스트 내 코드 작성이 편리해지고
  2. 독자가 별도의 개발 환경을 준비할 필요가 없으며
  3. 코드 수정 후 즉시 결과를 확인할 수 있는
  4. 학습 및 데모에 최적화된 환경을 제공할 수 있다.

본 포스트에서는 OneCompilerEmbed EditorCode Executon API, Monaco Editor, Netlify를 연동하여 구현하였으며 각각 코드 실행, 코드 에디터, 호스팅을 담당한다.

2. Organization

  1. Embed Code-Runner — 기능 소개 및 사용 예제
  2. Implementation — 구성 요소 및 설정 방법
  3. Customizaton — 스타일 및 추가 옵션
  4. References — 참고 자료

3. Sections

3.1. Embed Code-Runner

render_with_liquid: 옵션을 true로 설정하고, 아래 Liquid 태그를 포스트에 삽입하면 Embed Code-Runner가 동작한다.

1
2
3
4
5
6
7
8
9
{% code_runner id="hello-1" language="cpp" %}
{% file "hello.cpp" %}
#include <iostream>
int main() {
  std::cout << "Hello, World!" << std::endl;
  return 0;
}
{% endfile %}
{% endcode_runner %}

위 코드를 적용하면, 다음과 같이 에디터와 실행 버튼이 자동으로 렌더링된다.

Click Run ▶

Embed Code-Runner의 주요 기능을 정리하면 다음과 같다.

  1. Run ▶ 버튼 클릭 시 코드 컴파일 및 실행
  2. 에디터 내 직접 편집 및 재실행
  3. 자동 높이 조절: 에디터와 콘솔 높이 동적으로 변경
  4. 스크롤 기능: 콘솔 스크롤 가능
  5. 다양한 언어 지원: C/C++, Python, Java 등 Code Execution APIs 참고
  6. C/C++ 다중 파일: {% file “…” %}{% endfile %}를 여러 개 넣으면 프록시 서버가 하나의 TU로 번들하고 #line을 주입하여 오류 위치가 원본 파일·라인으로 표시됨

추가 예제:
1) python

Click Run ▶

2) 100줄 이상 출력 테스트

Click Run ▶

3) 컴파일 에러

  • 콘솔에서 오류/경고/노트, 파일:라인(:컬럼), 캐럿이 하이라이트된다.
Click Run ▶

4) 다중 파일 (C++)

  • 파일 순서/이름은 자유, int main(이 있는 파일을 자동으로 메인으로 선택한다.
Click Run ▶

3.2. Implementation

구현은 다음 4단계로 나뉜다.

  1. Netlify Functions(proxy)
    • OneCompiler API 호출을 proxy로 중계(CORS/키 보호).
    • 서버에서 C/C++ 다중 파일을 하나의 TU로 번들하고, 각 파일 앞에 #line을 주입하여 컴파일 오류/경고의 파일 및 라인 정보를 원본 기준으로 유지.
    • ONECOMPILER_API_KEY는 Netlify 환경변수로 보관, 클라이언트에 노출 금지.
  2. HTML (iframe 문서)
    • Monaco Editor 렌더링 + 테마/스크롤바/패딩/레이아웃 제어.
    • postMessage 수신해 코드 실행 요청 처리 → Netlify 함수 호출 → 결과를 부모에 postMessage로 회신.
  3. JavaScript (부모 페이지 스크립트)
    • 임베드된 iframe과 양방향 메시징.
    • Run 버튼 클릭 → iframe에 { type: 'get-all-files' } 전송 → 최신 코드 수집 → { type: 'run' }로 프록시에 실행 의뢰.
    • runnerId로 다중 인스턴스 충돌 방지.
    • C/C++ 외 언어는 단일 파일 기준, C/C++은 다중 파일 번들(프록시).
  4. Jekyll Plugin (Liquid 태그)
    • 포스트 안에서 {% code_runner id="id" language="cpp"%} {% file "a.cpp" %} ... {% endfile %}} {% endcode_runner %} 형태로 여러 파일을 수집
    • 파일 태그는 "...", '...', 혹은 공백 없는 토큰, filename"..." 등 유연한 표기 지원
    • 빌드시 정적 치환이므로 배포가 간단하고, 포스트마다 옵션 주입 편리.

3.2.1. Netlify

  1. RapidAPI에서 One Compiler Execution API를 활성화하고 API 키를 발급받는다.
  2. Netlify 프로젝트를 GitHub repository와 연동하여 생성한다.
  3. Netlify 환경 변수(ONECOMPILER_API_KEY)로 API 키를 등록하여 배포한다.

Netlify를 이용한 proxy를 사용하는 이유는 API 키 보호와 CORS 처리, 그리고 C/C++ 번들링을 서버에서 일관되게 수행하기 위함이다. 단순 중계라 오버헤드는 크지 않다.
proxy 서버의 구현은 code-runner-proxy를 참고하라.

3.2.2. JavaScript

GitHub assets/js/code_runner.js 참조

3.2.3. Html

GitHib embed/code_runner.html 참조

1
2
3
4
# _config.yml
# 다음을 추가
include:
  - embed

3.2.4. Jekyll Plugin

GitHub _plugins/code_runner.rb 참조

3.3. Customization

3.3.1. head.html

code_runner.js 사용을 위해 head.html에서 <script src="/assets/js/dist/theme.min.js"></script> 아래 다음 script를 추가한다

1
2
3
4
5
6
  <!-- Scripts -->

  <script src="/assets/js/dist/theme.min.js"></script>
  
  <!-- Code Runner 추가 -->
  <script src="/assets/js/code_runner.js"></script> 

3.3.2. CSS

GitHub _sass/_code-runner.scss 참조

생성한 css를 main.scss에 추가해주면 Embed Code-Runner가 적용된다.

1
2
3
4
5
6
// main.scss
@forward 'base';
@forward 'components';
@forward 'layout';
@forward 'pages';
@forward "code-runner"; // 추가

3.4. References

  1. OneCompiler
  2. Monaco Editor를 활용해서 React 기반 프로젝트에 코드 에디터 적용하기!
  3. Monaco Editor
  4. Netlify
  5. Shiki
This post is licensed under CC BY 4.0 by the author.