Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function HtmlOutput = convertMarkdownToHtml2(InputFile, options)
- % CONVERTMARKDOWNTOHTML Convert a Markdown file to HTML
- % HtmlOutput = convertMarkdownToHtml(InputFile) converts the markdown file
- % to HTML and saves it with the same name but .html extension
- %
- % HtmlOutput = convertMarkdownToHtml(InputFile, 'OutputFile', filename)
- % saves the HTML to the specified filename
- %
- % HtmlOutput = convertMarkdownToHtml(..., 'DoBase64Encoding', true)
- % encodes images as base64 within the HTML file
- %
- % HtmlOutput = convertMarkdownToHtml(..., 'DoSyntaxHighlight', true)
- % adds syntax highlighting for code blocks using Prism.js
- arguments
- InputFile (1,1) string {mustBeFile}
- options.OutputFile (1,1) string = replace(InputFile, '.md', '.html')
- options.DoBase64Encoding (1,1) logical = false
- options.DoSyntaxHighlight (1,1) logical = false
- end
- % Read the markdown file
- FileContent = string(fileread(InputFile));
- Lines = splitlines(FileContent);
- % Initialize HTML content
- HtmlContent = strings(0);
- HtmlContent = [HtmlContent; "<!DOCTYPE html>"; "<html>"; "<head>"; ...
- "<meta charset=""utf-8"">"];
- % Add Prism.js resources if syntax highlighting is enabled
- if options.DoSyntaxHighlight
- HtmlContent = [HtmlContent;
- "<link href=""https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css"" rel=""stylesheet"" />";
- "<link href=""https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/line-numbers/prism-line-numbers.min.css"" rel=""stylesheet"" />";
- ];
- end
- HtmlContent = [HtmlContent; "</head>"];
- if options.DoSyntaxHighlight
- HtmlContent = [HtmlContent; "<body class=""line-numbers"">"];
- else
- HtmlContent = [HtmlContent; "<body>"];
- end
- % Process the content
- IsInCodeBlock = false;
- IsInList = false;
- CurrentCodeLanguage = "";
- for i = 1:length(Lines)
- CurrentLine = Lines(i);
- % Handle code blocks
- if startsWith(strip(CurrentLine), "```")
- if ~IsInCodeBlock
- % Starting a code block
- Language = extractAfter(strip(CurrentLine), "```");
- CurrentCodeLanguage = determineLanguage(Language);
- if options.DoSyntaxHighlight
- HtmlContent = [HtmlContent; ...
- sprintf("<pre class=""line-numbers""><code class=""language-%s"">", ...
- CurrentCodeLanguage)];
- else
- HtmlContent = [HtmlContent; "<pre><code>"];
- end
- IsInCodeBlock = true;
- else
- % Ending a code block
- HtmlContent = [HtmlContent; "</code></pre>"];
- IsInCodeBlock = false;
- CurrentCodeLanguage = "";
- end
- continue;
- end
- if IsInCodeBlock
- HtmlContent = [HtmlContent; htmlEncode(CurrentLine)];
- continue;
- end
- % Handle headers
- if startsWith(strip(CurrentLine), "#")
- [HeadingLevel, HeadingText] = parseHeading(CurrentLine);
- HtmlContent = [HtmlContent; ...
- sprintf("<h%d>%s</h%d>", HeadingLevel, HeadingText, HeadingLevel)];
- continue;
- end
- % Handle task lists and regular lists
- if startsWith(strip(CurrentLine), "- ")
- if ~IsInList
- HtmlContent = [HtmlContent; "<ul>"];
- IsInList = true;
- end
- % Check for task list item
- if contains(CurrentLine, "- [ ]") || contains(CurrentLine, "- [x]")
- IsChecked = contains(CurrentLine, "- [x]");
- TaskText = extractAfter(CurrentLine, "]");
- CheckboxHtml = sprintf('<input type="checkbox" %s disabled> %s', ...
- conditionalString(IsChecked, "checked", ""), ...
- strip(TaskText));
- HtmlContent = [HtmlContent; "<li>" + CheckboxHtml + "</li>"];
- else
- ListItem = extractAfter(CurrentLine, "- ");
- HtmlContent = [HtmlContent; "<li>" + processInlineMarkdown(ListItem) + "</li>"];
- end
- continue;
- elseif IsInList && ~isempty(strip(CurrentLine))
- HtmlContent = [HtmlContent; "</ul>"];
- IsInList = false;
- end
- % Handle images
- if contains(CurrentLine, "![")
- HtmlContent = [HtmlContent; processImages(CurrentLine, ...
- fileparts(InputFile), options.DoBase64Encoding)];
- continue;
- end
- % Handle regular paragraphs
- if ~isempty(strip(CurrentLine))
- HtmlContent = [HtmlContent; "<p>" + processInlineMarkdown(CurrentLine) + "</p>"];
- end
- end
- % Close any open lists
- if IsInList
- HtmlContent = [HtmlContent; "</ul>"];
- end
- % Add Prism.js scripts if syntax highlighting is enabled
- if options.DoSyntaxHighlight
- HtmlContent = [HtmlContent;
- "<script src=""https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-core.min.js""></script>";
- "<script src=""https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js""></script>";
- "<script src=""https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/line-numbers/prism-line-numbers.min.js""></script>";
- "<script src=""https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-matlab.min.js""></script>";
- ];
- end
- % Close HTML document
- HtmlContent = [HtmlContent; "</body>"; "</html>"];
- % Write the output file
- HtmlOutput = options.OutputFile;
- writelines(HtmlContent, HtmlOutput);
- end
- function [Level, Text] = parseHeading(Line)
- % Parse markdown heading to get level and text
- LineChar = Line{1};
- Level = sum(LineChar == '#');
- Text = strip(extractAfter(Line, repmat('#', 1, Level)));
- end
- function Output = processInlineMarkdown(Line)
- % Process inline markdown syntax
- % Bold
- Line = regexprep(Line, '\*\*([^\*]+)\*\*', '<strong>$1</strong>');
- % Italic
- Line = regexprep(Line, '\*([^\*]+)\*', '<em>$1</em>');
- % Code
- Line = regexprep(Line, '`([^`]+)`', '<code>$1</code>');
- % Links
- Line = regexprep(Line, '\[([^\]]+)\]\(([^\)]+)\)', '<a href="$2">$1</a>');
- Output = Line;
- end
- function EncodedStr = htmlEncode(Str)
- % Encode special HTML characters
- EncodedStr = replace(Str, "&", "&");
- EncodedStr = replace(EncodedStr, "<", "<");
- EncodedStr = replace(EncodedStr, ">", ">");
- EncodedStr = replace(EncodedStr, """", """);
- end
- function Output = processImages(Line, BasePath, DoBase64)
- % Process markdown image syntax
- [AltText, ImagePath] = extractImageInfo(Line);
- if ~startsWith(ImagePath, ["http://", "https://", "/"])
- % Relative path - make it absolute
- ImagePath = fullfile(BasePath, ImagePath);
- end
- if DoBase64 && ~startsWith(ImagePath, ["http://", "https://"])
- try
- [~, ~, Ext] = fileparts(ImagePath);
- % Correctly read binary file data
- Fid = fopen(ImagePath, 'rb');
- if Fid == -1
- error('Could not open image file');
- end
- ImageData = fread(Fid, Inf, '*uint8');
- fclose(Fid);
- % Convert to base64
- Base64Data = matlab.net.base64encode(ImageData);
- % Get correct MIME type
- MimeType = getMimeType(Ext);
- ImgSrc = sprintf('data:%s;base64,%s', MimeType, char(Base64Data));
- catch ME
- warning('Could not encode image %s: %s', ImagePath, ME.message);
- ImgSrc = ImagePath;
- end
- else
- ImgSrc = ImagePath;
- end
- Output = sprintf('<img src="%s" alt="%s">', ImgSrc, AltText);
- end
- function [AltText, ImagePath] = extractImageInfo(Line)
- % Extract alt text and image path from markdown image syntax
- LineChar = Line{1};
- AltStart = find(LineChar == '[', 1) + 1;
- AltEnd = find(LineChar == ']', 1) - 1;
- PathStart = find(LineChar == '(', 1) + 1;
- PathEnd = find(LineChar == ')', 1) - 1;
- AltText = string(LineChar(AltStart:AltEnd));
- ImagePath = string(LineChar(PathStart:PathEnd));
- end
- function MimeType = getMimeType(Ext)
- % Return appropriate MIME type for the image extension
- switch lower(Ext)
- case '.jpg'
- MimeType = 'image/jpeg';
- case '.jpeg'
- MimeType = 'image/jpeg';
- case '.png'
- MimeType = 'image/png';
- case '.gif'
- MimeType = 'image/gif';
- case '.webp'
- MimeType = 'image/webp';
- case '.svg'
- MimeType = 'image/svg+xml';
- otherwise
- MimeType = 'image/png'; % default fallback
- end
- end
- function Language = determineLanguage(Lang)
- % Determine the language class for Prism.js
- % Focus on MATLAB, fallback to plain text for others
- Lang = lower(strip(Lang));
- if isempty(Lang)
- Language = "plain";
- elseif ismember(Lang, ["matlab", "m"])
- Language = "matlab";
- else
- Language = "plain";
- end
- end
- function Str = conditionalString(Condition, TrueStr, FalseStr)
- % Return string based on condition
- if Condition
- Str = TrueStr;
- else
- Str = FalseStr;
- end
- end
Add Comment
Please, Sign In to add comment