2009-03-03 4 views
112

편집 : 나는 최근 인Markdown 사양의 모호성을 정확하게 식별하고 다루는 CommonMark라는 프로젝트에 대해 알게되었습니다. http://commonmark.org/ 훌륭한 C# 라이브러리 을 지원합니다.Markdown 구문 분석에 대해 어떻게 생각하십니까?

here 구문을 찾을 수 있습니다.

다운로드와 함께 나오는 출처는 Perl으로 작성되어 있으며,이를 기리는 의도는 없습니다. 정규 표현식으로 가득 차 있으며 특정 문자를 이스케이프 처리하기 위해 해시가 MD5 개 있습니다. 뭔가 잘못되었습니다!

저는 파서를 Markdown으로 하드 코딩하려고합니다. 이 경험은 무엇입니까?

Markdown의 실제 구문 분석에 대해 의미있는 바가 없다면 시간을 절약하십시오. (가혹한 것처럼 보일 수도 있지만 예, 통찰력을 찾고 솔루션이 아니라 제 3 자 라이브러리를 찾고 있습니다.)

답변을 조금 도와주기 위해 정규식은 으로 지정되어 있습니다.! 문법 전체를 파싱하지 마라. 사람들은 그렇게하는 것이 foobar라고 생각합니다.

  • Markdown을 생각하면 근본적으로 단락 개념을 기반으로합니다.
  • 이와 같이 타당한 방법은 입력을 단락으로 나누는 것입니다.
  • 제목, 텍스트, 목록, blockquote 및 코드와 같은 많은 종류의 단락이 있습니다.
  • 그러므로 이러한 단락을 식별하고 이들이 어떤 맥락에서 발생하는지 파악해야합니다.

공유 할 가치가 있다고 판단되면 해결책을 찾을 것입니다.

+2

@cletus는 markdown 파서를 작성하고 있습니다. http://www.cforcoding.com/search/label/markdown을 참조하십시오. –

+0

동일한 결과를 얻었습니다. 그러나 명확히 그렇지 않기 때문에 나는 형식적인 문법 인 것처럼 문구를 분석하려고하지 않습니다. 재귀 적으로 다른 정규 표현식을 적용했습니다. 그리고 여러 번 통과합니다. 그것은 아주 잘 해결되었습니다. –

+0

@ JohnLeidegren, 나 자신과 같은 다른 호기심 많은 사용자가 마크 다운을 파싱 할 때 귀하의 시도를 볼 수 있습니까? – jmlopez

답변

60

실제로 파서를 사용하는 필자가 알고있는 유일한 마크 다운 구현은 Jon MacFarleanepeg-markdown입니다. Its parserpeg이라는 Parsing Expression Grammar 파서 생성기를 기반으로합니다.


