As a developer, I often end up needing to manipulate text. Sometimes this text can get quite large, and it might take a while to do it manually. If you have a text editor under your tool belt, it often helps in situations like that. Let’s looks at one of the common scenarios that I come across and how we can solve that using a text editor. I use Sublime Text as my go-to editor for such text editing hacks, but you can do this in any text editor that supports simultaneous editing.
Let’s say I just get a list of comma separated values and need to insert double (or single) quotes around each value to use in a SQL query. To demonstrate this, I ended up going to random.org to generate a list of random values and had to use the same technique that I was to demonstrate as in the SQL query case. I generated 12 random numbers, and the site gave a tab separated list of values, as shown below.
1 2 3
I now need to convert this into a comma-separated list. Let’s see how we can go about doing this.
- Select the recurring character pattern. In this case, it is the tab space.
- Select all occurrences of the pattern. (Alt + F3 - Find All in Sublime)
- Act on all the occurrences. In this case, I want to remove them, so I use Del
- Since I want to introduce a comma between each of the numbers, I first split them into multiple lines using Enter. Now I have all the numbers on a separate line.
- Select all the numbers and insert a cursor at the end of each. ( Ctrl + Shift + L)
- Insert comma. We still have the cursor at the end of all lines, so just pressing Delete again combines all the lines into one. Remove the trailing comma.
Though this is a specific example, I hope you get the general idea on how to go about manipulating text, to split and combine as required. I hope you will be able to insert double (or single) quotes around each value in the comma separated values that we have now, to use in a SQL query!
Setting up the React Application
With the create-react-app template generator, it is easy to setup and get up and running a react application. All you need to run are the below commands, and you have everything set up for a react application.
1 2 3 4 5
The above commands will create an ‘electron-react’ folder with all the code and set up the app at *http://localhost:3000* in development mode.
Setting up Electron
Now that we have a react application setup, let us integrate electron with it. The below command installs electron package.
A basic Electron application needs just these files:
- package.json - Points to the app’s main file and lists its details and dependencies. We already have this as part of the react application.
- main.js - Starts the app and creates a browser window to render HTML. This is the app’s main process. We will add this file.
- index.html - A web page to render. This is the app’s renderer process. We already have this as part of the react application.
Let’s start by adding a main.js file. We will keep the code to the bare minimum. All we are doing here is adding a function createWindow which uses BrowserWindow from the electron package, to create a new window instance. The window loads the development server URL. We will modify this URL later to run independently without a hosted server so that it can be packaged and deployed easily. The app’s ready event is wired to create the new window.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
After updating the package.json with the electron application main entry point, we are all set to run the application.
Fire up two consoles and launch the react application in one using npm start and the electron application in the other using ‘set DEV_URL=http://localhost:3000 && electron .’
Setting up for Deployment
Opening up two consoles and starting up the react server first will start becoming a pain soon. To avoid this, we can use two npm packages to start both the tasks one after the other.
- concurrently: Run multiple commands concurrently.
- wait-on: Wait for files, ports, sockets, http(s) resources to become available
Install both the packages and modify the package.json as shown below.
1 2 3
Running npm start now launches the react application, waits for the server to be up and running and then launches the electron application.
The electron app depends on the react application being hosted locally to run. Let’s update main.js so that it can run from the generated output of the react application. Running npm build generates the website contents into the build folder.
1 2 3 4 5 6 7 8 9 10 11 12
Set the homepage property in package.json (“homepage”: “./”) to enable relative paths on the generated index.html file. Once this is done, we can generate the site using npm run build and run the electron application using ‘electron .’. This will launch the application from the build folder.
Hope this helps you to jump start with your Electron app development using React.
In the previous post, Generating a Large PDF from Website Contents - HTML to PDF, Bookmarks and Handling Empty Pages, we saw how to generate a PDF from HTML and add bookmarks to the generated PDF files. The PDF file generated is for an individual section which now needs to be merged to form a single PDF file. The individual PDF files contain the relevant content for the section and related bookmarks, which needs to be combined into a single PDF file.
One of the important things to keep intact when merging is the document hierarchy. The Sections, Sub-Categories, and Categories should align correctly so that the final bookmark tree and the Table of Contents appear correctly. It is best to maintain the list of individual PDF document streams in the same hierarchy as required. Since we know the required structure right from the UI, this can be easily achieved by using a data structure similar as shown below
1 2 3 4 5 6 7 8
The above structure allows us to maintain a tree-like structure of the document. The structure is the same as that is provided to the user to select the PDF options. I used the iTextSharp library to merge PDF documents. To interact with the PDF, we first need to create a PdfReader object from the stream. Using the SimpleBookmark class, we can get the existing bookmarks for the PDF.
iText representation of bookmarks is a bit complex. It represents them as an ArrayList of Hashtables. The Hashtable has keys like Action, Title, Page, Kids, etc. Kids property represents child bookmarks and is the same ArrayList type. Since it was hard to work with this structure, I created a wrapper class to interact easily with the bookmarks.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
Recursively iterating through the list of DocumentSections, I add all the bookmarks to a root Bookmark class. The root bookmark class represents the full bookmark of the PDF file. The PageNumber is offset using a counter variable. The counter variable is incremented by the number of pages in each of PDF section (pdfReader.NumberOfPages) as it gets merged to the bookmark root. This ensures that the bookmark points to the correct bookmark page in the combined PDF file.
The individual documents are then merged by iterating through all the generated document sections. Once done we get the final PDF as a byte array which is returned to the user.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
To generate a Table of Contents (ToC), we can use the root bookmark information. We need to manually create a PDF page, read the bookmark text and add links to the page with the required font and styling. iText provides API’s to create custom PDF pages.
We are now able to generate a single PDF based on the website contents.
Very often I need to sign forms, receipts, invoices in PDF format and send them across to someone else. Printing the PDF, signing them physically and scanning them back (of course using Office Lens) is how I used to do this until a while back. Since I don’t have a printer at home, I always had to wait till I reach office. Also, I did not like wasting paper and ink just to put a signature.
Adobe PDF reader allows us to ‘Fill and Sign’ documents. Using this option we can add signatures without needing to print them. Follow the below steps to set up your Adobe Reader to sign any document.
1. Sign on a white paper and take a picture. Upload the picture onto your computer and crop the image using your favorite image editor. You should have something similar as shown below.
2. Open the PDF file that you need to sign with Adobe Reader.
3. Open ‘Fill and Sign’ option. You can do this either from the ‘Tools Pane’ (Shift + F4 on windows) or the menu ‘View -> Tools -> Fill and Sign.’
4. Under the Sign option, you can choose a signature image. Choose the image you created before and save.
You are all set to sign documents now. Anytime you want to sign a document, choose ‘Fill and Sign’ and you will see your signature under the Sign button. Click the signature and place it anywhere on the document that you want to sign. No more printing and scanning them back again.
Scanning physical documents can be cumbersome using a scanner, especially if you do not have easy access to one. Taking pictures with the default camera application on the phone might not give the best of results that you are expecting. Also, you will mostly end up needing to trim such photos of unwanted elements.
Microsoft Office Lens is the perfect application for scanning documents and whiteboards. Office Lens focuses documents in the camera frame and allows you to capture just what is required. It enhances the selected document sections. Below is an example of the highlight and the captured document.
- Capture and crop a picture of a whiteboard or blackboard, and share your meeting notes with colleagues.
- Make digital copies of your printed documents, business cards or posters, and trim them precisely.
- Printed text will be automatically recognized (using OCR) by converting Word and PDF, so you can search for words in images and copy and edit them.
‘I need some undistracted time.’
This was one of the things that came up in my team’s retrospective yesterday. Having some undistracted time is necessary for getting things done. It’s a good practice to have a consensus among the team members on how to manage disruptions and indicate whether you are open for a chat.
The Headphone Rule is an interesting way to indicate whether a person is open to interactions or not.
no headphones, you can talk to me.
1 headphone, you can talk to me about work
2 headphones, do not talk to me.
For people who do not use a headphone, some other technique needs to be used (like sticky notes, colored lights, etc.). Luckily in my team, everyone uses headphones, and it was an acceptable solution. Irrespective of the way you choose it is important to have some agreed way to indicate whether you are interruptible or not. It helps you and the team to have some undistracted time.
If you are a .NET developer and looking for some awesome free stuff, then check out Visual Studio Dev Essentials. You get loads of free stuff
Free tools, cloud services, and training
Get everything you need to build and deploy your app on any platform. With state-of-the-art tools, the power of the cloud, training, and support, it’s our most comprehensive free developer program ever.
Some of the key attractions of the program are
- $300 Azure Credit for a year
- Access to Xamarin University Training
- Pluralsight access for three months
- WintellectNOW access for three months
All you need is a Windows Live ID to signup. Get it if you have not already!
Last week was a busy one at NDC Sydney and was happy to be back there for the second time.The conference was three days long with 117 speakers, 37 technologies, and 151 talks. Some of the popular speakers were Scott Wlaschin, Scott Allen,Troy Hunt, Damian Edwards, Steve Sanderson and a lot more.
Each talk is one hour long and eight talks happen at the same time. Below are the talks I attended:
- Keynote: Using EEG and Machine Learning to Perform Lie Detection
- A teams transition to Continuous Delivery
- Docker, FROM scratch
- The Technical Debt Prevention Clinic
- How to start and run a software lifestyle business
- Asynchronous Programming From The Ground Up
- Building Docker Applications with .NET - tooling, cross platform support and migration
- Hack Your Career
- Writing high performance code in .NET
- Growing Serverless code with Azure Functions and F#
- “The website’s down!” Stories and lessons on keeping your website up
- Self-Aware Applications: Automatic Production Monitoring
- Domain Modeling Made Functional
- Interactive C# Development with Roslyn
- Building Resilient Applications In Microsoft Azure
- Functional Design Patterns
- Logic vs. side effects: functional goodness you don’t hear about
- How one team built their first microservice
All sessions are recorded and are available here. The Sydney 2017 ones will soon be there. Overall it was a good event but did not match the one last year. Last year there were more of the popular speakers and the talk content was also more interesting. But still, I am glad that NDC Sydney is still happening, and it gives a good exposure and networking possibilities for developers. Thanks to Readify for sponsoring my tickets and it’s one of the good things about working with Readify.
Hope to see you next year as well!
We are typists first, and programmers second.
If you are like me, spending a lot of time with a computer, it’s worth you take the time to learn to type without looking at the keyboard a.k.a touch typing (if you currently type by the hunt and peck method). Though productivity cannot be measured by the number of words you type per minute, it’s good to learn to touch type. There are various applications that help you to improve your typing speed. Some of them are online and some offline desktop applications. Pick one that suits you and improve your typing speed.
I learned to touch type only a couple of years back, getting inspired after reading Learn Anything in 20 Hours. In the book, the author explains how he learned a new keyboard layout, Colemak, in just 20 hours. The book explains the full process and setup used by the author. It uses various tools like Keyzen, Type-fu, Amphetype. More than the tools it is the process and the approach to the learning that is interesting. A summary of the tools and approaches is available here but highly recommend reading the book. I found the approach very helpful and effective and used to learn QWERTY layout.
Irrespective of the way you choose to learn touch typing, it might seem a bit hard at the start. Keep at it for some time snd you will soon see an improvement in your typing speed.
In the previous post, Generating a Large PDF from Website Contents we saw from a high level the approach taken to generate PDF files from a Content Management System (CMS) website. In this post, we will delve further into the details of each of those areas.
HTML To PDF
There are a lot of libraries and services that support converting HTML to PDF. We chose this mechanism mainly for keeping the content formatting simple and reusable. Most of the PDF data was to be structured like the website content. This means we can reuse (read copy/paste) the HTML styling for the PDF content as well.
We used Essential Objects HTML to PDF Converter library. Our website is hosted as an Azure Web App and the Essential Objects library does not work in the Azure sandbox environment. The Azure Sandbox restriction affects most of the HTML to PDF libraries. The recommended approach to use those libraries is to host the PDF conversion logic on an Azure Virtual Machine, which is what we also ended up doing. Alternatively, you can choose to use one of the HTML to PDF hosted services.
The below code snippet is what you need to convert an HTML URL endpoint to PDF. It uses the HtmlToPdf class from the EO.Pdf Nuget package. The HtmlToPdfOptions specifies various conversion and formatting options. You can set margin space, common headers, footers, etc. for the generated PDF content. It also provides extensibility points in the PDF conversion pipeline.
1 2 3 4 5 6 7 8 9 10 11
HTML Formatting Tip
You might want to avoid content being split across multiple pages. E.g., images, charts, etc. In this cases, you can use the page-break-* CSS property to adjust page breaks. Essentials objects honors the page-break-* settings and adjusts the content when converting into PDF.
A bookmark is a type of link with representative text in the Bookmarks panel in the navigation pane. Each bookmark goes to a different view or page in the document. Bookmarks are generated automatically during PDF creation from the table-of-contents entries of a document.
We generate a lot of small PDF files (per section and category/sub-category) and then merge them together to form the larger PDF. Each of the sections has one or more entries towards Table Of Contents (TOC). We decided to generate bookmarks first per each generated PDF. When merging the individual PDF, the bookmarks are merged first, and then the TOC is created from the full bookmark tree.
Bookmarks can be created automatically or manually using Essential Objects library. Most of the other libraries also provide similar functionality. Using the AutoBookmark property we can have bookmarks created automatically based on HTML header (H1-H6) elements. If this does not fit with your scenario, then you can create them manually. In our case, we insert hidden HTML tags to specify bookmarks. Bookmark hierarchy is represented using custom attributes as shown below.
1 2 3 4 5 6
Once the PDF is created from the URL, we parse the HTML content for elements with bookmark class and manually add the bookmarks into the generated PDF. The GetElementsByClassName and the CreateBookmark methods help us to create bookmarks from the hidden HTML elements in the page.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Handling Empty Pages
In our case, the content is from a CMS, and the user gets an option to select what categories/sub-categories and sections of data to be displayed in the generated PDF. At times it happens that some of the selected combinations might not have any data in the system. To avoid printing a blank page (or an error page) in the generated PDF, we can check the conversion result to check for the returned content. Whenever the content does not exists the HTML endpoint returns an EmptyResult class.aspx). At the PDF conversion side, you can check if the response is empty and accordingly perform your logic to ignore the generated PDF.
1 2 3 4 5 6 7 8 9 10
Once the individual PDF files are created for each of the section and category/subcategory combination, we can merge them together to generate the full PDF. We will see in the next post how to merge the bookmarks together along with shifting the PDF pages and generating Table of Contents from the bookmarks.