<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Injeniero</title>
    <description>The latest articles on DEV Community by Injeniero (@injeniero).</description>
    <link>https://dev.to/injeniero</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3404566%2F6fc601fa-7026-4a1c-a707-6dda832b0708.png</url>
      <title>DEV Community: Injeniero</title>
      <link>https://dev.to/injeniero</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/injeniero"/>
    <language>en</language>
    <item>
      <title>Reasoning + RAG: Toward a More Sustainable Future for LLMs</title>
      <dc:creator>Injeniero</dc:creator>
      <pubDate>Mon, 22 Sep 2025 04:33:09 +0000</pubDate>
      <link>https://dev.to/injeniero/reasoning-rag-toward-a-more-sustainable-future-for-llms-397f</link>
      <guid>https://dev.to/injeniero/reasoning-rag-toward-a-more-sustainable-future-for-llms-397f</guid>
      <description>&lt;p&gt;An &lt;a href="https://injeniero.com" rel="noopener noreferrer"&gt;Injeniero.com&lt;/a&gt; perspective&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F124l5ipso5vksdbe95sr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F124l5ipso5vksdbe95sr.jpg" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What Injeniero Means by “Sustainable Web”&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;At Injeniero, building a sustainable web is about minimizing the environmental, resource, and performance costs of digital technology—lean infrastructures, efficient content delivery, accessible design, and reducing waste in computation. We believe that as AI becomes more central to the web, its sustainability must be a first-order concern.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Energy Realities of Large Language Models&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Large Language Models (LLMs) have significant energy footprints, which vary depending on their use. The most energy-intensive phase is training, where a single full training run of a large model like GPT-3 (175B parameters) consumes an estimated 1,287 MWh (see sources [1,2,3]) equivalent to the annual energy consumption of hundreds of U.S. homes. In contrast, the energy used per individual query, or inference, is much lower. A typical short-prompt query to a model like GPT-4o or ChatGPT uses about 0.3 Wh (see sources [4,5]). However, for longer or more complex inputs, this energy usage can scale upward, as these prompts require more computational resources (see sources [6,7]).&lt;/p&gt;

&lt;p&gt;While the training phase consumes an enormous amount of energy in a one-time event (that might be equivalent to the lifetime of many homes), the inference phase, which is less power-intensive per query, typically dominates total lifetime energy use when you consider the sheer number of queries. Training is done only occasionally, but inference is continuous and global, resulting in a significantly larger cumulative energy footprint.&lt;/p&gt;

