Showing posts with label misc. Show all posts
Showing posts with label misc. Show all posts

20 January 2016

Using asciidocs to write documentation/PDF in a maven project

Bambitroll @ 10:51

Writing documentation like release notes in Word is a pain, especially when you have it within  your project which is under version control.
Diffs between commits are impossible and you risk having 2 people editing the document at the same time and overwriting each others changes (no automatic merge possibility like you have with the code).

The idea is then to use asciidocs to write the documentation and then generate PDF documents from there with some kind of template in order to have a final document which is easy to pass around.

So comes asciidoctor to the rescue, which has a maven plugin allowing us to do everything via maven!

You need this in your pom.xml file:

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <asciidoctor.maven.plugin.version>1.5.3</asciidoctor.maven.plugin.version>
        <asciidoctorj.pdf.version>1.5.0-alpha.11</asciidoctorj.pdf.version>
        <asciidoctorj.version>1.5.4</asciidoctorj.version>
        <jruby.version>1.7.21</jruby.version>
    </properties>

    <build>
        <defaultGoal>process-resources</defaultGoal>
        <plugins>
            <plugin>
                <groupId>org.asciidoctor</groupId>
                <artifactId>asciidoctor-maven-plugin</artifactId>
                <version>${asciidoctor.maven.plugin.version}</version>
                <dependencies>
                    <dependency>
                        <groupId>org.asciidoctor</groupId>
                        <artifactId>asciidoctorj-pdf</artifactId>
                        <version>${asciidoctorj.pdf.version}</version>
                    </dependency>
                    <!-- Comment this section to use the default jruby artifact provided by the plugin -->
                    <dependency>
                        <groupId>org.jruby</groupId>
                        <artifactId>jruby-complete</artifactId>
                        <version>${jruby.version}</version>
                    </dependency>
                    <!-- Comment this section to use the default AsciidoctorJ artifact provided by the plugin -->
                    <dependency>
                        <groupId>org.asciidoctor</groupId>
                        <artifactId>asciidoctorj</artifactId>
                        <version>${asciidoctorj.version}</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <sourceDirectory>src/main/resources/ReleaseNotes</sourceDirectory>
                    <!-- Attributes common to all output formats -->
                    <attributes>
                        <sourcedir>${project.build.sourceDirectory}</sourcedir>
                    </attributes>
                </configuration>
                <executions>
                    <execution>
                        <id>generate-pdf-doc</id>
                        <phase>generate-resources</phase>
                        <goals>
                            <goal>process-asciidoc</goal>
                        </goals>
                        <configuration>
                            <backend>pdf</backend>
                            <!-- Since 1.5.0-alpha.9 PDF back-end can use 'rouge' as well as 'coderay' source highlighting -->
                            <sourceHighlighter>rouge</sourceHighlighter>
                            <attributes>
                                <pdf-stylesdir>${project.basedir}/src/main/resources/ReleaseNotes/themes</pdf-stylesdir>
                                <pdf-style>my-theme</pdf-style>
                                <icons>font</icons>
                                <tabsize>4</tabsize>
                                <pagenums/>
                                <toc/>
                                <idprefix/>
                                <idseparator>-</idseparator>
                            </attributes>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>


If you have an image in src/main/resources/ReleaseNotes/images/image1.png and a theme in src/main/resources/ReleaseNotes/themes/my-theme.yml like this

title_page:
  align: right
  background_image: logo.jpg

page:
  layout: portrait
  margin: [2cm, 1cm, 2cm, 1cm] # top, right, bottom, left
  size: A4
base:
  font_color: #333333
  line_height_length: 17
  line_height: $base_line_height_length / $base_font_size
vertical_rhythm: $base_line_height_length
heading:
  font_color: #333333
  font_size: 17
  font_style: bold
  line_height: 1.2
  margin_bottom: $vertical_rhythm
link:
  font_color: #0e83a4
outline_list:
  indent: $base_font_size * 1.5
header:
  height: 1.5cm
  line_height: 1
  recto_content:
    center: '{document-title}'
  verso_content:
    center: '{document-title}'
footer:
  height: 1.5cm
  line_height: 1
  recto_content:
