diff --git a/extensions/notebook/resources/notebooks/JupyterBooksCreate.ipynb b/extensions/notebook/resources/notebooks/JupyterBooksCreate.ipynb index 94bb513e9c..77e96c7627 100644 --- a/extensions/notebook/resources/notebooks/JupyterBooksCreate.ipynb +++ b/extensions/notebook/resources/notebooks/JupyterBooksCreate.ipynb @@ -71,24 +71,27 @@ "source": [ "import os, re, shutil\r\n", "\r\n", - "overwrite = False\r\n", - "book_name = input('Please provide the path where the book needs to be saved along with the book name ex-> D:\\Book1: ') \r\n", + "try:\r\n", + " overwrite = False\r\n", + " book_name = input('Please provide the path where the book needs to be saved along with the book name ex-> D:\\Book1: ') \r\n", "\r\n", - "if (os.path.exists(book_name)):\r\n", - " new_book_name = input('A folder named ' + book_name + ' already exists. Enter a new name or the same name to overwrite the existing folder.\\n')\r\n", - " if book_name == new_book_name:\r\n", - " overwrite = True\r\n", - " book_name = new_book_name\r\n", + " if (os.path.exists(book_name)):\r\n", + " new_book_name = input('A folder named ' + book_name + ' already exists. Enter a new name or the same name to overwrite the existing folder.\\n')\r\n", + " if book_name == new_book_name:\r\n", + " overwrite = True\r\n", + " book_name = new_book_name\r\n", "\r\n", - "content_folder = input('Please provide the path to your folder containing notebooks and markdown files: ')\r\n", + " content_folder = input('Please provide the path to your folder containing notebooks and markdown files: ')\r\n", "\r\n", - "while (not os.path.exists(content_folder)):\r\n", - " content_folder = input('Cannot find folder ' + content_folder + '. Please provide another path: ')\r\n", - " \r\n", - "if overwrite:\r\n", - " !jupyter-book create \"$book_name\" --content-folder \"$content_folder\" --overwrite\r\n", - "else:\r\n", - " !jupyter-book create \"$book_name\" --content-folder \"$content_folder\"" + " while (not os.path.exists(content_folder)):\r\n", + " content_folder = input('Cannot find folder ' + content_folder + '. Please provide another path: ')\r\n", + " \r\n", + " if overwrite:\r\n", + " !jupyter-book create \"$book_name\" --content-folder \"$content_folder\" --overwrite\r\n", + " else:\r\n", + " !jupyter-book create \"$book_name\" --content-folder \"$content_folder\"\r\n", + "except Exception as e:\r\n", + " raise SystemExit(str(e))" ], "metadata": { "azdata_cell_guid": "d1a363f0-d854-4466-be87-d01d4c7e51ef", @@ -97,11 +100,26 @@ "outputs": [], "execution_count": null }, + { + "cell_type": "markdown", + "source": [ + "## 3. Format toc.yml file of the book\r\n", + "\r\n", + "Create a valid toc.yml file that enables your book to be opened on our viewlet.\r\n", + "\r\n", + "Note: Skipping this step may result in a malformed book being generated." + ], + "metadata": { + "azdata_cell_guid": "5a29e2dd-d9f5-4dc1-87bc-bce639362f51" + } + }, { "cell_type": "code", "source": [ "# Update toc file, book title and clean up the directores\n", - "tocFilePath = os.path.join(book_name, \"_data\", \"toc.yml\")\n", + "\n", + "from os import path\n", + "tocFilePath = path.join(book_name, \"_data\", \"toc.yml\")\n", "f = open(tocFilePath, \"r\")\n", "title = ''\n", "replacedString = ''\n", @@ -112,41 +130,95 @@ "firstLevelUrls = re.findall(r'^(?:\\s+$[\\r\\n]+)+(\\- url: [a-zA-Z0-9\\\\.\\s\\-\\/]+$[\\r\\n]+)', result, re.MULTILINE)\n", "urls = re.findall(r'- url: [a-zA-Z0-9\\\\.\\s\\-\\/]+$', result, re.MULTILINE)\n", "headers = re.findall(r'- header: [a-zA-Z0-9\\\\.\\s-]+$', result, re.MULTILINE)\n", + "# all the markdown urls are placed at the end of the list. \n", + "possibleMarkdowns = re.findall(r'(- url: [a-zA-Z0-9\\\\.\\s\\-\\/]+$[\\r\\n]+)[\\r\\n]', result, re.MULTILINE)\n", + "\n", + "def getMarkdownFile(url):\n", + " # url are usually defined in toc as: \"- url: \"\n", + " # substring from 7th postion excluding the \"- url: \" from the path\n", + " #folders = url[7:].rstrip().split(path.sep)\n", + " if (os.name == 'nt'):\n", + " # if windows get the drive letter and add it to the url\n", + " driveletter = content_folder.split(path.sep)[0]\n", + " markdownFilePath = path.join(driveletter, url[7:].rstrip()+'.md')\n", + " else:\n", + " markdownFilePath = url[7:].rstrip() + '.md'\n", + " return markdownFilePath\n", "\n", "try:\n", " if (firstLevelUrls or headers or urls):\n", " if (firstLevelUrls and len(firstLevelUrls) == 1):\n", " for url in firstLevelUrls:\n", - " title = url[url.rindex(os.path.sep)+1:].rstrip()\n", - " if (not headers):\n", - " markdownUrl = urls[len(urls) -1]\n", - " title = markdownUrl[markdownUrl.rindex(os.path.sep)+1:].rstrip()\n", + " # check first link is the markdown\n", + " title = url[url.rindex(path.sep)+1:].rstrip()\n", + " markdownFilePath = getMarkdownFile(url)\n", + " rootmarkdownExists = path.exists(markdownFilePath)\n", + " markdownUrl = urls[len(urls) -1]\n", + " if (rootmarkdownExists):\n", + " markdownUrl = url\n", + " replacedString = \"\\n- title: %s\\n url: /%s\\n not_numbered: true\\n\" % (title, title)\n", + " # else check if the last link in the url list is markdown \n", + " elif (not headers and path.exists(getMarkdownFile(markdownUrl))):\n", + " rootmarkdownExists = True\n", + " title = markdownUrl[markdownUrl.rindex(path.sep)+1:].rstrip()\n", " replacedString = \"\\n- title: %s\\n url: /%s\\n not_numbered: true\\n expand_sections: true\\n sections: %s\" % (title, title, url)\n", " result = result.replace(markdownUrl, '')\n", + " # if there not markdowns and folders contains markdowns, handle them\n", + " elif (possibleMarkdowns):\n", + " markdownUrl = possibleMarkdowns[0]\n", + " title = markdownUrl[markdownUrl.rindex(path.sep)+1:].rstrip()\n", + " markdownFilePath = getMarkdownFile(markdownUrl)\n", + " rootmarkdownExists = path.exists(markdownFilePath)\n", + " if (rootmarkdownExists):\n", + " replacedString = \"\\n- title: %s\\n url: /%s\\n not_numbered: true\\n expand_sections: true\\n sections: %s\" % (title, title, url)\n", + " result = result.replace(markdownUrl, '')\n", + " # there is no markdown and we're adding the first link as is\n", " else:\n", + " markdownUrl = url\n", " replacedString = \"\\n- title: %s\\n url: /%s\\n not_numbered: true\\n\" % (title, title)\n", " result = result.replace(url, replacedString)\n", + " # Folders and handling them -> each header is a folder\n", " if (headers):\n", " for header in headers:\n", " title = header[10:].rstrip()\n", - " contentFolders.append(title.lower())\n", - " filtered = list(filter(lambda x: (\"%s%s%s\" % (os.path.sep, title.lower(), os.path.sep)) in x, urls))\n", + " # filters all the urls with /headerName in them\n", + " filtered = list(filter(lambda x: (\"%s%s%s\" % (path.sep, title.lower(), path.sep)) in x.lower(), urls))\n", " index = urls.index(filtered[len(filtered)-1])\n", - " urlValue = urls[index][urls[index].rindex(os.path.sep)+1:].rstrip()\n", - " replacedString = \"\\n- title: %s\\n url: /%s/%s\\n not_numbered: true\\n expand_sections: true\\n sections: \" % (title, title.lower(), urlValue)\n", + " markdownFilePath = getMarkdownFile(filtered[len(filtered)-1])\n", + " markdownExists = path.exists(markdownFilePath)\n", + " if (not markdownExists):\n", + " index = urls.index(filtered[0])\n", + " folderEndIndex = urls[index].rindex(path.sep)\n", + " caseSensitiveFolderName = urls[index][urls[index].rindex(path.sep, 0, folderEndIndex)+1:folderEndIndex]\n", + " contentFolders.append(caseSensitiveFolderName)\n", + " urlValue = urls[index][urls[index].rindex(path.sep)+1:].rstrip()\n", + " replacedString = \"\\n- title: %s\\n url: /%s/%s\\n%s expand_sections: true\\n sections: \" % (title, caseSensitiveFolderName, urlValue, ' not_numbered: true\\n' if markdownExists else '')\n", " result = result.replace(header, replacedString)\n", - " result = result.replace(urls[index], '')\n", - " del urls[index]\n", - " if (urls):\n", + " if (markdownExists):\n", + " result = result.replace(urls[index], '')\n", + " del urls[index]\n", + " if (urls):\n", + " for url in urls:\n", + " title = url[url.rindex(path.sep)+1:].rstrip()\n", + " urlValue = title\n", + " if (len(contentFolders) > 0):\n", + " folders = url[7:].split(path.sep)\n", + " if (folders[len(folders)-2] in contentFolders):\n", + " parentFolder = contentFolders.index(folders[len(folders)-2])\n", + " urlValue = \"%s/%s\" % (contentFolders[parentFolder], title)\n", + " replacedString = \"\\n - title: %s\\n url: /%s\" % (title, urlValue)\n", + " else:\n", + " replacedString = \"\\n - title: %s\\n url: /%s\" % (title, urlValue) if rootmarkdownExists else \"\\n- title: %s\\n url: /%s\" % (title, urlValue)\n", + " result = result.replace(url, replacedString)\n", + " fwrite = open(tocFilePath, \"w\")\n", + " fwrite.write(result)\n", + " fwrite.close()\n", + " # formattinf any left over urls in the file\n", + " elif (urls):\n", " for url in urls:\n", - " title = url[url.rindex(os.path.sep)+1:].rstrip()\n", + " title = url[url.rindex(path.sep)+1:].rstrip()\n", " urlValue = title\n", - " if (len(contentFolders) > 0):\n", - " folders = url[7:].split(os.path.sep)\n", - " if (folders[len(folders)-2] in contentFolders):\n", - " parentFolder = contentFolders.index(folders[len(folders)-2])\n", - " urlValue = \"%s/%s\" % (contentFolders[parentFolder], title)\n", - " replacedString = \"\\n - title: %s\\n url: /%s\" % (title, urlValue)\n", + " replacedString = \"\\n - title: %s\\n url: /%s\" % (title, urlValue) if rootmarkdownExists else \"\\n- title: %s\\n url: /%s\" % (title, urlValue)\n", " result = result.replace(url, replacedString)\n", " fwrite = open(tocFilePath, \"w\")\n", " fwrite.write(result)\n", @@ -154,12 +226,12 @@ " else:\n", " raise SystemExit(f'\\n File Name contains unsupported-characters (ex: underscores) by Jupyter Book.\\n')\n", " # Update the Book title in config file\n", - " configFilePath = os.path.join(book_name, \"_config.yml\")\n", + " configFilePath = path.join(book_name, \"_config.yml\")\n", " f = open(configFilePath, \"r\")\n", " result = f.read()\n", " f.close()\n", " titleLine = re.search(r'title: [a-zA-Z0-9\\\\.\\s\\-\\/]+$', result, re.MULTILINE).group()\n", - " title = 'title: %s' % (os.path.splitext(os.path.basename(book_name))[0])\n", + " title = 'title: %s' % (path.splitext(path.basename(book_name))[0])\n", " result = result.replace(titleLine, title)\n", " fwrite = open(configFilePath, \"w\")\n", " fwrite.write(result)\n", @@ -172,7 +244,7 @@ " if path.is_dir() and path.name not in ('_data', 'content'):\n", " shutil.rmtree(path)\n", "except Exception as e:\n", - " print(str(e))" + " raise SystemExit(str(e))" ], "metadata": { "azdata_cell_guid": "6124730b-f52e-4103-8dbb-e3a62325fb55", @@ -186,7 +258,7 @@ { "cell_type": "markdown", "source": [ - "## 3. Open your Book!\r\n", + "## 4. Open your Book!\r\n", "**Run the below cell and click on the link to view your book in Azure Data Studio.**" ], "metadata": { diff --git a/extensions/notebook/src/book/bookTreeView.ts b/extensions/notebook/src/book/bookTreeView.ts index d4f5cd7095..0440c845b9 100644 --- a/extensions/notebook/src/book/bookTreeView.ts +++ b/extensions/notebook/src/book/bookTreeView.ts @@ -101,7 +101,7 @@ export class BookTreeViewProvider implements vscode.TreeDataProvider book.bookPath === bookPath) || []; // Check if the book is already open in viewlet. - if (books.length > 0 && books[0].bookItems) { + if (books.length > 0 && books[0].bookItems.length > 0) { this.currentBook = books[0]; await this.showPreviewFile(urlToOpen); }