[Blog] Custom: Embed Code-Runner (Last Update: 2025.08.29)
- 2025-08-08: 최초 구현
- 2025-08-10: 중복 렌더링 버그 fix
- 2025-08-20:
- Editor 코드 하이라이팅 Shiki 적용
- Editor 좌우 스크롤 허용
- Console 하이라이팅 추가
- code payload를 URL에서 제외하고 postMessage(init)/동일 출처 DOM Json으로 전달
- 2025-08-29:
- C/C++ 다중 컴파일 지원 (proxy가 번들 처리)
- code runner 정규식 변경
- 에디터 상한 제거 및 내부 세로 스크롤 제거
Abstract
포스트 소개에 앞서, GitHub Pages 설정 및 커스텀 관련 포스트는 국내 독자와 추후 문제 해결을 위해 한글로 작성하기로 하였다.
이번 포스트에서는 블로그 내에 Embed Code-Runner를 삽입하고 사용하는 방법을 정리한다. Jekyll의 Chirpy 테마를 기준으로, 별도 컴파일/실행 과정 없이 코드 예제를 바로 실행할 수 있는 환경을 구축한다.
1. Introduction
C/C++ 포스트 등에서 코드 블럭을 작성할 때, 예제 코드를 실행하려면 복사 → 컴파일 → 실행 과정을 거쳐야 한다. 이 과정이 반복되면 불필요한 시간이 소요되고 독자 역시 직접 에디터(ex. Vscode)에 코드를 옮겨야 하는 번거로움이 있다.
이를 해소하기 위해 블로그에 Emebed Code-Runner를 추가하면 포스트 내에서 바로 코드 수정 및 실행이 가능하다. 이를 통해
- 포스트 내 코드 작성이 편리해지고
- 독자가 별도의 개발 환경을 준비할 필요가 없으며
- 코드 수정 후 즉시 결과를 확인할 수 있는
- 학습 및 데모에 최적화된 환경을 제공할 수 있다.
본 포스트에서는 OneCompiler의 Embed Editor와 Code Executon API, Monaco Editor, Netlify를 연동하여 구현하였으며 각각 코드 실행, 코드 에디터, 호스팅을 담당한다.
2. Organization
- Embed Code-Runner — 기능 소개 및 사용 예제
- Implementation — 구성 요소 및 설정 방법
- Customizaton — 스타일 및 추가 옵션
- 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의 주요 기능을 정리하면 다음과 같다.
- Run ▶ 버튼 클릭 시 코드 컴파일 및 실행
- 에디터 내 직접 편집 및 재실행
- 자동 높이 조절: 에디터와 콘솔 높이 동적으로 변경
- 스크롤 기능: 콘솔 스크롤 가능
- 다양한 언어 지원: C/C++, Python, Java 등 Code Execution APIs 참고
- 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단계로 나뉜다.
- Netlify Functions(proxy)
- OneCompiler API 호출을 proxy로 중계(CORS/키 보호).
- 서버에서 C/C++ 다중 파일을 하나의 TU로 번들하고, 각 파일 앞에
#line을 주입하여 컴파일 오류/경고의 파일 및 라인 정보를 원본 기준으로 유지. - ONECOMPILER_API_KEY는 Netlify 환경변수로 보관, 클라이언트에 노출 금지.
- HTML (iframe 문서)
- Monaco Editor 렌더링 + 테마/스크롤바/패딩/레이아웃 제어.
- postMessage 수신해 코드 실행 요청 처리 → Netlify 함수 호출 → 결과를 부모에 postMessage로 회신.
- JavaScript (부모 페이지 스크립트)
- 임베드된 iframe과 양방향 메시징.
- Run 버튼 클릭 → iframe에
{ type: 'get-all-files' }전송 → 최신 코드 수집 →{ type: 'run' }로 프록시에 실행 의뢰. - runnerId로 다중 인스턴스 충돌 방지.
- C/C++ 외 언어는 단일 파일 기준, C/C++은 다중 파일 번들(프록시).
- Jekyll Plugin (Liquid 태그)
- 포스트 안에서
{% code_runner id="id" language="cpp"%} {% file "a.cpp" %} ... {% endfile %}} {% endcode_runner %}형태로 여러 파일을 수집 - 파일 태그는
"...",'...', 혹은 공백 없는 토큰,filename"..."등 유연한 표기 지원 - 빌드시 정적 치환이므로 배포가 간단하고, 포스트마다 옵션 주입 편리.
- 포스트 안에서
3.2.1. Netlify
- RapidAPI에서 One Compiler Execution API를 활성화하고 API 키를 발급받는다.
- Netlify 프로젝트를 GitHub repository와 연동하여 생성한다.
- 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"; // 추가