#    right: '{section-title} | *{page-number}/{page-count}*'
    right: '*{page-number}/{page-count}*'
  verso_content:
#    left: '*{page-number}/{page-count}* | {section-title}'
    left: '*{page-number}/{page-count}*'
image:
  align: center
caption:
  align: center
  font_color: #FF0000
  font_size: 10

You can then write your release notes in asciidocs format in src/main/resources/ReleaseNotes/Release_Notes.adoc, which could like like this:

= Release Notes 1.0.0
My Project
v1.0.0

// variables
:MyProj: My fancy project name


// Settings:
:sectnums:
:toc:
:toclevels: 3
:imagesdir[:imagesdir: images]




[.thumb]
image::image1.png[scaledwidth=20%]

[abstract]


== Introduction

This document contains release notes and change log for releases and patches to {MyProj}. +
 +
The document describes changes, known issues, deliverables and versions of sub components for a single version of the application. +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
,===
*Author*, Bugs Bunny
*Status*, Final
*Approved by*, Daffy Duck
*Version*, 1.0.0
*Created*,  January 14th 2016
*Last changed*, January 19th 2016
,===


<<<

== Revision History

*Only for this release* +
 +
[format="csv", options="header"]
|===
Date, Version, Description, Author
*15.01.2016*,0.1,First draft, Bugs Bunny
*15.01.2016*,0.2,Updates, Daffy Duck
|===

<<<

== Version Description


=== Deliverables (Sub components/Features)

bla bla bla...

<<<


=== Dependencies

+++<span style="color: #FF0000">Just some red text</span>+++ +

=== Comments

Comments comments +
 +
 +
*+++<span style="color: red;">WARNING: red and bold</span>+++* +



Then when you compile your project via maven, you will get a PDF document in target/generated-docs!
It should like like this.


In this example, we use asciidoctor to generate the PDF file so the syntax can be a bit different than plain asciidoc.


References:
AsciiDoc Syntax Quick Reference
http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/

Chapter 10. Text Formatting
http://www.methods.co.nz/asciidoc/chunked/ch10.html

asciidoctor-maven-examples/asciidoctor-pdf-example at master · asciidoctor/asciidoctor-maven-examples
https://github.com/asciidoctor/asciidoctor-maven-examples/tree/master/asciidoctor-pdf-example

asciidoctor/asciidoctor-pdfhttps://github.com/asciidoctor/asciidoctor-pdf

asciidoctor-pdf/theming-guide.adoc
https://github.com/asciidoctor/asciidoctor-pdf/blob/master/docs/theming-guide.adoc

AsciiDoc Writer’s Guide
http://asciidoctor.org/docs/asciidoc-writers-guide/

Asciidoctor User Manual
http://asciidoctor.org/docs/user-manual/

Asciidoctor Documentation
http://asciidoctor.org/docs/

Differences between Asciidoctor and AsciiDoc
http://asciidoctor.org/docs/asciidoc-asciidoctor-diffs/

AsciiDoc Writer’s Guide
http://asciidoctor.org/docs/asciidoc-writers-guide/


25 April 2014

Create fake TCP server to test a port is up and running

Bambitroll @ 16:41
There might be a way easier way to do this but here is how I solved it.

What I needed was to have a mock TCP server running on a given port on a given server to check that the firewall between my machine and the remote machine was properly open for a given port.
So I got a little  program running on the remote machine listening on the given port.
I also found a little client program, but using telnet works as well.

Under linux, just run "gcc server.c -o server_test" to compile the program and then run it with "server_test "
Also run "gcc client.c -o client_test" to compile and then run the client with "client_test "

Here is server.c:
/* A simple server in the internet domain using TCP
   The port number is passed as an argument */
#include 
#include 
#include 
#include 
#include  
#include 
#include 

void error(const char *msg)
{
    perror(msg);
    exit(1);
}

