How to preview mermaid graph in RStudio viewer? - r-markdown

Background:
It's possible to "use of an external text file with the .mmd file extension can provide the advantage of syntax coloring and previewing in the RStudio Viewer" (DiagrammeR Docs)
What should look like this:
Problem:
In my minimal working example the graph is not rendered in the viewer panel but the plain text from the mermaid.mmd-file is printed (see below). How to fix this behavior, so that the chart is rendered?
mermaid.mmd:
graph LR
A-->B
Output in viewer panel:
The text inside the mermaid.mmd-file is printed in the viewer panel, but not the rendered graph
My Setup
RStudio 2022.07.2 (<- newest version)
R version 4.2.1 (2022-06-23 ucrt)
DiagrammerR version 1.0.9 (<- newest version)
knitr version 1.40 (<- newest version)

Technical Reason for the Problem
I found the problem. It's the implementation of the handling of extern .mmd-files in the DigrammeR::mermaid()-function.
Within the mermaid()-function the htmlwidgets::createWidget(name = "DiagrammeR", x = x, width = NULL, height = NULL, package = "DiagrammeR")-functions takes the processed input x and renders the graph. This functions expects an input in the format "\ngraph LR\nA-->B\n", where every input start and ends with "\n" and each line in your mermaid-code is also separated by "\n". But the input from an extern .mmd-file (readLines("mermaid.mmd", encoding = "UTF-8", warn = FALSE)) looks like this:
"graph LR" "A-->B" (separated strings for each line of mermaid-code)
Transforming the input into the required format can be done by mermaid.code <- paste0("\n",paste0(mermaid.code, collapse = "\n"),"\n")
Unfortunately this processing step is not implemented for extern .mmd-files in DigrammeR::mermaid()
Soultion
Build a new mermaid()-function, including the required processing step
Replace the mermaid()-function within the DiagrammeR-packages by the new function
# Build new mermaid()-function
mermaid.new = function (diagram = "", ..., width = NULL, height = NULL) {
is_connection_or_file <- inherits(diagram[1], "connection") ||
file.exists(diagram[1])
if (is_connection_or_file) {
diagram <- readLines(diagram, encoding = "UTF-8", warn = FALSE)
diagram <- paste0("\n",paste0(d, collapse = "\n"),"\n") # NEW LINE
}
else {
if (length(diagram) > 1) {
nosep <- grep("[;\n]", diagram)
if (length(nosep) < length(diagram)) {
diagram[-nosep] <- sapply(diagram[-nosep], function(c) {
paste0(c, ";")
})
}
diagram = paste0(diagram, collapse = "")
}
}
x <- list(diagram = diagram)
htmlwidgets::createWidget(name = "DiagrammeR", x = x, width = width,
height = height, package = "DiagrammeR")
}
#Replace mermaid()-function in DiagrammeR-package
if(!require("R.utils")) install.packages("R.utils")
library(R.utils)
reassignInPackage(name="mermaid", pkgName="DiagrammeR", mermaid.new, keepOld=FALSE)
# Test new function
DiagrammeR::mermaid("mer.mmd")

