Làm thế nào bạn sẽ đi về phân tích Markdown? [đóng cửa]


126

Chỉnh sửa: Gần đây tôi đã biết về một dự án có tên CommonMark, xác định chính xác và xử lý các vấn đề mơ hồ trong đặc tả Markdown ban đầu. http://commonmark.org/ Nó có hỗ trợ thư viện C # tuyệt vời.

Bạn có thể tìm thấy cú pháp ở đây .

Nguồn tiếp theo với tải xuống được viết bằng Perl , mà tôi không có ý định tôn vinh. Nó được đánh đố với các biểu thức thông thường và nó dựa vào băm MD5 để thoát các ký tự nhất định. Có gì đó không đúng về điều đó!

Tôi sắp sửa mã hóa trình phân tích cú pháp cho Markdown . Kinh nghiệm với điều này là gì?

Nếu bạn không có bất cứ điều gì có ý nghĩa để nói về phân tích cú pháp thực tế của Markdown, hãy dành thời gian cho tôi. (Điều này nghe có vẻ khắc nghiệt, nhưng vâng, tôi đang tìm kiếm cái nhìn sâu sắc, không phải là một giải pháp, đó là thư viện của bên thứ ba).

Để giúp một chút với các câu trả lời, các biểu thức thông thường có nghĩa là để xác định các mẫu ! KHÔNG phân tích toàn bộ ngữ pháp. Mà mọi người coi như vậy là foobar.

  • Nếu bạn nghĩ về Markdown, về cơ bản, nó dựa trên khái niệm đoạn văn.
  • Như vậy, một cách tiếp cận hợp lý có thể là chia đầu vào thành các đoạn.
  • Có nhiều loại đoạn văn, ví dụ, tiêu đề, văn bản, danh sách, blockquote và mã.
  • Do đó, thách thức là xác định các đoạn này và trong bối cảnh chúng xảy ra.

Tôi sẽ trở lại với một giải pháp, một khi tôi thấy nó xứng đáng được chia sẻ.


2
@cletus đang viết một trình phân tích cú pháp đánh dấu, xem cforcoding.com/search/label/markdown
Alex Angas

Tôi cuối cùng đã làm như vậy. Tuy nhiên, tôi không cố phân tích đánh dấu như thể đó là một ngữ pháp chính thức, vì rõ ràng là không phải vậy. Tôi đã áp dụng các biểu thức chính quy khác nhau theo cách đệ quy. Và trong vài lần vượt qua. Điều đó làm việc rất tốt.
John Leidegren

@JohnLeidegren, bất kỳ cơ hội nào mà những người dùng tò mò khác như tôi có thể thấy nỗ lực của bạn trong việc phân tích cú pháp đánh dấu?
jmlopez

@jmlopez Xin lỗi, tôi không còn quyền truy cập vào nguồn đó nữa, nếu bạn cần một trình phân tích cú pháp đánh dấu, có một gói NuGet có sẵn có thể được sử dụng. Tuy nhiên, ý tưởng này đủ đơn giản, chỉ cần áp dụng một loạt các biểu thức chính quy trong các lượt đi, bắt đầu bằng cách ghép các đầu vào trong đoạn văn sau đó cố gắng xác định loại đoạn văn đó là gì, v.v. Cuối cùng, phân tích liên kết và kiểu ký tự trong các đoạn văn.
John Leidegren

2
Bạn nên nhìn vào Parsedown . Nó chia văn bản thành các dòng. Sau đó, nó nhìn vào cách các dòng này bắt đầu và liên quan với nhau.
Emanuil Rusev

Câu trả lời:


69

Việc thực hiện đánh dấu duy nhất mà tôi biết, sử dụng một trình phân tích cú pháp thực tế, là chốt đánh dấu chốt của Jon MacFarleaneát . Trình phân tích cú pháp của nó dựa trên trình tạo trình phân tích cú pháp ngữ pháp phân tích cú pháp được gọi là chốt .


EDIT: Mới đây, Mauricio Fernandez đã phát hành trình phân tích cú pháp Markup Markdown đơn giản của mình , được viết như một phần của OcsiBlog Weblog Engine. Bởi vì phân tích cú pháp được viết bằng OCaml , nó là vô cùng đơn giản và ngắn (268 SLOC cho phân tích cú pháp , 43 SLOC cho HTML phát ), nhưng blazingly nhanh (20% nhanh hơn so với giảm giá (viết bằng tay được tối ưu hóa C) và sixhundred lần nhanh hơn hơn BlueCloth ( Ruby)), mặc dù thực tế là nó thậm chí chưa được tối ưu hóa cho hiệu suất. Bởi vì nó chỉ dành cho mục đích sử dụng nội bộ của chính Mauricio cho weblog của mình, nên có một vài sai lệch so với thông số kỹ thuật chính thức của Markdown , nhưng Mauricio đã tạo ra một nhánh hoàn nguyên hầu hết những thay đổi đó .


