[parsing] Markdown을 파싱하는 방법은 무엇입니까? [닫은]

편집 : 최근에 원래 Markdown 사양의 모호성을 올바르게 식별하고 처리하는 CommonMark라는 프로젝트에 대해 배웠습니다. http://commonmark.org/ C # 라이브러리를 훌륭하게 지원합니다.

구문은 여기에서 찾을 수 있습니다 .

다운로드와 함께 제공되는 소스는 Perl 로 작성되었으며 ,이를 존중할 의도는 없습니다. 정규 표현식으로 가득 차 있으며 MD5 해시에 의존하여 특정 문자를 이스케이프합니다. 그것에 대해 뭔가 잘못되었습니다!

Markdown에 대한 파서를 하드 코딩하려고 합니다. 이것에 대한 경험은 무엇입니까?

Markdown의 실제 구문 분석에 대해 의미있는 말이 없으면 시간을 절약하십시오. (이것은 가혹하게 들릴 수도 있지만, 해결책이 아닌 통찰력, 즉 타사 라이브러리를 찾고 있습니다).

정답은 패턴식별 하기 위한 것입니다 . 전체 문법을 파싱하지 마십시오. 사람들이 그렇게 생각하는 것은 바보입니다.

  • Markdown에 대해 생각하면 기본적으로 단락 개념을 기반으로합니다.
  • 따라서 합리적인 접근 방식은 입력을 단락으로 나누는 것일 수 있습니다.
  • 제목, 텍스트, 목록, 인용 부호 및 코드와 같은 많은 종류의 단락이 있습니다.
  • 따라서이 단락과 그 문맥이 무엇인지 파악해야합니다.

공유 할 가치가 있다고 판단되면 솔루션으로 돌아올 것입니다.



답변

실제 파서를 사용하는 유일한 마크 다운 구현은 Jon MacFarleanepeg-markdown 입니다. 파서peg 라는 구문 분석 표현식 문법 파서 생성기를 기반으로합니다 .


편집 : Mauricio Fernandez는 최근 자신의 OcsiBlog 웹 로그 엔진의 일부로 쓴 Simple Markup Markdown 파서를 발표했습니다 . 파서가 작성된 때문에 OCaml로 , 그것은 인 매우 짧고 간단합니다 (268 SLOC 파서 , 43 SLOC는 HTML 터 ), 아직 엄청나게 빠른 (20 %보다 빠르게 할인 (손 최적화 C에 기입) 및 sixhundred 배 빠른 BlueCloth 보다 ( Ruby)), 아직 성능에 최적화되지 않았다는 사실에도 불구하고. Mauricio가 자체 웹 로그를 위해 내부적으로 만 사용하기 때문에 공식 Markdown 사양 과 약간의 차이가 있지만 Mauricio는 이러한 변경 사항을 대부분 되 돌리는 지점을 만들었습니다 .


답변

지난 주 pegdown 이라는 새로운 파서 기반 Markdown Java 구현을 발표했습니다 . pegdown은 PEG 파서를 사용하여 먼저 추상 구문 트리를 작성하며,이 구문 트리는 HTML로 작성됩니다. 따라서 정규식 기반 접근 방식보다 훨씬 깨끗하고 읽기 쉽고 유지 관리하며 확장됩니다. PEG 문법은 John MacFarlanes C 구현 “페그 마크 다운”을 기반으로합니다.

아마도 당신에게 관심이있는 것은 …


답변

markdown (및 확장명 Markdown extra ) 을 구문 분석 하려고하면 상태 머신을 사용하고 한 번에 한 문자 씩 구문 분석하여 텍스트 비트를 나타내는 내부 구조를 한 번에 연결하려고 시도한다고 생각합니다. 모두 구문 분석되어 모든 문자열로 묶인 객체의 출력을 생성합니다.

기본적으로 입력 파일을 읽을 때 미니 DOM과 같은 트리를 작성합니다.
출력을 생성하려면 트리를 통과하고 HTML 또는 다른 것을 출력합니다 (PS, LaTex, RTF 등).

복잡성을 증가시킬 수있는 것들 :

  • 규칙을 구현하기는 쉽지만 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가 편리해질 수 있다고 확신합니다.
결국, 그들은 텍스트를 처리해야했습니다.


답변

구문 사양을 알기에 충분한 시간을 읽고 구문 분석 방법에 대한 느낌을 얻었을 것입니다.

기존 파서 코드를 읽는 것은 물론 복잡성의 주요 원인이 무엇인지, 그리고 특별한 영리한 트릭이 사용되고 있는지를 보는 것이 훌륭합니다. MD5 체크섬을 사용하는 것은 조금 이상해 보이지만, 왜 그렇게되는지 이해하기에 충분한 코드를 연구하지는 않았습니다. _EscapeSpecialChars()상태 라는 루틴의 주석 :

이러한 각 문자를 해당 MD5 ​​체크섬 값으로 바꿉니다. 이것은 과잉 일 가능성이 있지만 우연히 이스케이프 값과 충돌하지 않도록해야합니다.

단일 문자를 전체 MD5로 바꾸는 것은 사치스러운 것처럼 보이지만 실제로는 의미가 있습니다.

물론 Flex 와 같은 도구 가 정규식 늪지에서 벗어날 수 있도록 “진정한”구문 작성을 고려하는 것이 현명합니다 .


답변

Perl이 마음에 들지 않으면 10 개 이상의 다른 언어로 Markdown 구현이 있습니다 . 그들은 모두 100 % 호환성을 가지고 있지는 않지만 꽤 가깝습니다.


답변

MarkdownPapers 는 파서가 JavaCC 문법에 정의 된 또 다른 Java 구현입니다 .


답변

다른 사용자가 3 명 이상인 프로그래밍 언어를 사용하는 경우 구문 분석 할 라이브러리를 찾을 수 있어야합니다. 빠른 Google 검색은 CL, Haskell, Python, JavaScript, Ruby 등의 라이브러리를 보여줍니다. 이 휠을 다시 발명해야 할 가능성은 거의 없습니다.

실제로 처음부터 작성해야하는 경우 적절한 파서를 작성하는 것이 좋습니다. 이 기술을 사용하면 MD5 해시로 물건을 벗어날 필요가 없습니다. (이와 같은 일을해야한다면 디자인을 재고해야 할 때입니다.)