Recently, I looked at the implementation of the TWO-DIMENSIONAL code, because I need to write some Demo. In order to facilitate debugging, it is convenient to directly display the two-dimensional code in terminal. Therefore, I looked at the implementation of qrcode-terminal, which involves two ways:

1. Spaces & colors

In Termnial it can be set033 \ [} {color value mSet the color. If you need to reset the color, you can pass again\033[0mReset the color.\ 033Is the base 8 representation of ESC’s keyCode.

The two-dimensional code can be understood as a two-dimensional array, which contains flag bits, identifying black or white blocks, so you can use the following functions to print the two-dimensional code:

function print(modules) {
  const black = '\033[40m \033[0m'
  const white = '\033[47m \033[0m'

  const rowLength = modules[0].length
  const border = Array(rowLength + 2)
    .fill(white)
    .join(' ')
  let output = border + '\n'

  modules.forEach((r) = > {
    output += white
    output += r.map((i) = > (i ? black : white)).join(' ')
    output += white + '\n'
  })
  output += border
  console.log(output)
}
// The usage mode
print([
  [1.0.1.0],
  [0.1.0.1],
  [1.0.1.0],
  [0.1.0.1]])Copy the code

2. Use Unicode form

The display of color blocks can be realized simply by using space, but if you want to control the size of color blocks, mode 1 cannot be realized. Moreover, Terminal does not provide an API for modifying the width and height of color blocks, but the size can be halved by Using Unicode. The idea is to use three different Unicode. All white, half white, half black, half black, half black, all black, corresponding unicode is:

{
    WHITE_ALL: '\u2588',
    WHITE_BLACK: '\u2580',
    BLACK_WHITE: '\u2584',
    BLACK_ALL: ' ',
}
Copy the code

function printByUnicode(moduleData) {
  const WHITE_ALL = '\u2588'
  const WHITE_BLACK = '\u2580'
  const BLACK_WHITE = '\u2584'
  const BLACK_ALL = ' '
  const rowLength = moduleData[0].length

  const borderTop = Array(rowLength + 2)
    .fill(BLACK_WHITE)
    .join(' ')
  const borderBottom = Array(rowLength + 2)
    .fill(WHITE_BLACK)
    .join(' ')

  let output = borderTop + '\n'
  for (let row = 0; row < rowLength; row += 2) {
    output += WHITE_ALL

    for (let col = 0; col < rowLength; col++) {
      if(! moduleData[row][col] && ! moduleData[row +1][col]) {
        output += WHITE_ALL
      } else if(! moduleData[row][col] && moduleData[row +1][col]) {
        output += WHITE_BLACK
      } else if(moduleData[row][col] && ! moduleData[row +1][col]) {
        output += BLACK_WHITE
      } else {
        output += BLACK_ALL
      }
    }

    output += WHITE_ALL + '\n'
  }
  output += borderBottom
  console.log(output)
}
Copy the code

Using the same data:

[[1.0.1.0],
  [0.1.0.1],
  [1.0.1.0],
  [0.1.0.1]]Copy the code

Compare the two ways:

The smaller ones are Unicode, and the larger ones are whitespace & color values.