1
hấp dẫn. có lẽ tôi sẽ thử chuyển đổi nó thành một dự án f #
ShuggyCoUk

@Benjol câu chuyện cũ cùng: không có thời gian: /
ShuggyCoUk

1
Terrence Parr (đồng tác giả của ANTLR) đã viết một bài cho ANTLR 4: github.com/parrt/mini-markdown
Chris S

17

Tôi đã phát hành một triển khai Java Markdown dựa trên trình phân tích cú pháp mới vào tuần trước, được gọi là pegdown . pegdown sử dụng trình phân tích cú pháp PEG để trước tiên xây dựng một cây cú pháp trừu tượng, sau đó được viết ra HTML. Vì vậy, nó khá sạch sẽ và dễ đọc hơn, duy trì và mở rộng hơn so với cách tiếp cận dựa trên regex. Ngữ pháp PEG dựa trên việc thực hiện "chốt đánh dấu" của John MacFarlanes C.

Có lẽ điều gì đó khiến bạn quan tâm ...


1
Điều này hiện đã được chính thức phản đối
Fabich

7

Nếu tôi cố gắng phân tích cú pháp đánh dấu (và phần mở rộng của nó Markdown thêm ) Tôi nghĩ rằng tôi sẽ thử sử dụng một máy trạng thái và phân tích cú pháp một lần, liên kết với nhau một số cấu trúc bên trong đại diện cho các đoạn văn bản khi tôi đi cùng, một lần tất cả được phân tích cú pháp, tạo đầu ra từ các đối tượng được xâu chuỗi lại với nhau.

Về cơ bản, tôi sẽ xây dựng một cây giống như DOM nhỏ khi tôi đọc tệp đầu vào.
Để tạo đầu ra, tôi chỉ cần duyệt qua cây và đầu ra HTML hoặc bất cứ thứ gì khác (PS, LaTex, RTF, ...)

Những thứ có thể làm tăng sự phức tạp:

  • Thực tế là bạn có thể trộn HTML và markdown, mặc dù quy tắc có thể dễ thực hiện: chỉ cần bỏ qua mọi thứ nằm giữa hai thẻ cân bằng và xuất ra nguyên văn.

  • URL và ghi chú có thể có tài liệu tham khảo của họ ở dưới cùng của văn bản. Sử dụng cấu trúc dữ liệu cho các siêu liên kết có thể chỉ cần ghi lại một cái gì đó như:

    [my text to a link][linkkey]
    results in a structure like: 
        URLStructure: 
        |  InnerText : "my text to a link"
        |  Key       : "linkkey"
        |  URL       : <null>
    
  • Các tiêu đề có thể được xác định bằng một gạch chân, điều đó có thể buộc chúng ta sử dụng cấu trúc dữ liệu đơn giản cho một đoạn chung và sửa đổi các thuộc tính của nó khi chúng ta đọc tệp:

    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.
    

Dù sao, chỉ là một vài suy nghĩ.

Tôi chắc chắn rằng có nhiều chi tiết nhỏ cần quan tâm và tôi khá chắc chắn rằng Regexes có thể trở nên tiện dụng trong quá trình này.
Rốt cuộc, họ có nghĩa là để xử lý văn bản.


3

Có lẽ tôi đã đọc đặc tả cú pháp đủ lần để biết nó và cảm nhận về cách phân tích cú pháp.

Đọc mã trình phân tích cú pháp hiện tại tất nhiên là tuyệt vời, cả hai để xem những gì dường như là nguồn phức tạp chính và nếu có bất kỳ thủ thuật thông minh đặc biệt nào đang được sử dụng. Việc sử dụng kiểm tra MD5 có vẻ hơi lạ, nhưng tôi chưa nghiên cứu mã đủ để hiểu tại sao nó được thực hiện. Một nhận xét trong một thói quen được gọi là _EscapeSpecialChars()trạng thái:

Chúng tôi sẽ thay thế từng ký tự như vậy bằng giá trị tổng kiểm tra MD5 tương ứng; điều này có thể là quá mức cần thiết, nhưng nó sẽ ngăn chúng ta va chạm với các giá trị thoát một cách tình cờ.

Thay thế một ký tự bằng MD5 đầy đủ có vẻ ngông cuồng, nhưng có lẽ nó thực sự có ý nghĩa.