int main(int argc, char *argv[])
{
     int sockfd, newsockfd, portno;
     socklen_t clilen;
     char buffer[256];
     struct sockaddr_in serv_addr, cli_addr;
     int n;
     if (argc < 2) {
         fprintf(stderr,"ERROR, no port provided\n");
         exit(1);
     }
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
     if (sockfd < 0) 
        error("ERROR opening socket");
     bzero((char *) &serv_addr, sizeof(serv_addr));
     portno = atoi(argv[1]);
     serv_addr.sin_family = AF_INET;
     serv_addr.sin_addr.s_addr = INADDR_ANY;
     serv_addr.sin_port = htons(portno);
     if (bind(sockfd, (struct sockaddr *) &serv_addr,
              sizeof(serv_addr)) < 0) 
              error("ERROR on binding");
     listen(sockfd,5);
     clilen = sizeof(cli_addr);
     newsockfd = accept(sockfd, 
                 (struct sockaddr *) &cli_addr, 
                 &clilen);
     if (newsockfd < 0) 
          error("ERROR on accept");
     bzero(buffer,256);
     n = read(newsockfd,buffer,255);
     if (n < 0) error("ERROR reading from socket");
     printf("Here is the message: %s\n",buffer);
     n = write(newsockfd,"I got your message",18);
     if (n < 0) error("ERROR writing to socket");
     close(newsockfd);
     close(sockfd);
     return 0; 
}

Here is client.c:
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include  

void error(const char *msg)
{
    perror(msg);
    exit(0);
}

int main(int argc, char *argv[])
{
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;

    char buffer[256];
    if (argc < 3) {
       fprintf(stderr,"usage %s hostname port\n", argv[0]);
       exit(0);
    }
    portno = atoi(argv[2]);
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) 
        error("ERROR opening socket");
    server = gethostbyname(argv[1]);
    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host\n");
        exit(0);
    }
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *)server->h_addr, 
         (char *)&serv_addr.sin_addr.s_addr,
         server->h_length);
    serv_addr.sin_port = htons(portno);
    if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) 
        error("ERROR connecting");
    printf("Please enter the message: ");
    bzero(buffer,256);
    fgets(buffer,255,stdin);
    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0) 
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0) 
         error("ERROR reading from socket");
    printf("%s\n",buffer);
    close(sockfd);
    return 0;
}



Sources: Linux Howtos: C/C++ -> Sockets Tutorial

13 June 2012

XML indenting/formatting

Bambitroll @ 14:56

Working with XML can be a pain, but it is even more so if the XML you get it not properly formatted or indented.

Editors support this more or less properly.

This simple command line will give you something nice:
$ xmllint --format original.xml > nice.xml

P.S: make sure you run this in order to have xmllint installed
apt-get install libxml2-utils

28 February 2011

Improving your laptop battery life

Bambitroll @ 08:14
-
According to this page, you should avoid charging your laptop if its battery is nearly full. Indeed, it destroys your battery capacity in the long run.

Running Ubuntu on a Thinkpad (mine is a T510), you can set up the thresholds for when to start and stop charging yourself.

Here is how:
# aptitude install tp-smapi-dkms
# modprobe tp_smapi
# echo 40 > /sys/devices/platform/smapi/BAT0/start_charge_thresh
# echo 70 > /sys/devices/platform/smapi/BAT0/stop_charge_thresh
# cat /sys/devices/platform/smapi/BAT0/*_charge_thresh

Then to have the settings loaded at each startup:
# apt-get install sysfsutils
And add the following in /etc/sysfs.conf
# For a LiIon battery in a Thinkpad
devices/platform/smapi/BAT0/start_charge_thresh = 50
devices/platform/smapi/BAT0/stop_charge_thresh =85

All the info is here.

Once you are done are reboot the machine, you will need to run the "modprobe tp_smapi" command to be able to access /sys/devices/platform/smapi
-

05 November 2010

Test syntax and xml publishing

Bambitroll @ 15:40
Use this little page to format the XML code for you


#! /bin/env python
def python_funct():
   a = a + b
   print "Hello Highlighted code"

class Foo(Bar):
   pass


<Location /svn>

  # Uncomment this to enable the repository
  DAV svn

  # The following three lines allow anonymous read, but make
  # committers authenticate themselves.  It requires the 'authz_user'
  # module (enable it with 'a2enmod').
  #<LimitExcept GET PROPFIND OPTIONS REPORT>
  Require valid-user
  #</LimitExcept> 

</Location>