&lt;p&gt;Training a model like GPT-3 also resulted in an estimated ~550 metric tons CO₂ equivalent emissions.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why Reasoning + Retrieval-Augmented Generation (RAG) Offers a More Sustainable Path&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Given the above, here’s why we believe the next generation of LLMs will shift more heavily toward architectures that are reasoning-capable + RAG-enabled, instead of simply scaling up data + parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reducing retraining load:&lt;/strong&gt; Models that rely heavily on large static datasets and frequent retraining consume enormous energy. With RAG, updates to knowledge bases can be incremental (update the index), rather than redoing full training runs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lower inference cost per useful answer:&lt;/strong&gt; If a model can retrieve relevant facts and reason over them, then fewer compute cycles are wasted on recalling or recreating irrelevant or less accurate content. Efficient reasoning architectures can leverage RAG to cut the number of floating-point operations (FLOPs) per query.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Improved verification, less hallucination, more caching:&lt;/strong&gt; Grounded outputs mean fewer errors and less need for repeat or corrective queries. Also, retrieving from well-maintained knowledge stores allows caching popular queries or passages, which reduces redundant computation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Alignment with sustainable web infrastructure:&lt;/strong&gt; The design patterns required by RAG (knowledge graphs, structured data, API-driven content, schema, edge caching, etc.) are congruent with the performance + low-energy web practices Injeniero champions.&lt;br&gt;
Acknowledging the RAG System Overheads and Challenges&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While RAG offers a clear path to sustainability, it's not without its own computational and engineering costs. A balanced view acknowledges these trade-offs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Infrastructure Overhead: Building and maintaining the external knowledge bases required for RAG, such as vector databases and knowledge graphs, still requires significant energy. Indexing new data and running similarity searches on vast datasets consumes power. This is a trade-off: you're shifting the computational load from the LLM to the retrieval system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Data Quality is King: The effectiveness of RAG is entirely dependent on the quality of its knowledge base. "Garbage in, garbage out" applies here. If the data is poorly structured, inaccurate, or outdated, the system can retrieve irrelevant information, leading to poor outputs and wasted computation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Integration Complexity: RAG systems can be complex to engineer and maintain. They involve a sophisticated pipeline that includes data chunking, embedding, vector search, and reranking. This requires specialized expertise and adds a layer of operational overhead not present in monolithic LLM architectures.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Example: LATAM and GSO Leading the Way&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In the LATAM region, companies doing Generative Search Optimization (GSO) are already showing how this can work in practice. One such LATAM GSO agency is &lt;a href="https://semanticpunch.com" rel="noopener noreferrer"&gt;SemanticPunch👊&lt;/a&gt;. Key features in their approach include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Optimizing content structure (structured data, semantic markup) so generative models can retrieve precise, authoritative facts rather than guessing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Designing architecture so that knowledge sources (local or regional where possible) are well-indexed and accessible (vector search / keyword indices) to reduce latency and inference cost.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Emphasizing content quality, reduction of noise, duplication, and ambiguity—which translates to less waste in both human authoring and AI inference.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are exactly the kinds of practices that minimize waste, improve performance, and help AI + web scale without runaway energy usage.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What We Advocate for Now&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;From Injeniero’s standpoint, to steer toward a sustainable future while preserving AI’s usefulness, here are recommended practices:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Build RAG-first stacks:&lt;/strong&gt; Use smaller or distilled models with strong reasoning; maintain and curate up-to-date external knowledge bases; integrate retrieval layers that are efficient and local (or edge).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Model efficiency and architecture innovation:&lt;/strong&gt; Explore sparsely activated models (Mixture-of-Experts etc.), distillation, pruning, and quantization—all those methods that let you get similar performance with much lower energy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Work on inference efficiency:&lt;/strong&gt; Since inference is ongoing and cumulative, even small wins per query (lowering Wh per request) multiply into large savings globally.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;4.** Measure, monitor, and report energy metrics:** Track watt-hours per query (or per user), PUE (Power Usage Effectiveness), and total inference energy; set targets for energy per result, not just latency or accuracy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speculative Forecast: What Next-Gen LLMs Will Look Like&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Putting trends together, here’s how we expect the next generation of LLMs to evolve, under pressure from sustainability:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Models will become hybrid: solid, general reasoning cores + modular retrieval systems. The core model will be smaller but smarter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;More emphasis on domain-specific models or “experts,” rather than monolithic generalists that must cover everything. This allows efficient use per domain, lowering unnecessary overhead.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Infrastructure will shift toward edge / distributed retrieval + caching, reducing latency and energy cost of inference.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Standards and metrics for sustainability will become more central (e.g., energy cost per query, carbon cost per feature), possibly regulated or audited.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Injeniero’s view is that the path forward isn’t “bigger and hungrier,” it’s “smarter and more grounded.” As energy and environmental costs become more visible, the incentive to build models that lean on reasoning + RAG will only grow. Firms like &lt;a href="https://semanticpunch.com" rel="noopener noreferrer"&gt;SemanticPunch👊&lt;/a&gt; are already pointing the way: well-structured content, efficient retrieval, and semantic clarity. That’s how we build both a sustainable web and sustainable AI.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Sources&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Strubell, E., Ganesh, A., &amp;amp; McCallum, A. (2019). Energy and Policy Considerations for Deep Learning in NLP. arXiv preprint arXiv:1906.02243.&lt;/li&gt;
&lt;li&gt;Patterson, D., et al. (2021). Carbon Emissions and Large Scale AI Models. arXiv preprint arXiv:2104.10350.&lt;/li&gt;
&lt;li&gt;Luccioni, A. S., et al. (2022). The Carbon Footprint of AI: A Review of the Current Landscape. ScienceDirect.&lt;/li&gt;
&lt;li&gt;Epoch AI. (2024). AI Benchmarking Hub. Retrieved from &lt;a href="https://epoch.ai/" rel="noopener noreferrer"&gt;https://epoch.ai/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Marmelab. (2025). AI's Environmental Impact: Making an Informed Choice. Marmelab Blog. Retrieved from &lt;a href="https://marmelab.com/blog/2025/03/19/ai-carbon-footprint.html" rel="noopener noreferrer"&gt;https://marmelab.com/blog/2025/03/19/ai-carbon-footprint.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Sánchez-Mompó, A., et al. (2025). Green MLOps to Green GenOps: An Empirical Study of Energy Consumption in Discriminative and Generative AI Operations. arXiv preprint arXiv:2503.23934.&lt;/li&gt;
&lt;li&gt;De Vries, A. (2023). The Growing Energy Consumption of Artificial Intelligence. Joule, 7(10), 2191-2194.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>sustainable</category>
      <category>ai</category>
    </item>
    <item>
      <title>Responsive and sustainable images in markdown (commonmark) using haskell MMark</title>
      <dc:creator>Injeniero</dc:creator>
      <pubDate>Fri, 01 Aug 2025 03:36:09 +0000</pubDate>
      <link>https://dev.to/injeniero/responsive-and-sustainable-images-in-markdown-commonmark-using-haskell-mmark-1gjm</link>
      <guid>https://dev.to/injeniero/responsive-and-sustainable-images-in-markdown-commonmark-using-haskell-mmark-1gjm</guid>
      <description>&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;For full article please read &lt;a href="https://injeniero.com/en/blog/responsive-sustainable-images-markdown-commonmark-haskell-mmark" rel="noopener noreferrer"&gt;https://injeniero.com/en/blog/responsive-sustainable-images-markdown-commonmark-haskell-mmark&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;MMark, created by Mark Karpov, is a great haskell library that uses Commonmark specification to transform Markdown into HTML and is based on the following philosophy:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Strict, explicitly specifying where parsing errors occur and what they are about.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extensible, where the user can compose extensions that add functionality.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Since it's extensible, it's pretty easy to create useful extensions that can enrich your workflow from Markdown to a website. &lt;/p&gt;

