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


126

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

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

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

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

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

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

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

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


2
@cletus가 인하 파서를 쓰고, 참조 cforcoding.com/search/label/markdown
알렉스 Angas

나는 똑같이했다. 그러나 마크 다운을 공식 문법처럼 파싱하려고하지 않습니다. 왜냐하면 명확하지 않기 때문입니다. 나는 다른 정규 표현식을 재귀 방식으로 적용했습니다. 그리고 몇 번의 패스로. 그것은 아주 잘 작동했습니다.
John Leidegren

@JohnLeidegren, 나 같은 다른 호기심 많은 사용자가 마크 다운을 파싱하려는 시도를 볼 수 있습니까?
jmlopez

@jmlopez 죄송합니다. 더 이상 해당 소스에 액세스 할 수 없습니다. 마크 다운 파서가 필요한 경우 사용할 수있는 NuGet 패키지가 있습니다. 아이디어는 충분히 간단합니다. 패스에 일련의 정규 표현식을 적용하고 단락의 입력을 분류하여 시작한 다음 어떤 종류의 단락인지 식별하십시오. 마지막으로 단락 자체 내에서 링크와 문자 스타일을 구문 분석하십시오.
John Leidegren

2
Parsedown봐야 합니다. 텍스트를 여러 줄로 나눕니다. 그런 다음이 선들이 서로 어떻게 시작하고 관련되는지 살펴 봅니다.
Emanuil Rusev

답변:


69

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


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


1
흥미 롭군 아마 나는 이것을 f # 프로젝트로 변환하려고 노력할 것입니다
ShuggyCoUk

@Benjol 같은 오래된 이야기 : 시간이 없다 : /
ShuggyCoUk

1
Terrence Parr (ANTLR의 공동 저자)는 ANTLR 4에 대해 하나를 썼습니다. github.com/parrt/mini-markdown
Chris S

17

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

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


1
이것은 공식적으로 더 이상 사용되지 않습니다
Fabich

7

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가 편리해질 수 있다고 확신합니다.
결국, 그들은 텍스트를 처리해야했습니다.


3

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

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

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

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

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


MD5는 여전히 나를 귀찮게하고 과도한 문자열 조작은 실제로 쓸 수있는 파서보다 느려 야합니다.
John Leidegren

2
Flex는 실제로 파서의 절반에 불과합니다. 입력을 토큰 화하면 토큰의 의미를 결정해야합니다. 이것이 파서 생성기입니다. 그것들이 많이 있습니다. ( "Parser combinator", "recursive-descent"및 "LALR (1)"은 Google의 핵심 단어입니다.)
jrockway

1
@jrockway : 물론 그렇습니다. 나는 어깨를 으 and하고 "Flex를 읽으면 Bison을 자동으로 찾을 것"이라고 생각했습니다. :) 감사.



1

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

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


나는 도전에 나섰다. 나는 도서관을 보았지만 단지 끔찍합니다. 못생긴 바보 F # 프로젝트가 필요하기 때문에 F #에서 파서를 작성하는 것을 고려하고 있지만 아마도 C #에서 수행 할 것입니다.
John Leidegren

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

0

php, ruby, java, c #, javascript 등 여러 언어로 제공되는 라이브러리가 있습니다. 아이디어 중 일부를 살펴볼 것을 제안합니다.

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

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


1
누군가가 그렇게 말했기 때문에 정규식과 펄은 가장 친한 친구입니다. 역사적 조상보다 그 사실에 더 이상 진실이 없으며, 그렇게 사용되었습니다. 나는 펄과 같은 것을 사용하지 않는다.
John Leidegren

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

0

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

파서의 코드를 검사 할 수있는 많은 오픈 소스 위키가 있습니다. 대부분의 정규식 사용

screwturn 위키를 확인하십시오. 흥미로운 멀티 패스 포맷터 파이프 라인이 있으며 매우 좋은 기술입니다-/core/Formatter.cs 및 /core/FormatterPipeline.cs를 참조하십시오.

기존 프로젝트를 사용 / 가입하는 것이 가장 좋습니다. 이런 종류의 것들은 항상 보이는 것보다 훨씬 어렵습니다.


0

여기 에서 Markdown의 JavaScript 구현을 찾을 수 있습니다. 또한 텍스트를 구문 분석하는 가장 빠르고 쉬운 방법이므로 정규식에 크게 의존합니다.

그러나 그것은 MD5 부분을 아끼지 않습니다.

파싱의 코딩을 직접 도울 수는 없지만이 링크는 어떤 식 으로든 도움이 될 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.