편집 : Mauricio Fernandez 최근에 그는 자신의 OcsiBlog 웹 로그 엔진의 한 부분으로 쓴 그의 Simple Markup Markdown parser을 발표했다. 파서는 OCaml에 기록되기 때문에 매우 간단하고 짧은합니다 (parser 268 SLOC 상기 HTML emitter 43 SLOC), 또 손으로 최적화 C에 기입 discount() 및 sixhundred보다 빠른 blazingly fast (20 % BlueCloth (Ruby)보다 빠르며, 아직 성능에 최적화되어 있지는 않습니다. 그의 웹 로그를 위해 Mauricio 자신이 내부 용으로 만 사용하기 때문에, official Markdown specification에서 약간의 편차가 있지만 Mauricio는 a branch which reverts most of those changes을 만들었습니다.

+0

흥미 롭습니다. 아마도 나는 그것을 f # 프로젝트로 변환하려고 시도 할 것입니다. – ShuggyCoUk

+0

@ShuggyCoUK, 당신 은요? – Benjol

+0

@ Benjol 같은 오래된 이야기 : no time :/ – ShuggyCoUk

2

Perl이 사용자의 것이 아니라면, at least 10 other languages에 Markdown 구현이 있습니다. 그들은 아마 100 % 호환성을 갖지는 않지만 꽤 가까운 경향이 있습니다.

3

필자는 구문 사양을 충분히 숙지하고이를 구문 분석하는 방법에 대한 느낌을 얻었을 것입니다.

기존 파서 코드를 읽는 것은 당연히 복잡성의 주요 원인으로 보이는 것이 무엇인지, 그리고 특별한 영리한 트릭이 사용되고 있는지를보기 위해 훌륭합니다. MD5 checksumming의 사용은 조금 이상하게 보입니다. 그러나 코드가 왜 완성되었는지를 충분히 연구하지는 않았습니다. 일상에서의 주석이라고 _EscapeSpecialChars() 상태 : 우리는 해당 MD5 ​​체크섬 값이 각각 같은 문자를 교체하고

; 이것은 과잉 공격 일 가능성이 있지만 우연히 도주 값과 충돌하는 것을 방지해야합니다.

단일 문자를 전체 MD5로 바꾸는 것은 너무 복잡해 보이지만 실제로는 의미가 있습니다.

물론 과 같은 도구에서 "true"구문을 작성하는 것이 좋습니다. 정규식 습격을 벗어날 수 있습니다.

+0

그 MD5 일은 여전히 ​​나를 귀찮게한다. 또한 과도한 문자열 조작이 있어야한다. 실제 필사적 인 파서보다 느리다. –

+2

Flex는 실제로 파서의 절반에 지나지 않습니다. 일단 입력을 토큰 화했으면 토큰의 의미를 결정해야합니다. 이것은 파서 생성기의 용도입니다. 그들 중 많은 수가 있습니다. ("Parser combinator", "recursive-descent"와 "LALR (1)"은 google을위한 주요 단어입니다.) – jrockway

+1

@jrockway : 그건 물론 사실입니다. 나는 어깨를 으ged하고 생각했습니다. "그러나 그가 플렉스, 그는 자동으로 들소를 찾을거야. " :) 감사. – unwind

0

Here Markdown의 JavaScript 구현을 찾을 수 있습니다. 이것은 텍스트를 파싱하는 가장 빠르고 쉬운 방법이기 때문에 정규 표현식에도 크게 의존합니다.

하지만 MD5 부분은 사용하지 않습니다.

구문 분석 코딩에 직접적으로 도움이되지는 않지만,이 링크는 당신을 도울 수 있습니다.

0

PHP, 루비, 자바, C#, 자바 스크립트 등 다양한 언어로 제공되는 라이브러리가 있습니다. 나는 아이디어를 위해 이들 중 일부를 살펴볼 것을 제안합니다.

사용하려는 언어에 따라 다르지만 구현하는 가장 좋은 방법은 관용적이고 비 관용적 인 방법입니다.

정규 표현식은 perl에서 작동합니다. perl과 regex는 가장 좋은 친구이기 때문입니다.

+1

Regex와 perl은 누군가가 그렇게 말했기 때문에 가장 친한 친구입니다. 역사적 조상 이라기보다는 그런 사실에 더 이상 진실이 없습니다. 나는 펄과 같은 것을 쓸모가 없다. –

+6

다음은 사용하지 마십시오 .. 또한 아이러니를 배우십시오. – garrow

0

사용자가명 이상인 프로그래밍 언어를 사용하는 경우이를 구문 분석 할 라이브러리를 찾을 수 있어야합니다. A 빠른 Google-ing은 CL, Haskell, Python에 대한 라이브러리를 보여줍니다. JavaScript, Ruby 등 이 바퀴를 재발 명하기 위해서는 이 필요할 것 같지 않습니다.