&lt;p&gt;Web sustainability is something that is often overlooked by programmers, however, &lt;strong&gt;given the non-negligible CO2 emissions of the internet&lt;/strong&gt;, it is worth mentioning. &lt;/p&gt;

&lt;p&gt;Here I post an example of an extension to produce responsive and sustainable images in Markdown. &lt;/p&gt;

&lt;p&gt;Feel free to improve on it, and more importantly, consider producing sustainable images in your projects.&lt;/p&gt;

&lt;p&gt;Cheers,&lt;br&gt;
Injeniero&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Some familiarity with the Haskell language&lt;/li&gt;
&lt;li&gt;Have GHC and cabal installed&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Code&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="cp"&gt;{-# LANGUAGE OverloadedStrings #-}&lt;/span&gt;
&lt;span class="cp"&gt;{-# LANGUAGE DeriveGeneric #-}&lt;/span&gt;

&lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Main&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;

&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="k"&gt;qualified&lt;/span&gt; &lt;span class="nn"&gt;Data.Text.IO&lt;/span&gt;      &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="k"&gt;qualified&lt;/span&gt; &lt;span class="nn"&gt;Data.Text.Lazy.IO&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;TL&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="k"&gt;qualified&lt;/span&gt; &lt;span class="nn"&gt;Text.MMark&lt;/span&gt;        &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;MMark&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="k"&gt;qualified&lt;/span&gt; &lt;span class="nn"&gt;Text.Megaparsec&lt;/span&gt;   &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;M&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="k"&gt;qualified&lt;/span&gt; &lt;span class="nn"&gt;Text.MMark.Extension&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;Ex&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="k"&gt;qualified&lt;/span&gt; &lt;span class="nn"&gt;Data.Text&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;Te&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="k"&gt;qualified&lt;/span&gt; &lt;span class="nn"&gt;Text.URI&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;URI&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="k"&gt;qualified&lt;/span&gt; &lt;span class="nn"&gt;System.FilePath&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;FP&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="k"&gt;qualified&lt;/span&gt; &lt;span class="nn"&gt;Data.ByteString.Lazy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;GHC.Generics&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Lucid.Base&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;makeAttribute&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Lucid&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Maybe&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fromMaybe&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Text.URI.Lens&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;uriPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Lens.Micro&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;^.&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Aeson&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ToJSON&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;FromJSON&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;System.Environment&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nf"&gt;getArgs&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;-- Define Config data structure&lt;/span&gt;
&lt;span class="kr"&gt;data&lt;/span&gt; &lt;span class="kt"&gt;Config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Config&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;confSizes&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;confSet&lt;/span&gt;   &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;deriving&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Show&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Generic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Eq&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;defaultConfig&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Config&lt;/span&gt;
&lt;span class="n"&gt;defaultConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Config&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;confSizes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"(max-width:600px) 100vw, 850px"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;confSet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;850&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;

&lt;span class="c1"&gt;-- Parsing the Config data&lt;/span&gt;
&lt;span class="kr"&gt;instance&lt;/span&gt; &lt;span class="kt"&gt;FromJSON&lt;/span&gt; &lt;span class="kt"&gt;Config&lt;/span&gt;
&lt;span class="kr"&gt;instance&lt;/span&gt; &lt;span class="kt"&gt;ToJSON&lt;/span&gt; &lt;span class="kt"&gt;Config&lt;/span&gt;

&lt;span class="c1"&gt;-- Function to read the config file&lt;/span&gt;
&lt;span class="n"&gt;readConfig&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;FilePath&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;IO&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;readConfig&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;jsonData&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="kt"&gt;B&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;readFile&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;
  &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt; &lt;span class="n"&gt;jsonData&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;IO&lt;/span&gt; &lt;span class="nb"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;getArgs&lt;/span&gt;
  &lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;
  &lt;span class="n"&gt;txt&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="kt"&gt;T&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;readFile&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;readConfig&lt;/span&gt; &lt;span class="s"&gt;"config.json"&lt;/span&gt;
  &lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="n"&gt;conf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;case&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt;
              &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;
              &lt;span class="kt"&gt;Nothing&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;defaultConfig&lt;/span&gt;
  &lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="n"&gt;sizes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;confSizes&lt;/span&gt; &lt;span class="n"&gt;conf&lt;/span&gt;
  &lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;confSet&lt;/span&gt; &lt;span class="n"&gt;conf&lt;/span&gt;
  &lt;span class="kr"&gt;case&lt;/span&gt; &lt;span class="kt"&gt;MMark&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;txt&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt;
    &lt;span class="kt"&gt;Left&lt;/span&gt; &lt;span class="n"&gt;bundle&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;putStrLn&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errorBundlePretty&lt;/span&gt; &lt;span class="n"&gt;bundle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kt"&gt;Right&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;TL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;writeFile&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;FP&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;takeBaseName&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="s"&gt;".html"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;renderText&lt;/span&gt; &lt;span class="c1"&gt;-- from Lucid&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;MMark&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;render&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;MMark&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;useExtensions&lt;/span&gt;
             &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;imgLazyExt&lt;/span&gt;
             &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;imgResExt'&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;sizes&lt;/span&gt;
             &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;audioExt&lt;/span&gt;
             &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;

&lt;span class="c1"&gt;-- Common function to extract base URL components&lt;/span&gt;
&lt;span class="n"&gt;extractImageAttributes&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;URI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;URI&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;extractImageAttributes&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="n"&gt;url'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;clearStr&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kt"&gt;URI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;
      &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;FP&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;takeBaseName&lt;/span&gt; &lt;span class="n"&gt;url'&lt;/span&gt;
      &lt;span class="n"&gt;ext&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;FP&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;takeExtension&lt;/span&gt; &lt;span class="n"&gt;url'&lt;/span&gt;
      &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;FP&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;takeDirectory&lt;/span&gt; &lt;span class="n"&gt;url'&lt;/span&gt;
  &lt;span class="kr"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;--EXTENSIONS&lt;/span&gt;
&lt;span class="c1"&gt;-- Adding lazy attribute to images composable&lt;/span&gt;
&lt;span class="n"&gt;imgLazyExt&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;MMark&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Extension&lt;/span&gt;
&lt;span class="n"&gt;imgLazyExt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inlineRender&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;old&lt;/span&gt; &lt;span class="n"&gt;inline&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class="kr"&gt;case&lt;/span&gt; &lt;span class="n"&gt;inline&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt;
    &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Image&lt;/span&gt; &lt;span class="n"&gt;txt&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fromMaybe&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;old&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
      &lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="n"&gt;wo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kt"&gt;Te&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unpack&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;
      &lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="n"&gt;mattr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;if&lt;/span&gt; &lt;span class="kt"&gt;Te&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;null&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt; &lt;span class="kt"&gt;Nothing&lt;/span&gt; &lt;span class="kr"&gt;else&lt;/span&gt; &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;
      &lt;span class="kr"&gt;if&lt;/span&gt; &lt;span class="s"&gt;"lazy"&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt; &lt;span class="n"&gt;wo&lt;/span&gt;
        &lt;span class="kr"&gt;then&lt;/span&gt; &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;old&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Image&lt;/span&gt; &lt;span class="n"&gt;txt&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="n"&gt;mattr&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;loading_&lt;/span&gt; &lt;span class="s"&gt;"lazy"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="kr"&gt;else&lt;/span&gt; &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="n"&gt;old&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Image&lt;/span&gt; &lt;span class="n"&gt;txt&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="n"&gt;mattr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;old&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;

&lt;span class="c1"&gt;-- Adding srcset and sizes attributes to images composable&lt;/span&gt;
&lt;span class="n"&gt;imgResExt&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;MMark&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Extension&lt;/span&gt;
&lt;span class="n"&gt;imgResExt&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;sizes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inlineRender&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;old&lt;/span&gt; &lt;span class="n"&gt;inline&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class="kr"&gt;case&lt;/span&gt; &lt;span class="n"&gt;inline&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt;
    &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Image&lt;/span&gt; &lt;span class="n"&gt;txt&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fromMaybe&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;old&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
      &lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;extractImageAttributes&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;
      &lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="n"&gt;mattr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;if&lt;/span&gt; &lt;span class="kt"&gt;Te&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;null&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt; &lt;span class="kt"&gt;Nothing&lt;/span&gt; &lt;span class="kr"&gt;else&lt;/span&gt; &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;
      &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;old&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Image&lt;/span&gt; &lt;span class="n"&gt;txt&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="n"&gt;mattr&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                    &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;srcset_&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;imgSet&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;ext&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sizes_&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Te&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pack&lt;/span&gt; &lt;span class="n"&gt;sizes&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;old&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;
&lt;span class="c1"&gt;-- Extension for images without title attribute but adding srcset and sizes attributes&lt;/span&gt;
&lt;span class="n"&gt;imgResExt'&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;MMark&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Extension&lt;/span&gt;
&lt;span class="n"&gt;imgResExt'&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;sizes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inlineRender&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;old&lt;/span&gt; &lt;span class="n"&gt;inline&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class="kr"&gt;case&lt;/span&gt; &lt;span class="n"&gt;inline&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt;
    &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Image&lt;/span&gt; &lt;span class="n"&gt;txt&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fromMaybe&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;old&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
      &lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;extractImageAttributes&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;
      &lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="n"&gt;src'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;URI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;
      &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="n"&gt;img_&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;alt_&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;asPlainText&lt;/span&gt; &lt;span class="n"&gt;txt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;src_&lt;/span&gt; &lt;span class="n"&gt;src'&lt;/span&gt;
                    &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;srcset_&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;imgSet&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;ext&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sizes_&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Te&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pack&lt;/span&gt; &lt;span class="n"&gt;sizes&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;old&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;

&lt;span class="c1"&gt;-- imgSet function&lt;/span&gt;
&lt;span class="n"&gt;imgSet&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Te&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Text&lt;/span&gt;
&lt;span class="n"&gt;imgSet&lt;/span&gt; &lt;span class="n"&gt;filebase&lt;/span&gt; &lt;span class="n"&gt;ext&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Te&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pack&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="n"&gt;concatMap&lt;/span&gt; &lt;span class="n"&gt;formatSize&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;formatSize&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;last&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kr"&gt;where&lt;/span&gt;
    &lt;span class="n"&gt;comma&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="kr"&gt;if&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;/=&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt; &lt;span class="s"&gt;","&lt;/span&gt; &lt;span class="kr"&gt;else&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;
    &lt;span class="n"&gt;formatSize&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;filebase&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="s"&gt;"_"&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;ext&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;  &lt;span class="s"&gt;" "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="s"&gt;"w"&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;comma&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;

&lt;span class="c1"&gt;-- Helper function to create srcset attribute&lt;/span&gt;
&lt;span class="n"&gt;srcset_&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Te&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Text&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Attribute&lt;/span&gt;
&lt;span class="n"&gt;srcset_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;makeAttribute&lt;/span&gt; &lt;span class="s"&gt;"srcset"&lt;/span&gt;

&lt;span class="c1"&gt;-- Clear quotes from string&lt;/span&gt;
&lt;span class="n"&gt;clearStr&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;span class="n"&gt;clearStr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(`&lt;/span&gt;&lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="c1"&gt;-- Bonus: Audio extension to render audio links&lt;/span&gt;
&lt;span class="n"&gt;audioExt&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;MMark&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Extension&lt;/span&gt;
&lt;span class="n"&gt;audioExt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inlineRender&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;old&lt;/span&gt; &lt;span class="n"&gt;inline&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class="kr"&gt;case&lt;/span&gt; &lt;span class="n"&gt;inline&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt;
    &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Link&lt;/span&gt; &lt;span class="n"&gt;txt&lt;/span&gt; &lt;span class="n"&gt;uri&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="kr"&gt;case&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt; &lt;span class="o"&gt;^.&lt;/span&gt; &lt;span class="n"&gt;uriPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;asPlainText&lt;/span&gt; &lt;span class="n"&gt;txt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;[]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;old&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"audio"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
          &lt;span class="n"&gt;audio_&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;controls_&lt;/span&gt; &lt;span class="s"&gt;"controls"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;preload_&lt;/span&gt; &lt;span class="s"&gt;"none"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt;
               &lt;span class="n"&gt;source_&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;src_&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;URI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;type_&lt;/span&gt; &lt;span class="s"&gt;"audio/mp4"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;old&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;
    &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;old&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Use&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a directory &amp;amp; cd to the directory&lt;/li&gt;
&lt;li&gt;Run ‘cabal init’ command in the terminal within the directory&lt;/li&gt;
&lt;li&gt;Create a markdown file, example.md or any name and add some images&lt;/li&gt;
&lt;li&gt;Copy the sourcecode to the Main.hs file in the /app folder replacing the one created by cabal init
Add the dependencies in the.cabal file, line build-depends:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;project.cabal&lt;/p&gt;

&lt;p&gt;build-depends: base ^&amp;gt;=4.21.0.0, text&amp;gt;=2.1.2, mmark &amp;gt;= 0.0.8.0, megaparsec &amp;gt;= 9.7.0, modern-uri &amp;gt;= 0.3.6.1, filepath &amp;gt;= 1.5.4.0, microlens &amp;gt;= 0.4.14.0, lucid &amp;gt;= 2.11.20250303, aeson &amp;gt;= 2.2.3.0, bytestring &amp;gt;= 0.12.2.0&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run cabal update &amp;amp;&amp;amp; cabal build&lt;/li&gt;
&lt;li&gt;Run cabal run exes -- yourfile.md&lt;/li&gt;
&lt;li&gt;See the yourfile.html file with the resulting HTML&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Full code also available on github &lt;a href="https://github.com/injeniero-com/injeniero" rel="noopener noreferrer"&gt;https://github.com/injeniero-com/injeniero&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkzehb6s6lvydpwpj11vm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkzehb6s6lvydpwpj11vm.jpg" alt="Injeniera from injeniero.com/en/" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cheers,&lt;br&gt;
Injeniero &lt;a href="https://injeniero.com" rel="noopener noreferrer"&gt;https://injeniero.com&lt;/a&gt;&lt;br&gt;
Best sustainable web development agency&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