You can preview your codes as simple as running them like this:
library(DiagrammeR)
DiagrammeR(
"
**graph LR
A-->B**
")
You should be able to see
this

Related

How I can zoom-in for a sankey plot in R-shiny?

I have been trying to create a R shiny dashboard including a sankey network. It is working without any problem, however some of the plots seem quite clutter due to high number of nodes and connections based on some input parameters. As an alternative solution, i am trying to implement zooming feature triggered by double click by the user, but I am getting an error of "unused element" by shiny.
The part of the ui code including double click is:
sankeyNetworkOutput("diagram",dblclick = "plot1_dblclick",
brush = brushOpts(id = "plot1_brush",resetOnNew = TRUE)
The server side code is:
output$diagram<- renderSankeyNetwork({
sankeyNetwork(Links = rv1()$links, Nodes = rv1()$nodes,
Source = "IDsource", Target = "IDtarget",
Value = "value", NodeID = "name",
iterations = 0, sinksRight=TRUE,
fontSize=13, nodePadding=20)
observeEvent(input$plot1_dblclick, {
brush <- input$plot1_brush
if (!is.null(brush)) {
ranges$x <- c(brush$xmin, brush$xmax)
ranges$y <- c(brush$ymin, brush$ymax)
} else {
ranges$x <- NULL
ranges$y <- NULL
}
})
})
I would really appreciate if I can get any help regarding to that!
Thanks!

Conditional highlighting of output

I suppose I'm missing something obvious here, but I've been stumped for a while on this. I have my .Rmd file setup, and almost everything knits fine to Markdown_strict and latex_fragment (with a little preprocessing on that one), but nevermind for now.
Here's a sample.Rmd file that I have as input. I couldn't figure how to nest backticks, so for now it's pseudo-escaped.
---
title: "Sample"
output:
md_document:
preserve_yaml: yes
variant: markdown_strict+raw_html+all_symbols_escapable
latex_fragment: default
knit: (function(inputFile, encoding) {
rmarkdown::render(inputFile, encoding = encoding,
output_dir = ".", output_format = "all") })
---
\`\`\`{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
sqlcode <- function(sql, code = "") {
if (knitr::is_latex_output()) {
return(paste0('\n```{=sql}\n',sql,'\n```\n'))
} else if (!knitr::is_html_output(excludes = "markdown")) {
if (length(code)>0) {
code = paste0(" ", code," ")
} else {
code = " "
}
pre <- paste0("{{< sql",code,">}}\n")
post <- "\n{{< /sql >}}"
return(knitr::raw_html(paste0(pre,sql,post)))
}
}
\`\`\`
This is a sample.
\`\`\`{r echo=FALSE}
sqlcode("SELECT *
FROM TABLE", "sample")
\`\`\`
The LaTeX fragment I want is:
This is a sample.
\begin{Shaded}
\begin{Highlighting}[]
\KeywordTok{SELECT} \OperatorTok{*}
\KeywordTok{FROM}\NormalTok{ TABLE}
\end{Highlighting}
\end{Shaded}
What I get is:
This is a sample.
\begin{verbatim}
## [1] "\n```{=sql}\nSELECT *\nFROM TABLE\n```\n"
\end{verbatim}
And on the MD side, I do get what I want, that is:
---
title: "Sample"
output:
md_document:
preserve_yaml: yes
variant: markdown_strict+raw_html+all_symbols_escapable
latex_fragment: default
knit: (function(inputFile, encoding) {
rmarkdown::render(inputFile, encoding = encoding,
output_dir = ".", output_format = "all") })
---
This is a sample.
{{< sql sample >}}
SELECT *
FROM TABLE
{{< /sql >}}
For those familiar with Hugo, these are custom shortcodes I use for a Hugo-generated site. The lack of ident of the SQL code is on purpose, it's then highlighted through hugo.
At any rate, how do I get sqlcode(...) to output a fenced block that pandoc will correctly highlight in LaTeX, or alternatively, what part of pdf_document.R should I customize in order to achieve that ?
I've tried various knitr functions that mark output and I can get an intermediary MD file that I could process to remove some markers, but I can't manage to process that intermediary MD file before knitr sends it to Pandoc.
After a while of trial and error I figured it out. It's as simple as changing one line -_-
sqlcode <- function(sql, code = "") {
if (knitr::is_latex_output()) {
knitr::raw_output(paste0('\n```sql\n',sql,'\n```\n'), markers=NULL)
} else if (!knitr::is_html_output(excludes = "markdown")) {
if (length(code)>0) {
code = paste0(" ", code," ")
} else {
code = " "
}
pre <- paste0("{{< sql",code,">}}\n")
post <- "\n{{< /sql >}}"
return(knitr::raw_html(paste0(pre,sql,post)))
}
}

Aspose.Barcode cannot read DecodeType.Code128 barcode

The aspose.barcode reader is unable to read the barcode of type DecodeType.Code128
Workflow Steps
1>Using Aspose.Barcode we have created a barcode using DecodeType.Code128 and put on PDF page ( our clients use this page as separator sheet)
2>Our client then insert this barcode page between several physical documents and scanned them all, which creates big single PDF
3>Our splitting process then, loop through all pages and check if any page is barcode page, and splits the big PDF into individual small PDF
Issue is some times the scanned quality of the barcode is not that great, and in such case ASPOSE.Barcode unable to read the barcode.
I have attached couple of barcode PDF with low scanned quality, and aspose is not able to read these barcodes. I have tried different combinations of RecognitionMode and ManualHints options without any luck
Below is my code to identity barcode page
using (var fs = new FileStream(file, FileMode.Open))
{
var pdfDocument = new Document(fs);
foreach (Page page in pdfDocument.Pages)
{
var isSeparator = splitter.IsSeparator(page);
Assert.IsTrue(isSeparator);
}
}
public bool IsSeparator(Page page)
{
if (page.Resources.Images != null && page.Resources.Images.Count >= 1)
{
var img = page.Resources.Images[1];
using (MemoryStream barcodeImage = new MemoryStream())
{
img.Save(barcodeImage, ImageFormat.Jpeg);
barcodeImage.Seek(0L, SeekOrigin.Begin);
using (BarCodeReader barcodeReader = new BarCodeReader(barcodeImage, _barcodeDecodeType))
{
barcodeReader.RecognitionMode = RecognitionMode.MaxQuality;
while (barcodeReader.Read())
{
var barcodeText = barcodeReader.GetCodeText();
if (barcodeText.ToLower() == "eof")
{
return true;
}
}
}
}
}
return false;
}
Unable to reproduce the issue at my end. I used the following sample code snippet to recognize the barcode along with latest version of the API. It is always recommended to use the latest version of the API as it contains new features and improvements.
CODE:
Aspose.Pdf.License licensePdf = new Aspose.Pdf.License();
licensePdf.SetLicense(#"Aspose.Total.lic");
// bind the pdf document
Aspose.Pdf.Facades.PdfExtractor pdfExtractor = new Aspose.Pdf.Facades.PdfExtractor();
pdfExtractor.BindPdf(#"173483_2.pdf");
// extract the images
pdfExtractor.ExtractImage();
// save images to stream in a loop
while (pdfExtractor.HasNextImage())
{
// save image to stream
System.IO.MemoryStream imageStream = new System.IO.MemoryStream();
pdfExtractor.GetNextImage(imageStream);
imageStream.Position = 0;
Aspose.BarCode.BarCodeRecognition.BarCodeReader barcodeReader =
new Aspose.BarCode.BarCodeRecognition.BarCodeReader(imageStream);
while (barcodeReader.Read())
{
Console.WriteLine("Codetext found: " + barcodeReader.GetCodeText() + ", Symbology: " + barcodeReader.GetCodeType().ToString());
}
// close the reader
barcodeReader.Close();
}
Further to update you that the same query has been post on Aspose.BarCode support forum. You may please visit the link for details.
I work as developer evangelist at Aspose.

How to display Highlighted text using Solrj

I am new to Solr and SolrJ. I am trying to use for a desktop application and I have files(text files) to index and search. I wanted to use highlight feature and display the fragments with highlight,but I don't get them to display in yellow background as you highlight a text, please let me know how to display the text in yellow background.
here is my code snippet:
public void TestHighLight(SolrQuery query) throws
SolrServerException, IOException {
query.setQuery("*");
query.set("hl", "true");
query.set("hl.snippets", "5");
query.set("q", "text:Pune");
query.set("hl.fl", "*");
QueryResponse queryResponse = client.query(query);
SolrDocumentList docs = queryResponse.getResults();
Iterator iter = docs.iterator();
for (int i = 0; i < docs.size(); i++) {
iter = docs.get(i).getFieldNames().iterator();
String fldVal = (String) docs.get(i).getFieldValue("id");
String docID = (String) docs.get(i).get("id");
while (iter.hasNext()) {
String highlighText = getHighlightedText(queryResponse,
"text", docID);
System.out.println(" tHighlightedText is " + highlighText );
}
}
}
The output looks like this:how do I color it ?
[ for Java Developer at Pune
Thanks a lot !
Set the pre and post parameters of the highlighter. Specifies the “tag” to use before a highlighted term. This can be any string, but is most often an HTML or XML tag.
e.g:
solrQueryHandler.setHighlightSimplePre("<font color="yellow">");
solrQueryHandler.setHighlightSimplePost("/font");
But note that this will work only for the Original Highlighter

different output with mono on linux as on visual studio on win7 with calling a webservice

I use the Exchange webservices to extract attachments from exchange mailserver.
When i call the code on linux with mono a certain text attachment contain some mixed-up strings.
like so
"sam winglin vz" becomes "sainglin vz" -> so it is missing "m w".
I see this about 3 times in a 150kb file. 3 bytes are missing in the linux output vs the windows output.
When i extract it from visual studio the text attachment is perfect.
It is like this example
Save attachments from exchange inbox
Any idea in what direction i should look to fix this?
Code:
#r "Microsoft.Exchange.WebServices.dll"
open Microsoft
open Microsoft.Exchange.WebServices.Data
open System
open System.Net
type PgzExchangeService(url,user,password) =
let service = new ExchangeService(ExchangeVersion.Exchange2007_SP1,
TimeZoneInfo.CreateCustomTimeZone("Central Standard Time",new TimeSpan(-6, 0, 0),"(GMT-06:00) Central Time (US & Canada)","Central Standard Time"))
do
ServicePointManager.ServerCertificateValidationCallback <- ( fun _ _ _ _ -> true )
service.Url <- new Uri(url)
service.Credentials <- new WebCredentials(user, password, "domain")
member this.Service with get() = service
member this.InboxItems = this.Service.FindItems(WellKnownFolderName.Inbox, new ItemView(10))
member this.GetFileAttachments ( item : Item ) =
let emailMessage =
EmailMessage.Bind( this.Service,
item.Id,
new PropertySet(BasePropertySet.IdOnly, ItemSchema.Attachments))
item, emailMessage.Attachments |> Seq.choose (fun attachment -> match box attachment with
| :? FileAttachment as x -> Some(x) | _ -> None)
let mailAtdomain = new PgzExchangeService("https://xx.xx.XX.XX/EWS/Exchange.asmx", "user", "passw")
let printsave (item : Item ,att : seq<FileAttachment>) =
if (Seq.length att) > 0 then
printfn "%A - saving %i attachments" item.Subject (Seq.length att)
att |> Seq.iter ( fun attachment -> printfn "%A" attachment.Name
attachment.Load(#"/tmp/test/" + attachment.Name ) )
// filter so we only have items with attachements and ...
let itemsWithAttachments = mailAtdomain.InboxItems
|> Seq.map mailAtdomain.GetFileAttachments
|> Seq.iter printsave
The code doesn't run on Windows with mono due to a bug in TimeZoneInfo
This sample code runs on linux but not on windows. because of the TimeZoneInfo bug.
But with this the code that works on linux to extract attachments.
Try csv attachments and see if the result is the same. i loose data ! about 3 bytes every somemany lines
mail me if you need the sample csv attachment that gives the problem
Here is a c# version that i used for testing. Running from VS2010 it works perfect but on linux with mono the attachment has wrong size , some bytes are missing?!.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Exchange.WebServices.Data;
using System.Net;
namespace Exchange_SDP_Attachment_Extracter
{
public class PgzExchangeService
{
public void Extract()
{
ExchangeService service = new ExchangeService (ExchangeVersion.Exchange2007_SP1,TimeZoneInfo.Local);
service.Credentials = new NetworkCredential("user", "pass", "domain");
service.Url = new Uri("https://xx.xx.xx.xx/EWS/Exchange.asmx");
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.Inbox, new ItemView(10));
foreach (Item item in findResults.Items)
{
EmailMessage e = EmailMessage.Bind
(service,
item.Id,
new PropertySet(BasePropertySet.IdOnly, ItemSchema.Attachments));
foreach ( Attachment att in e.Attachments )
{
if (att is FileAttachment)
{
FileAttachment fileAttachment = (FileAttachment)att;
fileAttachment.Load(#"/tmp/testsdp/" + fileAttachment.Name);
}
}
}
}
}
class Program
{
static void Main(string[] args)
{
PgzExchangeService pgz = new PgzExchangeService();
pgz.Extract();
}
}
}
My suggestion would be to try examining the text attachment with a hex editor. There has be something unusual about those three occurrences. You need to find out what those three lines have in common before any of us can recommend a course of action to you.