{"action":"created","comment":{"url":"https://api.github.com/repos/tidyverse/readxl/pulls/comments/177090768","pull_request_review_id":106902661,"id":177090768,"diff_hunk":"@@ -145,4 +145,25 @@ inline std::string trim(const std::string& s) {\n   return s.substr(begin, end - begin + 1);\n }\n \n+inline std::string dirName(const std::string& path) {\n+  std::size_t found = path.find_last_of(\"/\");\n+  if (found == std::string::npos) {\n+    return \"\";\n+  }\n+  return path.substr(0, found);\n+}\n+\n+inline std::string baseName(const std::string& path) {\n+  std::size_t found = path.find_last_of(\"/\");\n+  if (found == std::string::npos) {\n+    return path;\n+  }\n+  return path.substr(found + 1);\n+}\n+\n+inline std::string deSlash(const std::string& s) {\n+  size_t start = s.find_first_not_of(\"/\");\n+  return s.substr(start);\n+}\n+","path":"src/utils.h","position":24,"original_position":24,"commit_id":"9b8b89081f0c7e847923ed0bf4a69edcd4ac584f","original_commit_id":"7021c13d4b485d1cc21bee60f321f7adc48e509e","user":{"login":"jimhester","id":205275,"avatar_url":"https://avatars3.githubusercontent.com/u/205275?v=4","gravatar_id":"","url":"https://api.github.com/users/jimhester","html_url":"https://github.com/jimhester","followers_url":"https://api.github.com/users/jimhester/followers","following_url":"https://api.github.com/users/jimhester/following{/other_user}","gists_url":"https://api.github.com/users/jimhester/gists{/gist_id}","starred_url":"https://api.github.com/users/jimhester/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jimhester/subscriptions","organizations_url":"https://api.github.com/users/jimhester/orgs","repos_url":"https://api.github.com/users/jimhester/repos","events_url":"https://api.github.com/users/jimhester/events{/privacy}","received_events_url":"https://api.github.com/users/jimhester/received_events","type":"User","site_admin":false},"body":"I think calling `deSlash` something like `removeLeadingSlash` would make it more clear what it does, I was not sure if `deSlash` was supposed to remove the leading slashes, trailing slashes or all slashes.\r\n\r\nAlso it does not handle the case where the input consists of only slashes, e.g. what happens if `find_first_not_of` returns `std::string::npos`.","created_at":"2018-03-26T13:33:47Z","updated_at":"2018-03-26T13:43:26Z","html_url":"https://github.com/tidyverse/readxl/pull/437#discussion_r177090768","pull_request_url":"https://api.github.com/repos/tidyverse/readxl/pulls/437","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/tidyverse/readxl/pulls/comments/177090768"},"html":{"href":"https://github.com/tidyverse/readxl/pull/437#discussion_r177090768"},"pull_request":{"href":"https://api.github.com/repos/tidyverse/readxl/pulls/437"}},"in_reply_to_id":176921599},"pull_request":{"url":"https://api.github.com/repos/tidyverse/readxl/pulls/437","id":177260731,"html_url":"https://github.com/tidyverse/readxl/pull/437","diff_url":"https://github.com/tidyverse/readxl/pull/437.diff","patch_url":"https://github.com/tidyverse/readxl/pull/437.patch","issue_url":"https://api.github.com/repos/tidyverse/readxl/issues/437","number":437,"state":"open","locked":false,"title":"Parse _rels/.rels to get paths to package parts","user":{"login":"jennybc","id":599454,"avatar_url":"https://avatars3.githubusercontent.com/u/599454?v=4","gravatar_id":"","url":"https://api.github.com/users/jennybc","html_url":"https://github.com/jennybc","followers_url":"https://api.github.com/users/jennybc/followers","following_url":"https://api.github.com/users/jennybc/following{/other_user}","gists_url":"https://api.github.com/users/jennybc/gists{/gist_id}","starred_url":"https://api.github.com/users/jennybc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jennybc/subscriptions","organizations_url":"https://api.github.com/users/jennybc/orgs","repos_url":"https://api.github.com/users/jennybc/repos","events_url":"https://api.github.com/users/jennybc/events{/privacy}","received_events_url":"https://api.github.com/users/jennybc/received_events","type":"User","site_admin":false},"body":"Fixes #435 Be able to read sheets produced by the Los Angeles Police Department\r\n\r\nThe xlsx produced by LAPD is a very literal implementation of the example on pp65-66 of 5th edition of ECMA:\r\n\r\n> Example: The following package represents the minimal conformant SpreadsheetML package as defined by ECMA-376\r\n\r\nI used this as motivation to make a major upgrade to how readxl parses the package structure. Basically, readxl previously did not parse it but, rather, assumed a very common default. And the LAPD sheets show that other structures are possible (Excel can open the LAPD files, btw). Now we can read LAPD sheets, while still being able to read all the other weird 3rd party sheets in our test collection 🤞\r\n\r\nThe main feature of the LAPD sheets is that they do not use an `xl/` subdirectory, whereas every other xlsx we've seen before does. Browsable examples:\r\n\r\n  * LAPD sheets do not use an `xl/` subdirectory: [excelgesis/los-angeles-arrests-xlsx](https://jennybc.github.io/excelgesis/los-angeles-arrests-xlsx/index.html)\r\n  * [excelgesis/embedded-chartsheet](https://jennybc.github.io/excelgesis/embedded-chartsheet/index.html) is a good example of a \"normal\" xlsx with multiple worksheets and a chartsheet. It has an `xl/` subdirectory.\r\n  * [excelgesis/Ekaterinburg_IP_9](https://jennybc.github.io/excelgesis/Ekaterinburg_IP_9/index.html) is a valuable example of yet another type of 3rd party xlsx. It uses `xl/` but insists on giving paths in `/xl/foo/bar` form in all the relationship files, which is peculiar (very different from embedded-chartsheet example). It's also completely in Cyrillic, which is extra fun.","created_at":"2018-03-24T21:52:17Z","updated_at":"2018-03-26T13:43:26Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ad8b209c3a2b17cd7ff3ea714ff6789b7c40d9cd","assignee":null,"assignees":[],"requested_reviewers":[{"login":"hadley","id":4196,"avatar_url":"https://avatars3.githubusercontent.com/u/4196?v=4","gravatar_id":"","url":"https://api.github.com/users/hadley","html_url":"https://github.com/hadley","followers_url":"https://api.github.com/users/hadley/followers","following_url":"https://api.github.com/users/hadley/following{/other_user}","gists_url":"https://api.github.com/users/hadley/gists{/gist_id}","starred_url":"https://api.github.com/users/hadley/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hadley/subscriptions","organizations_url":"https://api.github.com/users/hadley/orgs","repos_url":"https://api.github.com/users/hadley/repos","events_url":"https://api.github.com/users/hadley/events{/privacy}","received_events_url":"https://api.github.com/users/hadley/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/tidyverse/readxl/pulls/437/commits","review_comments_url":"https://api.github.com/repos/tidyverse/readxl/pulls/437/comments","review_comment_url":"https://api.github.com/repos/tidyverse/readxl/pulls/comments{/number}","comments_url":"https://api.github.com/repos/tidyverse/readxl/issues/437/comments","statuses_url":"https://api.github.com/repos/tidyverse/readxl/statuses/9b8b89081f0c7e847923ed0bf4a69edcd4ac584f","head":{"label":"tidyverse:lapd","ref":"lapd","sha":"9b8b89081f0c7e847923ed0bf4a69edcd4ac584f","user":{"login":"tidyverse","id":22032646,"avatar_url":"https://avatars2.githubusercontent.com/u/22032646?v=4","gravatar_id":"","url":"https://api.github.com/users/tidyverse","html_url":"https://github.com/tidyverse","followers_url":"https://api.github.com/users/tidyverse/followers","following_url":"https://api.github.com/users/tidyverse/following{/other_user}","gists_url":"https://api.github.com/users/tidyverse/gists{/gist_id}","starred_url":"https://api.github.com/users/tidyverse/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tidyverse/subscriptions","organizations_url":"https://api.github.com/users/tidyverse/orgs","repos_url":"https://api.github.com/users/tidyverse/repos","events_url":"https://api.github.com/users/tidyverse/events{/privacy}","received_events_url":"https://api.github.com/users/tidyverse/received_events","type":"Organization","site_admin":false},"repo":{"id":32161666,"name":"readxl","full_name":"tidyverse/readxl","owner":{"login":"tidyverse","id":22032646,"avatar_url":"https://avatars2.githubusercontent.com/u/22032646?v=4","gravatar_id":"","url":"https://api.github.com/users/tidyverse","html_url":"https://github.com/tidyverse","followers_url":"https://api.github.com/users/tidyverse/followers","following_url":"https://api.github.com/users/tidyverse/following{/other_user}","gists_url":"https://api.github.com/users/tidyverse/gists{/gist_id}","starred_url":"https://api.github.com/users/tidyverse/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tidyverse/subscriptions","organizations_url":"https://api.github.com/users/tidyverse/orgs","repos_url":"https://api.github.com/users/tidyverse/repos","events_url":"https://api.github.com/users/tidyverse/events{/privacy}","received_events_url":"https://api.github.com/users/tidyverse/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/tidyverse/readxl","description":"Read excel files (.xls and .xlsx) into R 🖇","fork":false,"url":"https://api.github.com/repos/tidyverse/readxl","forks_url":"https://api.github.com/repos/tidyverse/readxl/forks","keys_url":"https://api.github.com/repos/tidyverse/readxl/keys{/key_id}","collaborators_url":"https://api.github.com/repos/tidyverse/readxl/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/tidyverse/readxl/teams","hooks_url":"https://api.github.com/repos/tidyverse/readxl/hooks","issue_events_url":"https://api.github.com/repos/tidyverse/readxl/issues/events{/number}","events_url":"https://api.github.com/repos/tidyverse/readxl/events","assignees_url":"https://api.github.com/repos/tidyverse/readxl/assignees{/user}","branches_url":"https://api.github.com/repos/tidyverse/readxl/branches{/branch}","tags_url":"https://api.github.com/repos/tidyverse/readxl/tags","blobs_url":"https://api.github.com/repos/tidyverse/readxl/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/tidyverse/readxl/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/tidyverse/readxl/git/refs{/sha}","trees_url":"https://api.github.com/repos/tidyverse/readxl/git/trees{/sha}","statuses_url":"https://api.github.com/repos/tidyverse/readxl/statuses/{sha}","languages_url":"https://api.github.com/repos/tidyverse/readxl/languages","stargazers_url":"https://api.github.com/repos/tidyverse/readxl/stargazers","contributors_url":"https://api.github.com/repos/tidyverse/readxl/contributors","subscribers_url":"https://api.github.com/repos/tidyverse/readxl/subscribers","subscription_url":"https://api.github.com/repos/tidyverse/readxl/subscription","commits_url":"https://api.github.com/repos/tidyverse/readxl/commits{/sha}","git_commits_url":"https://api.github.com/repos/tidyverse/readxl/git/commits{/sha}","comments_url":"https://api.github.com/repos/tidyverse/readxl/comments{/number}","issue_comment_url":"https://api.github.com/repos/tidyverse/readxl/issues/comments{/number}","contents_url":"https://api.github.com/repos/tidyverse/readxl/contents/{+path}","compare_url":"https://api.github.com/repos/tidyverse/readxl/compare/{base}...{head}","merges_url":"https://api.github.com/repos/tidyverse/readxl/merges","archive_url":"https://api.github.com/repos/tidyverse/readxl/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/tidyverse/readxl/downloads","issues_url":"https://api.github.com/repos/tidyverse/readxl/issues{/number}","pulls_url":"https://api.github.com/repos/tidyverse/readxl/pulls{/number}","milestones_url":"https://api.github.com/repos/tidyverse/readxl/milestones{/number}","notifications_url":"https://api.github.com/repos/tidyverse/readxl/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/tidyverse/readxl/labels{/name}","releases_url":"https://api.github.com/repos/tidyverse/readxl/releases{/id}","deployments_url":"https://api.github.com/repos/tidyverse/readxl/deployments","created_at":"2015-03-13T14:50:20Z","updated_at":"2018-03-24T21:43:52Z","pushed_at":"2018-03-26T07:17:13Z","git_url":"git://github.com/tidyverse/readxl.git","ssh_url":"git@github.com:tidyverse/readxl.git","clone_url":"https://github.com/tidyverse/readxl.git","svn_url":"https://github.com/tidyverse/readxl","homepage":"http://readxl.tidyverse.org","size":8417,"stargazers_count":433,"watchers_count":433,"language":"C++","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":115,"mirror_url":null,"archived":false,"open_issues_count":43,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":115,"open_issues":43,"watchers":433,"default_branch":"master"}},"base":{"label":"tidyverse:master","ref":"master","sha":"7db09cb017d6f38ab060536968888f5ca2a7192b","user":{"login":"tidyverse","id":22032646,"avatar_url":"https://avatars2.githubusercontent.com/u/22032646?v=4","gravatar_id":"","url":"https://api.github.com/users/tidyverse","html_url":"https://github.com/tidyverse","followers_url":"https://api.github.com/users/tidyverse/followers","following_url":"https://api.github.com/users/tidyverse/following{/other_user}","gists_url":"https://api.github.com/users/tidyverse/gists{/gist_id}","starred_url":"https://api.github.com/users/tidyverse/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tidyverse/subscriptions","organizations_url":"https://api.github.com/users/tidyverse/orgs","repos_url":"https://api.github.com/users/tidyverse/repos","events_url":"https://api.github.com/users/tidyverse/events{/privacy}","received_events_url":"https://api.github.com/users/tidyverse/received_events","type":"Organization","site_admin":false},"repo":{"id":32161666,"name":"readxl","full_name":"tidyverse/readxl","owner":{"login":"tidyverse","id":22032646,"avatar_url":"https://avatars2.githubusercontent.com/u/22032646?v=4","gravatar_id":"","url":"https://api.github.com/users/tidyverse","html_url":"https://github.com/tidyverse","followers_url":"https://api.github.com/users/tidyverse/followers","following_url":"https://api.github.com/users/tidyverse/following{/other_user}","gists_url":"https://api.github.com/users/tidyverse/gists{/gist_id}","starred_url":"https://api.github.com/users/tidyverse/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tidyverse/subscriptions","organizations_url":"https://api.github.com/users/tidyverse/orgs","repos_url":"https://api.github.com/users/tidyverse/repos","events_url":"https://api.github.com/users/tidyverse/events{/privacy}","received_events_url":"https://api.github.com/users/tidyverse/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/tidyverse/readxl","description":"Read excel files (.xls and .xlsx) into R 🖇","fork":false,"url":"https://api.github.com/repos/tidyverse/readxl","forks_url":"https://api.github.com/repos/tidyverse/readxl/forks","keys_url":"https://api.github.com/repos/tidyverse/readxl/keys{/key_id}","collaborators_url":"https://api.github.com/repos/tidyverse/readxl/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/tidyverse/readxl/teams","hooks_url":"https://api.github.com/repos/tidyverse/readxl/hooks","issue_events_url":"https://api.github.com/repos/tidyverse/readxl/issues/events{/number}","events_url":"https://api.github.com/repos/tidyverse/readxl/events","assignees_url":"https://api.github.com/repos/tidyverse/readxl/assignees{/user}","branches_url":"https://api.github.com/repos/tidyverse/readxl/branches{/branch}","tags_url":"https://api.github.com/repos/tidyverse/readxl/tags","blobs_url":"https://api.github.com/repos/tidyverse/readxl/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/tidyverse/readxl/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/tidyverse/readxl/git/refs{/sha}","trees_url":"https://api.github.com/repos/tidyverse/readxl/git/trees{/sha}","statuses_url":"https://api.github.com/repos/tidyverse/readxl/statuses/{sha}","languages_url":"https://api.github.com/repos/tidyverse/readxl/languages","stargazers_url":"https://api.github.com/repos/tidyverse/readxl/stargazers","contributors_url":"https://api.github.com/repos/tidyverse/readxl/contributors","subscribers_url":"https://api.github.com/repos/tidyverse/readxl/subscribers","subscription_url":"https://api.github.com/repos/tidyverse/readxl/subscription","commits_url":"https://api.github.com/repos/tidyverse/readxl/commits{/sha}","git_commits_url":"https://api.github.com/repos/tidyverse/readxl/git/commits{/sha}","comments_url":"https://api.github.com/repos/tidyverse/readxl/comments{/number}","issue_comment_url":"https://api.github.com/repos/tidyverse/readxl/issues/comments{/number}","contents_url":"https://api.github.com/repos/tidyverse/readxl/contents/{+path}","compare_url":"https://api.github.com/repos/tidyverse/readxl/compare/{base}...{head}","merges_url":"https://api.github.com/repos/tidyverse/readxl/merges","archive_url":"https://api.github.com/repos/tidyverse/readxl/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/tidyverse/readxl/downloads","issues_url":"https://api.github.com/repos/tidyverse/readxl/issues{/number}","pulls_url":"https://api.github.com/repos/tidyverse/readxl/pulls{/number}","milestones_url":"https://api.github.com/repos/tidyverse/readxl/milestones{/number}","notifications_url":"https://api.github.com/repos/tidyverse/readxl/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/tidyverse/readxl/labels{/name}","releases_url":"https://api.github.com/repos/tidyverse/readxl/releases{/id}","deployments_url":"https://api.github.com/repos/tidyverse/readxl/deployments","created_at":"2015-03-13T14:50:20Z","updated_at":"2018-03-24T21:43:52Z","pushed_at":"2018-03-26T07:17:13Z","git_url":"git://github.com/tidyverse/readxl.git","ssh_url":"git@github.com:tidyverse/readxl.git","clone_url":"https://github.com/tidyverse/readxl.git","svn_url":"https://github.com/tidyverse/readxl","homepage":"http://readxl.tidyverse.org","size":8417,"stargazers_count":433,"watchers_count":433,"language":"C++","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":115,"mirror_url":null,"archived":false,"open_issues_count":43,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":115,"open_issues":43,"watchers":433,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/tidyverse/readxl/pulls/437"},"html":{"href":"https://github.com/tidyverse/readxl/pull/437"},"issue":{"href":"https://api.github.com/repos/tidyverse/readxl/issues/437"},"comments":{"href":"https://api.github.com/repos/tidyverse/readxl/issues/437/comments"},"review_comments":{"href":"https://api.github.com/repos/tidyverse/readxl/pulls/437/comments"},"review_comment":{"href":"https://api.github.com/repos/tidyverse/readxl/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/tidyverse/readxl/pulls/437/commits"},"statuses":{"href":"https://api.github.com/repos/tidyverse/readxl/statuses/9b8b89081f0c7e847923ed0bf4a69edcd4ac584f"}},"author_association":"OWNER"}}
{"actor":{"display_login":"jimhester"}}