2009-03-03 53 views
112

Chỉnh sửa: Gần đây tôi đã tìm hiểu về một dự án gọi là CommonMark, trong đó xác định chính xác và giao dịch với sự mơ hồ trong đặc điểm kỹ thuật Đánh dấu ban đầu . http://commonmark.org/ Nó có thư viện C# tuyệt vời.Bạn sẽ phân tích cú pháp Markdown như thế nào?

Bạn có thể tìm cú pháp here.

Nguồn sau tải xuống được viết bằng Perl, mà tôi không có ý định tôn vinh. Nó được riddled với các biểu thức thông thường, và nó dựa trên MD5 băm để thoát khỏi các ký tự nhất định. Một cái gì đó chỉ là sai về điều đó!

Tôi chuẩn bị mã hóa phân tích cú pháp cứng cho Markdown. Kinh nghiệm với điều này là gì?

Nếu bạn không có bất kỳ điều gì có ý nghĩa để nói về việc phân tích cú pháp thực sự 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 có, tôi đang tìm kiếm thông tin chi tiết, không phải là giải pháp, nghĩa là thư viện của bên thứ ba).

Để giúp một chút với câu trả lời, cụm từ thông dụng có nghĩa là xác định các mẫu! KHÔNG phân tích cú pháp toàn bộ ngữ pháp. Mọi người xem xét làm 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 văn.
  • Có nhiều loại đoạn văn, ví dụ: tiêu đề, văn bản, danh sách, khối trích dẫn và mã.
  • Thách thức là như vậy để xác định các đoạn văn này và trong bối cảnh chúng xảy ra.

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

+2

@cletus đang viết trình phân tích cú pháp đánh dấu, xem http://www.cforcoding.com/search/label/markdown –

+0

Tôi đã thực hiện tương tự. Tuy nhiên, tôi không cố phân tích cú pháp như thể đó là ngữ pháp chính thức, bởi vì rõ ràng là không. Tôi áp dụng các biểu thức chính quy khác nhau theo cách đệ quy. Và trong nhiều lần. Điều đó làm việc rất tốt. –

+0

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

Trả lời

60

Cách triển khai đánh dấu duy nhất mà tôi biết, sử dụng trình phân tích cú pháp thực tế, là Jon MacFarleanepeg-markdown. Its parser dựa trên máy phát phân tích cú pháp Parsing Expression Grammar được gọi là peg.


EDIT: Mauricio Fernandez vừa cho ra mắt Simple Markup Markdown parser của ông, mà ông đã viết như là một phần của Công cụ OcsiBlog Weblog của mình. Bởi vì phân tích cú pháp được viết bằng OCaml, nó là cực kỳ đơn giản và ngắn (268 SLOC cho parser, 43 SLOC cho HTML emitter), nhưng blazingly fast (20 nhanh hơn discount (viết bằng tay được tối ưu hóa C) và sixhundred% nhanh hơn BlueCloth (Ruby)), mặc dù thực tế nó thậm chí không được tối ưu hóa cho hiệu suất. Bởi vì nó chỉ dành cho việc sử dụng nội bộ của Mauricio cho weblog của mình, có một vài sai lệch từ official Markdown specification, nhưng Mauricio đã tạo ra a branch which reverts most of those changes.

+0

thú vị. có lẽ tôi sẽ cố gắng chuyển đổi đó như là một dự án f # – ShuggyCoUk

+0

@ShuggyCoUK, phải không? – Benjol

+0

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

2

Nếu Perl không phải là điều của bạn, có triển khai Markdown trong at least 10 other languages. Họ có lẽ không phải tất cả đều có khả năng tương thích 100%, nhưng có xu hướng khá gần.

3

Tôi có thể đọc đặc tả cú pháp đủ lần để biết điều đó và cảm nhận 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 cái gì có vẻ 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 MD5 checksumming có vẻ hơi lạ, nhưng tôi đã không nghiên cứu mã đủ để hiểu tại sao nó được thực hiện. Nhận xét theo quy tắc được gọi là _EscapeSpecialChars() tiểu bang:

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