Tất nhiên, sẽ là thông minh khi xem xét việc tạo cú pháp "đúng", cho một công cụ như Flex để thoát khỏi chế độ regex.


Điều MD5 đó vẫn làm phiền tôi, thao tác chuỗi quá mức phải chậm hơn bất kỳ trình phân tích cú pháp thực tế nào bạn có thể tự viết.
John Leidegren

2
Flex thực sự chỉ là một nửa trình phân tích cú pháp; một khi bạn đã mã hóa đầu vào, bạn cần xác định ý nghĩa của các mã thông báo. Đây là những gì một trình tạo phân tích cú pháp dành cho. Chúng có rất nhiều. ("Trình kết hợp phân tích cú pháp", "đệ quy gốc" và "LALR (1)" là những từ khóa để google tìm kiếm.)
jrockway

1
@jrockway: điều đó đúng tất nhiên, tôi đoán tôi đã nhún vai và nghĩ "nhưng nếu anh ta đọc lên Flex, anh ta sẽ tự động tìm thấy Bison". :) Cảm ơn.
thư giãn

2

Nếu Perl không phải là thứ của bạn, thì có các triển khai Markdown bằng ít nhất 10 ngôn ngữ khác . Họ có thể không có khả năng tương thích 100%, nhưng có xu hướng khá gần gũi.



1

Nếu bạn đang sử dụng ngôn ngữ lập trình có nhiều hơn ba người dùng khác, bạn sẽ có thể tìm một thư viện để phân tích cú pháp cho bạn. Google-ing nhanh chóng tiết lộ các thư viện cho CL, Haskell, Python, JavaScript, Ruby, v.v. Rất khó có khả năng bạn sẽ cần phải phát minh lại bánh xe này.

Nếu bạn thực sự phải viết nó từ đầu, tôi khuyên bạn nên viết một trình phân tích cú pháp thích hợp. Với kỹ thuật này, bạn sẽ không phải thoát mọi thứ với băm MD5. (Tôi đồng ý rằng nếu bạn phải làm một cái gì đó như thế này, đã đến lúc xem xét lại thiết kế của bạn.)


Tôi sẵn sàng cho thử thách. Tôi đã xem các thư viện nhưng chúng chỉ là khủng khiếp. Xấu xí và ngu ngốc. Tôi đang xem xét việc viết trình phân tích cú pháp trong F # vì tôi cần một dự án F # nhưng có lẽ cuối cùng tôi sẽ thực hiện nó trong C #.
John Leidegren

Hy vọng F # có một thư viện như Parsec; nếu vậy, đây sẽ là một dự án thú vị;)
jrockway

0

Có các thư viện có sẵn trong một số ngôn ngữ, bao gồm php, ruby, java, c #, javascript. Tôi muốn đề nghị xem xét một vài trong số này cho các ý tưởng.

Nó phụ thuộc vào ngôn ngữ bạn muốn sử dụng, đối với cách tốt nhất để thực hiện nó, sẽ có những cách thành ngữ và không thành ngữ để làm điều đó.

Regexes hoạt động trong perl, bởi vì perl và regex là những người bạn tốt nhất.


1
Regex và perl là những người bạn tốt nhất vì ai đó đã nói như vậy. Không có sự thật nào cho sự thật đó hơn tổ tiên lịch sử của nó, rằng nó đã được sử dụng như thế. Tôi không có sử dụng cho một cái gì đó như perl.
John Leidegren

7
Sau đó không sử dụng nó .. Ngoài ra, học trớ trêu.
garrow

0

Markdown là một JAWL (chỉ là một ngôn ngữ wiki khác)

Có rất nhiều wiki nguồn mở ngoài kia mà bạn có thể kiểm tra mã của trình phân tích cú pháp. Hầu hết sử dụng REGEX

Kiểm tra wiki vít, có một đường dẫn định dạng nhiều lượt thú vị, một kỹ thuật rất hay - xem /core/Formatter.cs và /core/FormatterPipeline.cs

Tốt nhất là sử dụng / tham gia một dự án hiện có, những thứ này luôn khó hơn nhiều so với chúng xuất hiện


0

Tại đây bạn có thể tìm thấy triển khai JavaScript của Markdown. Nó cũng phụ thuộc rất nhiều vào các biểu thức thông thường, vì đây chỉ là cách nhanh nhất và dễ nhất để phân tích văn bản.

Nhưng nó bỏ qua phần MD5.

Tôi không thể giúp trực tiếp với việc mã hóa phân tích cú pháp, nhưng có lẽ liên kết này có thể giúp bạn bằng cách này hay cách khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.