{"id":23291019,"url":"https://github.com/jplusplus/tusg","last_synced_at":"2025-10-08T11:41:10.394Z","repository":{"id":18973897,"uuid":"77907239","full_name":"jplusplus/tusg","owner":"jplusplus","description":"The ultimate spreadsheet guide for journalists","archived":false,"fork":false,"pushed_at":"2022-12-10T16:11:53.000Z","size":3648,"stargazers_count":2,"open_issues_count":11,"forks_count":0,"subscribers_count":9,"default_branch":"master","last_synced_at":"2024-04-14T04:55:28.822Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://tusg.herokuapp.com","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jplusplus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-01-03T10:32:21.000Z","updated_at":"2023-08-09T00:40:41.000Z","dependencies_parsed_at":"2023-01-13T20:06:34.976Z","dependency_job_id":null,"html_url":"https://github.com/jplusplus/tusg","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jplusplus%2Ftusg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jplusplus%2Ftusg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jplusplus%2Ftusg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jplusplus%2Ftusg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jplusplus","download_url":"https://codeload.github.com/jplusplus/tusg/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247526675,"owners_count":20953141,"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":[],"created_at":"2024-12-20T05:13:53.072Z","updated_at":"2025-10-08T11:41:05.341Z","avatar_url":"https://github.com/jplusplus.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# The Ultimate Spreadsheet Guide\nThis is a dynamic spreadsheet guide for journalists. It contains the everyday skills needed in a newsroom, adopted to your platform, software version and language. Live demo: https://tusg.herokuapp.com\n\n## Installation\n\nTo install:\n\n    git clone https://github.com/jplusplus/tusg.git\n    cd tusg\n    npm install\n\nOptionally, to make the Google Sheets integration work, you will also need to add a API key and either Memcached or MemCachier.\n - Get an API key (json format with line breaks, and explicit `=`'s) for your Google Drive service account (see [this guide](https://github.com/theoephraim/node-google-spreadsheet#user-content-service-account-recommended-method) for step by step insctuctions on how to do this).\n - Open the downloaded json file, and copy the private key to a separate text file.\n - Replace `\\n` with actual line breaks.\n - Replace `\\u003d` with `=`\n - `export GOOGLE_PRIVATE_KEY=\"$(cat google_private_key.txt)\"`\n - `export GOOGLE_CLIENT_EMAIL=yourserviceaccountemail@google.com`\n - `apt-get install memcached` (Ubuntu) or `brew install memcached` (OS X) to install Memcached.\n - `export MEMCACHIER_SERVERS=127.0.0.1:11211` (depending on your server setup. This is the defult for many systems) to set the Memcached server.\n\n## Developing\n\nTo get started:\n\n    gulp develop\n\n`gulp develop` will set environment variables to defaults and start the app in development mode. You should now be able to access the site at [localhost:3000](http://localhost:3000)\n\nEach pug file in [`views/chapters`](https://github.com/jplusplus/tusg/tree/master/views/chapters) corresponds to one chapter in the guide. Just edit the pug files, and reload the page.\n\nIn your chapter files, you can access a number of variables and helper functions, e.g.:\n\n### Variables\n\nThese are accessed like this:\n\n```pug\n    if os == \"MacOS\"\n      p Character encoding can sometimes be an issue when importing CSV files.\n```\n\nor inline like this:\n\n```pug\n    p The bitwise AND function is written #{version \u003c \"Excel 2013\" ? \"with an ugly hack using SUBSTITUTE\" : \"BITAND\"} in Excel.\n```\n\n* `os`: Operating system, e.g. `Windows`.\n* `software`: E.g. `Excel`.\n* `version`: E.g. `Excel 2010`\n* `language`: Interface language for the software, e.g. `Swedish`\n* `locale`: Locale settings for the workbook, e.g. `sv-SE`. \n\n### Functions\n\nThese are accessed like this: `!{f()}`, eg:\n\n```pug\n    p Use the function !{f(\"=MID()\")} to extract a substring from a string, like this: !{f('=MID(A1, FIND(\"-\", A1), 6)')}.\n```\n\n* `f()`: Translates a spreadsheet function, and uses the right argument delimiter (comma och semicolon). E.g. `!{f(\"=LEFT(A1, 4)\")}` =\u003e `=VÄNSTER(A1; 4)`\n* `t()`: Translates a localized string. E.g. `!{t(\"TRUE\")}` =\u003e `SANT`\n* `menu()`: Translates an option or a menu path, and formats is like nicely. E.g. `!{menu(\"Format\", \"Cells\")}` =\u003e `Formatera \u003e Celler`\n* `key()`: Translates keyboard shortcut to the current OS. E.g. `!{key(\"Ctrl\", \"A\")}` =\u003e `⌘-A`\n\n### Filters\n\nThese are accessed like this: `:image(name.png)`, eg:\n\n```pug\n    :image(spreadsheet.png)\n      Here goes a caption to that image\n```\n\n * `image(filename.png)`: Embeds an image from the `/public/img` folder. Use `small` as the second argument to inline a smaller, floating image. If the filename contains a comma you will have to enclose it in quotes.\n * `spreadsheet(KEY)`: Embeds an interactive spreadsheet, based on a Google Sheets identified by KEY, but localized.\n\n## Environment variables\n\n - `export DEBUG=tusg` to enable debug messages\n - `export NODE_ENV=development` to run in development mode, `export NODE_ENV=production` otherwise\n\nTo enable Google Sheets integration:\n - `export GOOGLE_PRIVATE_KEY=\"$(cat google_private_key.txt)\"` private API key (json format with line breaks, and explicit `=`'s) for your Google Drive service account (see [this guide](https://github.com/theoephraim/node-google-spreadsheet#user-content-service-account-recommended-method) for step by step insctuctions on how to do this).\n - `export GOOGLE_CLIENT_EMAIL=yourserviceaccountemail@google.com`\n - `export MEMCACHIER_SERVERS=127.0.0.1:11211`\n \nFor Heroku, the corresponding commands would be:\n - `heroku config:add DEBUG=tusg`\n - `heroku config:add NODE_ENV=production`\n - `heroku config:add GOOGLE_PRIVATE_KEY=\"$(cat google_private_key.txt)\"`\n - `heroku config:add GOOGLE_CLIENT_EMAIL=yourserviceaccountemail@google.com`\n - `heroku config:add MEMCACHIER_SERVERS=127.0.0.1:11211`\n \n## Changelog\n\n* 0.0.1: First version","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjplusplus%2Ftusg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjplusplus%2Ftusg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjplusplus%2Ftusg/lists"}