정말로 처음부터 작성해야한다면 적절한 파서를 작성하는 것이 좋습니다. 이 기술을 사용하면 MD5 해시로 일을 피할 필요가 없습니다. (난 당신이 그런 짓을해야하는 경우, 당신의 디자인을 재고하는 시간에 동의합니다.)

+0

나는 도전하고있다. 나는 도서관을 보았다. 그러나 그들은 단지 지독하다. 추악하고 어리 석다. F # 프로젝트가 필요하기 때문에 F #에서 파서 작성을 고려하고 있지만 아마도 C#으로 끝낼 것입니다. –

+0

바라 건데 F #에는 Parsec과 같은 라이브러리가 있습니다. 그렇다면 재미있는 프로젝트가 될 것입니다.) – jrockway

0

마크 다운은 JAWL (또 다른 위키 언어)입니다

거기 오픈 소스 위키의 밖으로의 많음이있다 당신은 파서의 코드를 검사 할 수있다. 대부분의 사용 REGEX

체크 아웃 screwturn 위키입니다 흥미로운 멀티 패스 포맷터 파이프 라인, 아주 좋은 기술을 가지고 - /core/Formatter.cs 및 /core/FormatterPipeline.cs 참조

최저 사용하는 것입니다/기존 프로젝트에 참여하는 경우 이러한 종류의 것들은 항상 표시되는 것보다 훨씬 더 깁니다.

3

markdown (및 해당 확장자 Markdown extra)을 구문 분석하려고하면 상태 시스템을 사용하여 하나의 char 한 번 모두가 파싱되면, 함께 묶여있는 모든 객체의 결과물을 생성하면서 텍스트의 비트를 나타내는 내부 구조를 연결하는 시간.

기본적으로 입력 파일을 읽는 것처럼 미니 DOM과 유사한 트리를 작성합니다.

  • 사실이 :
    는 (... PS, 라텍스, RTF,) 난 그냥 나무 및 출력 HTML 또는 아무것도를 통과 것이다 복잡성을 증가시킬 수

    것들 출력을 생성하려면 규칙을 쉽게 구현할 수 있지만 HTML과 마크 다운을 혼합 할 수 있습니다. 두 개의 균형 잡힌 태그 사이에있는 모든 것을 무시하고 그대로 출력합니다.

  • URL과 메모는 텍스트 하단에 참조 할 수 있습니다. 하이퍼 링크 데이터 구조를 사용하면 간단하게 뭔가를 기록 할 수 있습니다 :

    [my text to a link][linkkey] 
    results in a structure like: 
        URLStructure: 
        | InnerText : "my text to a link" 
        | Key  : "linkkey" 
        | URL  : <null> 
    
  • 헤더 밑줄, 즉 일반 단락 간단한 데이터 구조를 사용하여 우리가 파일을 읽을 때 해당 속성을 수정하는 우리를 강제 할 수 정의 할 수 있습니다 :

    어쨌든
    ParagraphStructure: 
    | InnerText : the current paragraph text 
    |     (beginning of line until end of line). 
    | HeadingLevel : <null> or 1-4 when we can assess 
    |     that paragraph heading level, if any. 
    

, 단지 몇 가지 생각.

저는 많은 작은 세부 사항이 있다고 확신합니다. Regexes가 프로세스 중에 편리해질 수 있다고 확신합니다.
결국 텍스트를 처리하기위한 것이 었습니다.

17

나는 지난주 새로운 파서 기반의 Markdown Java 구현을 발표했는데, pegdown이라고 불렀다. pegdown은 PEG 구문 분석기를 사용하여 추상 구문 트리를 먼저 작성한 다음 나중에 HTML로 작성합니다. 따라서 정규식 기반 접근법보다 읽기 쉽고, 유지 관리하고 확장하는 것이 훨씬 쉽고 훨씬 쉽습니다. PEG 문법은 John MacFarlanes C 구현 "peg-markdown"을 기반으로합니다.

당신에게 관심이 아마도 뭔가 ...

관련 문제