{"id":19965436,"url":"https://github.com/tategakibunko/typenovel","last_synced_at":"2025-05-03T23:30:44.746Z","repository":{"id":35157101,"uuid":"195502782","full_name":"tategakibunko/TypeNovel","owner":"tategakibunko","description":"A simple markup language to write novel with types.","archived":false,"fork":false,"pushed_at":"2023-03-04T04:55:00.000Z","size":710962,"stargazers_count":91,"open_issues_count":3,"forks_count":3,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-19T13:47:47.150Z","etag":null,"topics":["compiler","machine-learning","markup-language","natural-language-processing","novel","typescript","writing","writing-tool"],"latest_commit_sha":null,"homepage":"https://github.com/tategakibunko/TypeNovel/tree/master/Docs/README.md","language":"TypeScript","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/tategakibunko.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES","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,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-07-06T05:47:19.000Z","updated_at":"2024-10-14T15:53:33.000Z","dependencies_parsed_at":"2024-11-13T02:31:43.463Z","dependency_job_id":"b4b07d55-3bcc-4694-bf86-e0e2a038e7af","html_url":"https://github.com/tategakibunko/TypeNovel","commit_stats":{"total_commits":392,"total_committers":3,"mean_commits":"130.66666666666666","dds":"0.015306122448979553","last_synced_commit":"3f241aa00152583a076131353b0bf6ab7bc6980b"},"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tategakibunko%2FTypeNovel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tategakibunko%2FTypeNovel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tategakibunko%2FTypeNovel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tategakibunko%2FTypeNovel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tategakibunko","download_url":"https://codeload.github.com/tategakibunko/TypeNovel/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252269026,"owners_count":21721239,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["compiler","machine-learning","markup-language","natural-language-processing","novel","typescript","writing","writing-tool"],"created_at":"2024-11-13T02:28:46.600Z","updated_at":"2025-05-03T23:30:43.707Z","avatar_url":"https://github.com/tategakibunko.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TypeNovel\n\nA simple markup language to write novel with types.\n\n## Example\n\nThis is what it looks like.\n\n```javascript\n@scene({\n  season:\"winter\"\n}){\n  Finally, $season(\"Xmas\") has come!\n}\n```\n\nOutput is here.\n\n```html\n\u003cscene data-season=\"winter\"\u003e\n  Finally, \u003cseason\u003eXmas\u003c/season\u003e has come!\n\u003c/scene\u003e\n```\n\nFor more information, take a look at [Cheatsheet](https://github.com/tategakibunko/TypeNovel/tree/master/docs/Cheatsheet.md).\n\n## Install\n\n```bash\nnpm install -g typenovel\n```\n\nThen `/usr/local/bin/tnc` would be installed.\n\n```bash\n[foo@localhost] tnc --version\n1.0.4\n```\n\n## Use compiler from your project\n\nYou can compile from source by `Tnc.fromString`.\n\n```typescript\nimport { Tnc } from 'typenovel';\n\nconst result = Tnc.fromString('@scene(){ foo }', {\n  format: 'html', // or 'text'\n  minify: false\n});\n\nconsole.error(result.errors);\nconsole.log(result.output);\n```\n\nOr you can compile from file by `Tnc.fromFile`.\n\n```typescript\nimport { Tnc } from 'typenovel';\n\nconst result = Tnc.fromFile('sample.tn', {\n  format: 'html',\n  minify: false\n});\n\nconsole.error(result.errors);\nconsole.log(result.output);\n```\n\n## Reader Application\n\nReader application is available for TypeNovel(compiler included).\n\nTake a look at [TypeNovelReader](https://github.com/tategakibunko/TypeNovelReader).\n\n\n## Motivation\n\n### What is the difference between pro novelist and amature novelist?\n\nI'm running a [novel posting platform](https://tb.antiscroll.com) over recent decades, and I always thought about differences between pro and amature.\n\nI think that amature novelist sometimes lack some context description in their story, especially tend to lack the **time** description.\n\nTo confirm this feeling, I measured the scores how many times they wrote **time** in their novel, and gave them **quolity scores**.\n\nThe formula is simple.\n\n[Total count of time written sentence] * [Entropy of time written sentence] / [Total sentence count]\n\nFor example, score of \"Mon\"('門' in Japanese) written by 'Natsume Soukeki (1867-1916)' is like this.\n\n```bash\nhistgram: [30, 24, 33, 21, 29, 29, 30, 24, 24, 17]\nscore: 0.221913(total sentence size = 3879, total time sentences = 261, entropy = 3.298082)\n```\n\nIn this way, I measured the average scores of many writers in my platform.\n\nHere is scores of **amature** writers.\n\n```\nuser1: average score:0.055084\nuser2: average score:0.057143\nuser3: average score:0.020505\nuser4: average score:0.071971\nuser5: average score:0.045247\nuser6: average score:0.042603\nuser7: average score:0.086316\nuser8: average score:0.051926\nuser9: average score:0.089533\n```\n\nAnd here is scores of **pro** writers.\n\n```\npro1: average score:0.120076, Arthur Conan Doyle\npro2: average score:0.210235, Anton Pavlovich Chekhov\npro3: average score:0.124371, James Augustine Aloysius Joyce\npro4: average score:0.101132, Feodor Dostoyevsky\npro5: average score:0.138546, Nomura Kodou(野村胡堂)\npro6: average score:0.153463, Mori Ougai(森鴎外)\npro7: average score:0.148902, Christian Andersen\npro8: average score:0.110636, Natsume Souseki(夏目漱石)\npro9: average score:0.118976, Nakajima Atsushi(中島敦)\n```\n\nClearly pro scores around `0.1`, but amature scores around `0.05`, difference is not so small.\n\nSo I thought \"How can we fill the differences between pro and amature?\".\n\nIn other words, \"Can we fill the diffecence using some kind of technology?\".\n\n### My answer is \"novel with type\"\n\nI think we can force all writers to fill enough information in their text, to use **typing**.\n\nBut what is the type of novel?\n\nI think it's pair of **constraint** and **annotation**.\n\nThis is what it looks like.\n\n```javascript\n// block level tag starts with '@'\n@scene({\n  season: \"winter\", // constraint 'season'\n  time: \"7:00AM\" // constraint 'time'\n}){\n  // annotation tag starts with '$'.\n  // annotated constraint 'time(7:00AM)' as 'morning'\n  I woke up at the $time(\"morning\"). // I woke up at the morning.\n\n  // annotated constraint 'season(winter)' as 'Xmas'\n  Finally $season(\"Xmas\")!\n}\n```\n\nIn this example, we have two constraints(`season` as \"winter\" and `time` as \"7:00AM\") for this scene block.\n\nSo we have to annotate them by writing **annotation** tag.\n\nAnd we annotated them by `$time(\"morning\")` and `$season(\"Xmas\")`.\n\nNow we annotated all constraints, let's compile this code!\n\n```bash\n[foo@localhost]$ tnc sample.tn\n```\n\nAnd you get html output like this.\n\n```html\n\u003cscene data-season=\"winter\" data-time=\"7:00AM\"\u003e\n  I woke up at the \u003ctime\u003emorning\u003c/time\u003e.\n  \"Finally \u003cseason\u003eXmas\u003c/season\u003e!\"\n\u003c/scene\u003e\n```\n\nThis output is NLP(Natural Language Processing) or ML(Machine Leraning) friendly, so both platform and writers win!\n\nWriters merit: **quality of novel**\n\nPlatform merit: **quality of data**\n\nBy the way, if we don't annotated our constraints, what happens?\n\nOffcource, you'll get errors at the compilation time.\n\n```bash\n/Users/u1/sample.tn(line:1) 'season' is not annotated in this block!\n/Users/u1/sample.tn(line:2) 'time' is not annotated in this block!\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftategakibunko%2Ftypenovel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftategakibunko%2Ftypenovel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftategakibunko%2Ftypenovel/lists"}