Thay thế một ký tự đơn bằng MD5 đầy đủ có vẻ quá lộng lẫy, nhưng có lẽ nó thực sự hợp lý.

Tất nhiên, bạn nên cân nhắc việc tạo cú pháp "đúng" cho một công cụ như Flex để thoát khỏi bog regex.

+0

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

+2

Flex thực sự chỉ phân nửa cú pháp; khi bạn đã mã hóa đầu vào , bạn cần phải xác định ý nghĩa của mã thông báo. Đây là máy phát phân tích cú pháp của . Chúng có rất nhiều. ("Parser combinator", "đệ quy-descent" và "LALR (1)" là từ khóa để google cho.) – jrockway

+1

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

0

Here bạn có thể tìm thấy JavaScript thực thi Markdown. Nó cũng dựa rất nhiều vào các biểu thức chính quy, vì đây chỉ là cách nhanh nhất và dễ nhất để phân tích văn bản.

Nhưng nó phụ tùng phần MD5.

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

0

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

Tùy thuộc vào ngôn ngữ bạn muốn sử dụng, 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ữ để thực hiện.

Regex làm việc trong perl, vì perl và regex là bạn thân nhất.

+1

Regex và perl là những người bạn tốt nhất bởi vì ai đó đã nói như vậy. Không có nhiều sự thật với thực tế đó hơn là tổ tiên lịch sử, rằng nó đã được sử dụng như thế. Tôi không sử dụng cái gì như perl. –

+6

Sau đó, không sử dụng nó .. Ngoài ra, học mỉa mai. – garrow

0

Nếu bạn đang sử dụng ngôn ngữ lập trình có hơn ba người dùng khác , bạn sẽ có thể tìm thấy thư viện để phân tích cú pháp đó cho bạn. A 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ó thể bạn sẽ cần để 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 khỏi những 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, đó là thời gian để xem xét lại thiết kế của bạn.)

+0

Tôi đang chuẩn bị cho thử thách. Tôi đã xem các thư viện nhưng chúng thật 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ẽ tôi sẽ kết thúc việc thực hiện nó trong C#. –

+0

Hy vọng rằ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

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

Có rất nhiều ra mã nguồn mở wiki của đó 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 các ScrewTurn wiki, là có nhiều đường ống vượt qua định dạng thú vị, một kỹ thuật rất đẹp - xem /core/Formatter.cs và /core/FormatterPipeline.cs

tốt nhất là sử dụng/Tham gia vào một dự án hiện có, những thứ này luôn khó khăn hơn khi chúng xuất hiện

3

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

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

Những điều có thể làm tăng độ 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 bất kỳ thứ gì nằm giữa hai thẻ cân bằng và xuất ra đúng nguyên văn.

  • URL và ghi chú có thể có tham chiếu của chúng ở cuối 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ỉ đơn giản là 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> 
    
  • Headers có thể được định nghĩa với một gạch dưới, có thể buộc chúng ta phải sử dụng một cấu trúc dữ liệu đơn giản cho một đoạn văn tổng quát và sửa đổi thuộc tính của nó như chúng ta đọc các tập tin :

    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ỉ cần một vài suy nghĩ.

Tôi chắc chắn rằng có rất nhiều chi tiết nhỏ để chăm sóc và tôi khá chắc chắn rằng Regexes có thể trở nên hữu ích trong quá trình này.
Sau khi tất cả, họ đã có nghĩa là để xử lý văn bản.

17

Tôi đã phát hành một triển khai Java Markdown dựa trên 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 để xây dựng một cây cú pháp trừu tượng, sau đó được viết ra HTML. Như vậy nó khá sạch sẽ và dễ đọc hơn nhiều, duy trì và mở rộng hơn một phương pháp dựa trên regex. Ngữ pháp PEG dựa trên việc thực hiện John MacFarlanes C "peg-markdown".

Có lẽ một cái gì đó quan tâm đến bạn ...

2

MarkdownPapers là một thực hiện Java mà phân tích cú pháp được định nghĩa trong một ngữ pháp JavaCC.

Các vấn đề liên quan