OCaml library for JSONfeed parsing and creation

readme

+178
+18
LICENSE.md
··· 1 + (* 2 + * ISC License 3 + * 4 + * Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org> 5 + * 6 + * Permission to use, copy, modify, and distribute this software for any 7 + * purpose with or without fee is hereby granted, provided that the above 8 + * copyright notice and this permission notice appear in all copies. 9 + * 10 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 + * 18 + *)
+160
README.md
··· 1 + # OCaml-JSONFeed 2 + 3 + An OCaml library for parsing and generating [JSON Feed](https://www.jsonfeed.org/) documents. 4 + 5 + JSON Feed is a format similar to RSS and Atom but uses JSON instead of XML. 6 + It is designed to be easier for developers to work with while providing all the 7 + functionality needed for feed syndication. 8 + 9 + ## Installation 10 + 11 + Add to your `dune-project`: 12 + 13 + ```lisp 14 + (package 15 + (name your-package) 16 + (depends 17 + jsonfeed 18 + ...)) 19 + ``` 20 + 21 + ## Quick Start 22 + 23 + ### Creating a Feed 24 + 25 + ```ocaml 26 + open Jsonfeed 27 + 28 + (* Create an author *) 29 + let author = Author.create 30 + ~name:"Jane Doe" 31 + ~url:"https://example.com/jane" 32 + () 33 + 34 + (* Create an item with HTML content *) 35 + let item = Item.create 36 + ~id:"https://example.com/posts/1" 37 + ~url:"https://example.com/posts/1" 38 + ~title:"Hello, JSON Feed!" 39 + ~content:(`Html "<p>My first post using JSON Feed.</p>") 40 + ~authors:[author] 41 + ~tags:["introduction"; "jsonfeed"] 42 + () 43 + 44 + (* Create the feed *) 45 + let feed = Jsonfeed.create 46 + ~title:"My Blog" 47 + ~home_page_url:"https://example.com" 48 + ~feed_url:"https://example.com/feed.json" 49 + ~items:[item] 50 + () 51 + 52 + (* Serialize to JSON *) 53 + let json = Jsonfeed.to_string feed 54 + ``` 55 + 56 + ### Parsing a Feed 57 + 58 + ```ocaml 59 + open Jsonfeed 60 + 61 + (* Parse from string *) 62 + match Jsonfeed.of_string json_string with 63 + | Ok feed -> 64 + Printf.printf "Feed: %s\n" (Jsonfeed.title feed); 65 + List.iter (fun item -> 66 + match Item.title item with 67 + | Some title -> Printf.printf "- %s\n" title 68 + | None -> () 69 + ) (Jsonfeed.items feed) 70 + | Error (`Msg err) -> 71 + Printf.eprintf "Parse error: %s\n" err 72 + 73 + (* Parse from file *) 74 + let content = In_channel.with_open_text "feed.json" In_channel.input_all in 75 + match Jsonfeed.of_string content with 76 + | Ok feed -> (* ... *) 77 + | Error _ -> (* ... *) 78 + ``` 79 + 80 + ### Content Types 81 + 82 + Items can have HTML content, plain text content, or both: 83 + 84 + ```ocaml 85 + (* HTML only *) 86 + let item1 = Item.create 87 + ~id:"1" 88 + ~content:(`Html "<p>Rich <strong>HTML</strong> content</p>") 89 + () 90 + 91 + (* Plain text only *) 92 + let item2 = Item.create 93 + ~id:"2" 94 + ~content:(`Text "Plain text content") 95 + () 96 + 97 + (* Both HTML and text *) 98 + let item3 = Item.create 99 + ~id:"3" 100 + ~content:(`Both ("<p>HTML version</p>", "Text version")) 101 + () 102 + 103 + (* Access content *) 104 + match Item.content_html item1 with 105 + | Some html -> Printf.printf "HTML: %s\n" html 106 + | None -> () 107 + ``` 108 + 109 + ### Podcast Feed with Attachments 110 + 111 + ```ocaml 112 + (* Create an audio attachment *) 113 + let episode_audio = Attachment.create 114 + ~url:"https://podcast.example.com/ep1.mp3" 115 + ~mime_type:"audio/mpeg" 116 + ~size_in_bytes:15_728_640L 117 + ~duration_in_seconds:1800 118 + () 119 + 120 + (* Create a podcast episode *) 121 + let episode = Item.create 122 + ~id:"https://podcast.example.com/episodes/1" 123 + ~title:"Episode 1: Introduction" 124 + ~content:(`Html "<p>Welcome to the show!</p>") 125 + ~attachments:[episode_audio] 126 + () 127 + ``` 128 + 129 + ## Examples 130 + 131 + The `example/` directory contains several complete examples: 132 + 133 + - **feed_example.ml** - Creating and serializing feeds (blog and podcast) 134 + - **feed_parser.ml** - Parsing and analyzing feeds from files 135 + - **feed_validator.ml** - Validating feeds and demonstrating various feed types 136 + 137 + Run examples: 138 + 139 + ```bash 140 + opam exec -- dune exec -- ./example/feed_parser.exe 141 + opam exec -- dune exec -- ./example/feed_example.exe 142 + ``` 143 + 144 + ## API Documentation 145 + 146 + Build the API documentation: 147 + 148 + ```bash 149 + opam exec -- dune build @doc 150 + ``` 151 + 152 + Then open `_build/default/_doc/_html/index.html` in your browser. 153 + 154 + ## Specification 155 + 156 + This library implements [JSON Feed Version 1.1](https://www.jsonfeed.org/version/1.1/). 157 + 158 + ## License 159 + 160 + See LICENSE.md for details.