{"id":13426024,"url":"https://github.com/daranzolin/textych","last_synced_at":"2026-01-17T07:04:07.336Z","repository":{"id":129155315,"uuid":"245077388","full_name":"daranzolin/textych","owner":"daranzolin","description":"Create interactive text parallels :page_with_curl: :page_with_curl: :page_with_curl:","archived":false,"fork":false,"pushed_at":"2020-03-05T20:51:10.000Z","size":3343,"stargazers_count":9,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-15T20:32:51.390Z","etag":null,"topics":["htmlwidgets","textanalysis"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/daranzolin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-03-05T05:30:49.000Z","updated_at":"2024-08-01T16:11:05.000Z","dependencies_parsed_at":null,"dependency_job_id":"fe86167e-e8d1-4976-937e-090194ab7132","html_url":"https://github.com/daranzolin/textych","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/daranzolin/textych","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daranzolin%2Ftextych","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daranzolin%2Ftextych/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daranzolin%2Ftextych/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daranzolin%2Ftextych/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/daranzolin","download_url":"https://codeload.github.com/daranzolin/textych/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daranzolin%2Ftextych/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28503021,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T06:57:29.758Z","status":"ssl_error","status_checked_at":"2026-01-17T06:56:03.931Z","response_time":85,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["htmlwidgets","textanalysis"],"created_at":"2024-07-31T00:01:24.519Z","updated_at":"2026-01-17T07:04:07.313Z","avatar_url":"https://github.com/daranzolin.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# textych\n\n\u003c!-- badges: start --\u003e\n![](https://camo.githubusercontent.com/ea6e0ff99602c3563e3dd684abf60b30edceaeef/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6966656379636c652d6578706572696d656e74616c2d6f72616e67652e737667)\n![CRAN log](http://www.r-pkg.org/badges/version/textych)\n\u003c!-- badges: end --\u003e\n\nThe goal of textych is to create interactive text parallels. This form of reference is useful for exploring similarities and differences betwixt passages. \n\n## Installation\n\nYou can install the released version of textych from GitHub with:\n\n``` r\nremotes::install_github(\"daranzolin/textych\")\n```\n## Simple Example\n\nSplit any text into words and assign a corresponding color and tooltip.\n\n```r\nlibrary(textych)\nlibrary(tidytext)\nlibrary(dplyr)\n\ndf \u003c- tibble(\n  text = c(\"The quick brown fox jumps over the lazy grey dog\",\n           \"The catepiller ate through once nice green leaf\"),\n  ind = c(\"A\", \"B\")\n) %\u003e% \n  unnest_tokens(word, text, to_lower = FALSE) %\u003e% \n  mutate(\n    color = case_when(\n      word == \"brown\" ~ \"brown\",\n      word == \"grey\" ~ \"grey\",\n      word == \"green\" ~ \"green\",\n      TRUE ~ \"#333333\"\n    ),\n    tooltip = case_when(\n      word == \"caterpillar\" ~ \"An insect\",\n      word %in% c(\"fox\", \"dog\") ~ \"A cute mammal\",\n      word == \"leaf\" ~ \"Vegetation\"\n    )\n  )\n\ntextych(df, text = word, text_index = ind, color = color, tooltip = tooltip)\n```\n![](inst/textych-gif2.gif)\n\n## Complex Example: Greek Text Analysis\n\nArranging parallel texts with similar language and ideas is a common practice in textual analysis, and there is *very* expensive software that parses each word's form, tense, mood, gender, case, etc. This is a cheaper (and more customizable) alternative.\n\nFirst,  I load the packages, then [retrieve and parse the texts via rperseus.](https://github.com/ropensci/rperseus)\n\n``` r\nlibrary(rperseus) # remotes::install_github(\"ropensci/rperseus\")\nlibrary(glue)\n\ntexts \u003c- bind_rows(\n  get_perseus_text(\"urn:cts:greekLit:tlg0031.tlg012.perseus-grc2\", \"1.4\"),\n  get_perseus_text(\"urn:cts:greekLit:tlg0031.tlg013.perseus-grc2\", \"1.3\"),\n  get_perseus_text(\"urn:cts:greekLit:tlg0031.tlg006.perseus-grc2\", \"8.39\")\n)\n\nparsed_texts \u003c- bind_rows(\n  parse_excerpt(\"urn:cts:greekLit:tlg0031.tlg012.perseus-grc2\", \"1.4\"),\n  parse_excerpt(\"urn:cts:greekLit:tlg0031.tlg013.perseus-grc2\", \"1.3\"),\n  parse_excerpt(\"urn:cts:greekLit:tlg0031.tlg006.perseus-grc2\", \"8.39\")\n)\n```\n\nSecond, I want to (1) specify title labels; (2) color the word ἀγάπη (\"love\"); and (3) create a custom HTML tooltip parsing each word on hover. \n\n``` r\ntt_data \u003c- texts %\u003e% \n  transmute(\n    text,\n    passage = glue(\"{label} {section}\")\n  ) %\u003e% \n  unnest_tokens(word, text) %\u003e% \n  left_join(\n    distinct(parsed_texts, word, form, .keep_all = TRUE), \n    by = c(\"word\" = \"form\")\n  ) %\u003e% \n  mutate(color = ifelse(grepl(\"ἀγάπη\", word), \"firebrick\", \"#333333\")) %\u003e% \n  mutate(tooltip = glue(\"\u003ctable\u003e\n                              \u003ctr\u003e\n                                  \u003cth\u003eword\u003c/th\u003e\n                                  \u003cth\u003epart\u003c/th\u003e\n                                  \u003cth\u003enumber\u003c/th\u003e\n                                  \u003cth\u003egender\u003c/th\u003e\n                                  \u003cth\u003ecase\u003c/th\u003e\n                              \u003c/tr\u003e\n                              \u003ctr\u003e\n                                  \u003ctd\u003e{word.y}\u003c/td\u003e\n                                  \u003ctd\u003e{part_of_speech}\u003c/td\u003e\n                                  \u003ctd\u003e{number}\u003c/td\u003e\n                                  \u003ctd\u003e{gender}\u003c/td\u003e\n                                  \u003ctd\u003e{case}\u003c/td\u003e\n                              \u003c/tr\u003e\n                        \u003c/table\u003e\n                              \")\n         )\n```\n\nFinally, I pass the data to `textych`, specifying the respective columns for each parallel, text color, and tooltip.\n\n```r\ntextych(tt_data, word, passage, color, tooltip)\n```\n![](inst/textych-gif1.gif)\n\n## Future work\n\n* Highlighting words\n* More easily customizable tooltips\n* Additional styling\n* Improved margins\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaranzolin%2Ftextych","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdaranzolin%2Ftextych","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaranzolin%2Ftextych/lists"}