
> [!CAUTION]
> This package will modify and delete tidders in Tiddlywiki. Use it with caution. 
> Create a backup and test it before using,


# rtiddlywiki
![R-CMD-check](https://github.com/byzheng/rtiddlywiki/workflows/R-CMD-check/badge.svg)
[![CRAN_Status_Badge](http://www.r-pkg.org/badges/version/rtiddlywiki)](https://cran.r-project.org/package=rtiddlywiki)

[![](http://cranlogs.r-pkg.org/badges/grand-total/rtiddlywiki?color=green)](https://cran.r-project.org/package=rtiddlywiki)
[![](http://cranlogs.r-pkg.org/badges/last-month/rtiddlywiki?color=green)](https://cran.r-project.org/package=rtiddlywiki)
[![](http://cranlogs.r-pkg.org/badges/last-week/rtiddlywiki?color=green)](https://cran.r-project.org/package=rtiddlywiki)


R interface for [tiddlywiki](https://tiddlywiki.com/) which is a unique non-linear notebook for capturing, organising and sharing complex information.

## Communicate with WebServer API for node.js only

[WebServer APIs](https://tiddlywiki.com/static/WebServer%2520API.html) of tiddlywiki are implemented in R interface including `GET` list of tiddlers by filters, a tiddler, and file; `PUT` a new tiddler.

```r
tw_options(host = "http://127.0.0.1:8080/")
# Get all tiddlers
get_tiddlers()
# Get a tiddler by title 
get_tiddler(title = "GettingStarted")

# Put a new tiddler 
title <- "New tiddler"
text <- c("!! Section",
          "This is a new tiddler")
type <- "text/vnd.tiddlywiki"
tags <- c("Tag1", "Tag 2")
fields <- c("field 1" = "value 1", "field 2" = "field 2")
put_tiddler(title = title, 
            text = text,
            type = type, 
            tags = tags,
            fields = fields)
```

## Generate markdown tiddler from Rmarkdown file

A new output format `tiddler_document` is exported to generate markdown tiddler from [Rmarkdown file](https://rmarkdown.rstudio.com/) and then `PUT` into tiddlywiki WebServer. The image files generated by `knitr` are embeded as base64. [Lazy load](https://tiddlywiki.com/static/LazyLoading.html) under Node.js can be used to load big markdown file.

The host of tiddlywiki server can be configured in the Environment variable `TW_HOST` (e.g. in `.Renviron`) or using `tw_options(host = "http://<host>:<port>/")`. This method is only working in the local or remote tiddlywiki node.js server without authentication. `rtiddlywiki` does not support basic authentication now.

A new tiddler in json format is generated in the Rmd folder and can be used to import into tiddlywiki in the server or single file. The tiddler `PUT` into server if `host` is specified in the environment variable and remote sets as `true` in the yaml header.

The `yaml` header can be specified to export `tiddler_document`.

```yaml
title: "R Markdown file"
output: 
  rtiddlywiki::tiddler_document:
    remote: true
    preview: true
    tags: ["tag 1", "tag 2"]
    fields:
      "field1": "V1"
      "field 2": "Value 2"
```

The `title` in the Rmarkdown file is used as tiddler name. 

The markdown file is generated by functions `rmarkdown::md_document` or `bookdown::markdown_document2` if `use_bookdown` is specified. 

The `preview` option is used to preview the markdown file in tiddlywiki plugin [tw-livebridge](https://github.com/byzheng/tw-livebridge) is installed. A `open_tiddler` command is sent to `websocket` server of `tw-livebridge` to open the tiddler in the browser, which bring the generated tiddler into view.


## Authentication for remote tiddlywiki server

For remote tiddlywiki server, I use an alternative way for authentication. A nginx server is used as a reverse proxy to add header authorization. Environment variables `TW_HTTP_X_AUTH_KEY` in `.Renviron` is used to set the auth key. An example nginx configuration is as below:

> All placeholders (e.g., `<your_domain>`, `<your_path>`, `<a unique key>`, `<remote_ip>`) should be replaced with your actual values before use.

```nginx
server {
    listen 443 ssl;
    server_name <your_domain>;

    ssl_certificate     <your_path>.crt;
    ssl_certificate_key <your_path>.key;
    client_max_body_size 100M;
    location / {
        allow 127.0.0.1;
        allow <remote_ip>;
        deny all;
        if ($http_x_auth_key != '<a unique key>') {
            return 403;
        }
        
        proxy_pass http://127.0.0.1:8001;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept';
    }
    location /ws {
        allow 127.0.0.1;
        allow <remote_ip>;
        deny all;
        if ($http_x_auth_key != '<a unique key>') {
            return 403;
        }
        
        proxy_pass http://127.0.0.1:8001/ws;
        proxy_http_version 1.1;

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
        proxy_connect_timeout 3600s;
        proxy_buffering off;
    }
        
}
```

## Installation

Install the developing version from [Github](https://github.com/byzheng/rtiddlywiki).


```r
remotes::install_github('byzheng/rtiddlywiki')
```
