A faux parser for fdf files












0












$begingroup$


Introduction



If you know what FDF files are, you can skip this section.



PDF files sometimes includes form fields. These fields can be represented as FDF in plain text form, extracted using certain utilities. Important things to note about this file are:



A field is represented by



/V ()
/T (Field)


where "Field" is the field name and whatever is written within the parenthesis next to /V will become the input for the utility that will fill the form.



It is possible for there to be nested fields of arbitrary depth. A basic example is



/Kids [
<<
/V ()
/T (node1)
>>
<<
/V ()
/T (node2)
>>]
/T (root)


Here there are two fields node1 and node2 both nested under root. When fields are nested, names that are seen by a user are the components of the hierarchy, separated by .s. For instance name of node1 is root.node1.



The code



The big picture goal of this is to identify the lines that need to be modified when a user provides a bunch of field names (eg. Field, root.node1)



This code reads the FDF file and marks the lines that should be modified to fill a field of a given name. The way I do it involves iterating every line to detect the tree roots and append the name of the roots to every child. Since this will end up in CRAN I want to make sure the approach isn't overly convoluted.



fdfAnnotate = function(fdfLines){
fields = vector(length = length(fdfLines),mode= 'character')
nests = 0
# iterate over every line
for (i in seq_along(fdfLines)){
if(grepl('/T \(',fdfLines[i])){
# /T represents a field or a root name
# take the name
name = stringr::str_extract(fdfLines[i],'(?<=\().*?(?=\))')
if(grepl('/V',fdfLines[i-1])){
# if the line before the naming line starts with /V
# there is no hierarhcy, just name the line
fields[i-1] = name
} else if(grepl('>>\]',fdfLines[i-1])){
# if the line above the name is >>] the name represents a root
# start reading from the line above
z = i-2
# this keeps track of the nest levels.
# we will be reading the file backwards trying to
# reach to the end of this root
nest = 1
while(nest!=0){
if(grepl('/V',fdfLines[z])){
# if a field is found, append the name of the root to the left
# separated by a "."
fields[z] = paste0(name,'.',fields[z])
} else if(grepl('>>\]',fdfLines[z])){
# if another nest stops, that means we are inside another root
nest = nest + 1
} else if(grepl('/Kids \[',fdfLines[z])){
# every time a root closes reduce the nest. if you reach 0
# it means its over
nest = nest - 1
}
# go back one line in the file.
z = z - 1
}
}
}
}
data.frame(fdfLines,fields,stringsAsFactors = FALSE)
}



Usage



You can use it by doing



fdfLines = readLines([pathToFDFfile])
fdfAnnotate(fdfLines)


Below is the FDF file I use for my tests. It includes single and double layered hierarchies as well as a bunch of normal fields.



%FDF-1.2
%âãÏÓ
1 0 obj
<<
/FDF
<<
/Fields [
<<
/V ()
/T (node1)
>>
<<
/Kids [
<<
/Kids [
<<
/V ()
/T (node1)
>>
<<
/V ()
/T (node3)
>>
<<
/V ()
/T (node2)
>>]
/T (child)
>>
<<
/Kids [
<<
/V ()
/T (node1)
>>
<<
/V ()
/T (node2)
>>]
/T (child2)
>>]
/T (hierarchy2)
>>
<<
/V ()
/T (TextField1)
>>
<<
/V ()
/T (TextField2)
>>
<<
/V ()
/T (TextFieldPage2)
>>
<<
/V ()
/T (List Box)
>>
<<
/V ()
/T (TextFieldPage3)
>>
<<
/Kids [
<<
/V ()
/T (node1)
>>
<<
/V ()
/T (node4)
>>
<<
/V ()
/T (node3)
>>
<<
/V ()
/T (node2)
>>]
/T (hierarchy)
>>
<<
/V ()
/T (betweenHierarch)
>>
<<
/V /Off
/T (RadioGroup)
>>
<<
/V /Off
/T (checkBox)
>>]
>>
>>
endobj
trailer

<<
/Root 1 0 R
>>
%%EOF


This file represents the form fields in this pdf file.



Using my function, the output is:



                fdfLines                  fields
1 %FDF-1.2
2 %âãÏÓ
3 1 0 obj
4 <<
5 /FDF
6 <<
7 /Fields [
8 <<
9 /V () node1
10 /T (node1)
11 >>
12 <<
13 /Kids [
14 <<
15 /Kids [
16 <<
17 /V () hierarchy2.child.node1
18 /T (node1)
19 >>
20 <<
21 /V () hierarchy2.child.node3
22 /T (node3)
23 >>
24 <<
25 /V () hierarchy2.child.node2
26 /T (node2)
27 >>]
28 /T (child)
29 >>
30 <<
31 /Kids [
32 <<
33 /V () hierarchy2.child2.node1
34 /T (node1)
35 >>
36 <<
37 /V () hierarchy2.child2.node2
38 /T (node2)
39 >>]
40 /T (child2)
41 >>]
42 /T (hierarchy2)
43 >>
44 <<
45 /V () TextField1
46 /T (TextField1)
47 >>
48 <<
49 /V () TextField2
50 /T (TextField2)
51 >>
52 <<
53 /V () TextFieldPage2
54 /T (TextFieldPage2)
55 >>
56 <<
57 /V () List Box
58 /T (List Box)
59 >>
60 <<
61 /V () TextFieldPage3
62 /T (TextFieldPage3)
63 >>
64 <<
65 /Kids [
66 <<
67 /V () hierarchy.node1
68 /T (node1)
69 >>
70 <<
71 /V () hierarchy.node4
72 /T (node4)
73 >>
74 <<
75 /V () hierarchy.node3
76 /T (node3)
77 >>
78 <<
79 /V () hierarchy.node2
80 /T (node2)
81 >>]
82 /T (hierarchy)
83 >>
84 <<
85 /V () betweenHierarch
86 /T (betweenHierarch)
87 >>
88 <<
89 /V /Off RadioGroup
90 /T (RadioGroup)
91 >>
92 <<
93 /V /Off checkBox
94 /T (checkBox)
95 >>]
96 >>
97 >>
98 endobj
99 trailer
100
101 <<
102 /Root 1 0 R
103 >>
104 %%EOF









share|improve this question







New contributor




OganM is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$

















    0












    $begingroup$


    Introduction



    If you know what FDF files are, you can skip this section.



    PDF files sometimes includes form fields. These fields can be represented as FDF in plain text form, extracted using certain utilities. Important things to note about this file are:



    A field is represented by



    /V ()
    /T (Field)


    where "Field" is the field name and whatever is written within the parenthesis next to /V will become the input for the utility that will fill the form.



    It is possible for there to be nested fields of arbitrary depth. A basic example is



    /Kids [
    <<
    /V ()
    /T (node1)
    >>
    <<
    /V ()
    /T (node2)
    >>]
    /T (root)


    Here there are two fields node1 and node2 both nested under root. When fields are nested, names that are seen by a user are the components of the hierarchy, separated by .s. For instance name of node1 is root.node1.



    The code



    The big picture goal of this is to identify the lines that need to be modified when a user provides a bunch of field names (eg. Field, root.node1)



    This code reads the FDF file and marks the lines that should be modified to fill a field of a given name. The way I do it involves iterating every line to detect the tree roots and append the name of the roots to every child. Since this will end up in CRAN I want to make sure the approach isn't overly convoluted.



    fdfAnnotate = function(fdfLines){
    fields = vector(length = length(fdfLines),mode= 'character')
    nests = 0
    # iterate over every line
    for (i in seq_along(fdfLines)){
    if(grepl('/T \(',fdfLines[i])){
    # /T represents a field or a root name
    # take the name
    name = stringr::str_extract(fdfLines[i],'(?<=\().*?(?=\))')
    if(grepl('/V',fdfLines[i-1])){
    # if the line before the naming line starts with /V
    # there is no hierarhcy, just name the line
    fields[i-1] = name
    } else if(grepl('>>\]',fdfLines[i-1])){
    # if the line above the name is >>] the name represents a root
    # start reading from the line above
    z = i-2
    # this keeps track of the nest levels.
    # we will be reading the file backwards trying to
    # reach to the end of this root
    nest = 1
    while(nest!=0){
    if(grepl('/V',fdfLines[z])){
    # if a field is found, append the name of the root to the left
    # separated by a "."
    fields[z] = paste0(name,'.',fields[z])
    } else if(grepl('>>\]',fdfLines[z])){
    # if another nest stops, that means we are inside another root
    nest = nest + 1
    } else if(grepl('/Kids \[',fdfLines[z])){
    # every time a root closes reduce the nest. if you reach 0
    # it means its over
    nest = nest - 1
    }
    # go back one line in the file.
    z = z - 1
    }
    }
    }
    }
    data.frame(fdfLines,fields,stringsAsFactors = FALSE)
    }



    Usage



    You can use it by doing



    fdfLines = readLines([pathToFDFfile])
    fdfAnnotate(fdfLines)


    Below is the FDF file I use for my tests. It includes single and double layered hierarchies as well as a bunch of normal fields.



    %FDF-1.2
    %âãÏÓ
    1 0 obj
    <<
    /FDF
    <<
    /Fields [
    <<
    /V ()
    /T (node1)
    >>
    <<
    /Kids [
    <<
    /Kids [
    <<
    /V ()
    /T (node1)
    >>
    <<
    /V ()
    /T (node3)
    >>
    <<
    /V ()
    /T (node2)
    >>]
    /T (child)
    >>
    <<
    /Kids [
    <<
    /V ()
    /T (node1)
    >>
    <<
    /V ()
    /T (node2)
    >>]
    /T (child2)
    >>]
    /T (hierarchy2)
    >>
    <<
    /V ()
    /T (TextField1)
    >>
    <<
    /V ()
    /T (TextField2)
    >>
    <<
    /V ()
    /T (TextFieldPage2)
    >>
    <<
    /V ()
    /T (List Box)
    >>
    <<
    /V ()
    /T (TextFieldPage3)
    >>
    <<
    /Kids [
    <<
    /V ()
    /T (node1)
    >>
    <<
    /V ()
    /T (node4)
    >>
    <<
    /V ()
    /T (node3)
    >>
    <<
    /V ()
    /T (node2)
    >>]
    /T (hierarchy)
    >>
    <<
    /V ()
    /T (betweenHierarch)
    >>
    <<
    /V /Off
    /T (RadioGroup)
    >>
    <<
    /V /Off
    /T (checkBox)
    >>]
    >>
    >>
    endobj
    trailer

    <<
    /Root 1 0 R
    >>
    %%EOF


    This file represents the form fields in this pdf file.



    Using my function, the output is:



                    fdfLines                  fields
    1 %FDF-1.2
    2 %âãÏÓ
    3 1 0 obj
    4 <<
    5 /FDF
    6 <<
    7 /Fields [
    8 <<
    9 /V () node1
    10 /T (node1)
    11 >>
    12 <<
    13 /Kids [
    14 <<
    15 /Kids [
    16 <<
    17 /V () hierarchy2.child.node1
    18 /T (node1)
    19 >>
    20 <<
    21 /V () hierarchy2.child.node3
    22 /T (node3)
    23 >>
    24 <<
    25 /V () hierarchy2.child.node2
    26 /T (node2)
    27 >>]
    28 /T (child)
    29 >>
    30 <<
    31 /Kids [
    32 <<
    33 /V () hierarchy2.child2.node1
    34 /T (node1)
    35 >>
    36 <<
    37 /V () hierarchy2.child2.node2
    38 /T (node2)
    39 >>]
    40 /T (child2)
    41 >>]
    42 /T (hierarchy2)
    43 >>
    44 <<
    45 /V () TextField1
    46 /T (TextField1)
    47 >>
    48 <<
    49 /V () TextField2
    50 /T (TextField2)
    51 >>
    52 <<
    53 /V () TextFieldPage2
    54 /T (TextFieldPage2)
    55 >>
    56 <<
    57 /V () List Box
    58 /T (List Box)
    59 >>
    60 <<
    61 /V () TextFieldPage3
    62 /T (TextFieldPage3)
    63 >>
    64 <<
    65 /Kids [
    66 <<
    67 /V () hierarchy.node1
    68 /T (node1)
    69 >>
    70 <<
    71 /V () hierarchy.node4
    72 /T (node4)
    73 >>
    74 <<
    75 /V () hierarchy.node3
    76 /T (node3)
    77 >>
    78 <<
    79 /V () hierarchy.node2
    80 /T (node2)
    81 >>]
    82 /T (hierarchy)
    83 >>
    84 <<
    85 /V () betweenHierarch
    86 /T (betweenHierarch)
    87 >>
    88 <<
    89 /V /Off RadioGroup
    90 /T (RadioGroup)
    91 >>
    92 <<
    93 /V /Off checkBox
    94 /T (checkBox)
    95 >>]
    96 >>
    97 >>
    98 endobj
    99 trailer
    100
    101 <<
    102 /Root 1 0 R
    103 >>
    104 %%EOF









    share|improve this question







    New contributor




    OganM is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.







    $endgroup$















      0












      0








      0





      $begingroup$


      Introduction



      If you know what FDF files are, you can skip this section.



      PDF files sometimes includes form fields. These fields can be represented as FDF in plain text form, extracted using certain utilities. Important things to note about this file are:



      A field is represented by



      /V ()
      /T (Field)


      where "Field" is the field name and whatever is written within the parenthesis next to /V will become the input for the utility that will fill the form.



      It is possible for there to be nested fields of arbitrary depth. A basic example is



      /Kids [
      <<
      /V ()
      /T (node1)
      >>
      <<
      /V ()
      /T (node2)
      >>]
      /T (root)


      Here there are two fields node1 and node2 both nested under root. When fields are nested, names that are seen by a user are the components of the hierarchy, separated by .s. For instance name of node1 is root.node1.



      The code



      The big picture goal of this is to identify the lines that need to be modified when a user provides a bunch of field names (eg. Field, root.node1)



      This code reads the FDF file and marks the lines that should be modified to fill a field of a given name. The way I do it involves iterating every line to detect the tree roots and append the name of the roots to every child. Since this will end up in CRAN I want to make sure the approach isn't overly convoluted.



      fdfAnnotate = function(fdfLines){
      fields = vector(length = length(fdfLines),mode= 'character')
      nests = 0
      # iterate over every line
      for (i in seq_along(fdfLines)){
      if(grepl('/T \(',fdfLines[i])){
      # /T represents a field or a root name
      # take the name
      name = stringr::str_extract(fdfLines[i],'(?<=\().*?(?=\))')
      if(grepl('/V',fdfLines[i-1])){
      # if the line before the naming line starts with /V
      # there is no hierarhcy, just name the line
      fields[i-1] = name
      } else if(grepl('>>\]',fdfLines[i-1])){
      # if the line above the name is >>] the name represents a root
      # start reading from the line above
      z = i-2
      # this keeps track of the nest levels.
      # we will be reading the file backwards trying to
      # reach to the end of this root
      nest = 1
      while(nest!=0){
      if(grepl('/V',fdfLines[z])){
      # if a field is found, append the name of the root to the left
      # separated by a "."
      fields[z] = paste0(name,'.',fields[z])
      } else if(grepl('>>\]',fdfLines[z])){
      # if another nest stops, that means we are inside another root
      nest = nest + 1
      } else if(grepl('/Kids \[',fdfLines[z])){
      # every time a root closes reduce the nest. if you reach 0
      # it means its over
      nest = nest - 1
      }
      # go back one line in the file.
      z = z - 1
      }
      }
      }
      }
      data.frame(fdfLines,fields,stringsAsFactors = FALSE)
      }



      Usage



      You can use it by doing



      fdfLines = readLines([pathToFDFfile])
      fdfAnnotate(fdfLines)


      Below is the FDF file I use for my tests. It includes single and double layered hierarchies as well as a bunch of normal fields.



      %FDF-1.2
      %âãÏÓ
      1 0 obj
      <<
      /FDF
      <<
      /Fields [
      <<
      /V ()
      /T (node1)
      >>
      <<
      /Kids [
      <<
      /Kids [
      <<
      /V ()
      /T (node1)
      >>
      <<
      /V ()
      /T (node3)
      >>
      <<
      /V ()
      /T (node2)
      >>]
      /T (child)
      >>
      <<
      /Kids [
      <<
      /V ()
      /T (node1)
      >>
      <<
      /V ()
      /T (node2)
      >>]
      /T (child2)
      >>]
      /T (hierarchy2)
      >>
      <<
      /V ()
      /T (TextField1)
      >>
      <<
      /V ()
      /T (TextField2)
      >>
      <<
      /V ()
      /T (TextFieldPage2)
      >>
      <<
      /V ()
      /T (List Box)
      >>
      <<
      /V ()
      /T (TextFieldPage3)
      >>
      <<
      /Kids [
      <<
      /V ()
      /T (node1)
      >>
      <<
      /V ()
      /T (node4)
      >>
      <<
      /V ()
      /T (node3)
      >>
      <<
      /V ()
      /T (node2)
      >>]
      /T (hierarchy)
      >>
      <<
      /V ()
      /T (betweenHierarch)
      >>
      <<
      /V /Off
      /T (RadioGroup)
      >>
      <<
      /V /Off
      /T (checkBox)
      >>]
      >>
      >>
      endobj
      trailer

      <<
      /Root 1 0 R
      >>
      %%EOF


      This file represents the form fields in this pdf file.



      Using my function, the output is:



                      fdfLines                  fields
      1 %FDF-1.2
      2 %âãÏÓ
      3 1 0 obj
      4 <<
      5 /FDF
      6 <<
      7 /Fields [
      8 <<
      9 /V () node1
      10 /T (node1)
      11 >>
      12 <<
      13 /Kids [
      14 <<
      15 /Kids [
      16 <<
      17 /V () hierarchy2.child.node1
      18 /T (node1)
      19 >>
      20 <<
      21 /V () hierarchy2.child.node3
      22 /T (node3)
      23 >>
      24 <<
      25 /V () hierarchy2.child.node2
      26 /T (node2)
      27 >>]
      28 /T (child)
      29 >>
      30 <<
      31 /Kids [
      32 <<
      33 /V () hierarchy2.child2.node1
      34 /T (node1)
      35 >>
      36 <<
      37 /V () hierarchy2.child2.node2
      38 /T (node2)
      39 >>]
      40 /T (child2)
      41 >>]
      42 /T (hierarchy2)
      43 >>
      44 <<
      45 /V () TextField1
      46 /T (TextField1)
      47 >>
      48 <<
      49 /V () TextField2
      50 /T (TextField2)
      51 >>
      52 <<
      53 /V () TextFieldPage2
      54 /T (TextFieldPage2)
      55 >>
      56 <<
      57 /V () List Box
      58 /T (List Box)
      59 >>
      60 <<
      61 /V () TextFieldPage3
      62 /T (TextFieldPage3)
      63 >>
      64 <<
      65 /Kids [
      66 <<
      67 /V () hierarchy.node1
      68 /T (node1)
      69 >>
      70 <<
      71 /V () hierarchy.node4
      72 /T (node4)
      73 >>
      74 <<
      75 /V () hierarchy.node3
      76 /T (node3)
      77 >>
      78 <<
      79 /V () hierarchy.node2
      80 /T (node2)
      81 >>]
      82 /T (hierarchy)
      83 >>
      84 <<
      85 /V () betweenHierarch
      86 /T (betweenHierarch)
      87 >>
      88 <<
      89 /V /Off RadioGroup
      90 /T (RadioGroup)
      91 >>
      92 <<
      93 /V /Off checkBox
      94 /T (checkBox)
      95 >>]
      96 >>
      97 >>
      98 endobj
      99 trailer
      100
      101 <<
      102 /Root 1 0 R
      103 >>
      104 %%EOF









      share|improve this question







      New contributor




      OganM is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.







      $endgroup$




      Introduction



      If you know what FDF files are, you can skip this section.



      PDF files sometimes includes form fields. These fields can be represented as FDF in plain text form, extracted using certain utilities. Important things to note about this file are:



      A field is represented by



      /V ()
      /T (Field)


      where "Field" is the field name and whatever is written within the parenthesis next to /V will become the input for the utility that will fill the form.



      It is possible for there to be nested fields of arbitrary depth. A basic example is



      /Kids [
      <<
      /V ()
      /T (node1)
      >>
      <<
      /V ()
      /T (node2)
      >>]
      /T (root)


      Here there are two fields node1 and node2 both nested under root. When fields are nested, names that are seen by a user are the components of the hierarchy, separated by .s. For instance name of node1 is root.node1.



      The code



      The big picture goal of this is to identify the lines that need to be modified when a user provides a bunch of field names (eg. Field, root.node1)



      This code reads the FDF file and marks the lines that should be modified to fill a field of a given name. The way I do it involves iterating every line to detect the tree roots and append the name of the roots to every child. Since this will end up in CRAN I want to make sure the approach isn't overly convoluted.



      fdfAnnotate = function(fdfLines){
      fields = vector(length = length(fdfLines),mode= 'character')
      nests = 0
      # iterate over every line
      for (i in seq_along(fdfLines)){
      if(grepl('/T \(',fdfLines[i])){
      # /T represents a field or a root name
      # take the name
      name = stringr::str_extract(fdfLines[i],'(?<=\().*?(?=\))')
      if(grepl('/V',fdfLines[i-1])){
      # if the line before the naming line starts with /V
      # there is no hierarhcy, just name the line
      fields[i-1] = name
      } else if(grepl('>>\]',fdfLines[i-1])){
      # if the line above the name is >>] the name represents a root
      # start reading from the line above
      z = i-2
      # this keeps track of the nest levels.
      # we will be reading the file backwards trying to
      # reach to the end of this root
      nest = 1
      while(nest!=0){
      if(grepl('/V',fdfLines[z])){
      # if a field is found, append the name of the root to the left
      # separated by a "."
      fields[z] = paste0(name,'.',fields[z])
      } else if(grepl('>>\]',fdfLines[z])){
      # if another nest stops, that means we are inside another root
      nest = nest + 1
      } else if(grepl('/Kids \[',fdfLines[z])){
      # every time a root closes reduce the nest. if you reach 0
      # it means its over
      nest = nest - 1
      }
      # go back one line in the file.
      z = z - 1
      }
      }
      }
      }
      data.frame(fdfLines,fields,stringsAsFactors = FALSE)
      }



      Usage



      You can use it by doing



      fdfLines = readLines([pathToFDFfile])
      fdfAnnotate(fdfLines)


      Below is the FDF file I use for my tests. It includes single and double layered hierarchies as well as a bunch of normal fields.



      %FDF-1.2
      %âãÏÓ
      1 0 obj
      <<
      /FDF
      <<
      /Fields [
      <<
      /V ()
      /T (node1)
      >>
      <<
      /Kids [
      <<
      /Kids [
      <<
      /V ()
      /T (node1)
      >>
      <<
      /V ()
      /T (node3)
      >>
      <<
      /V ()
      /T (node2)
      >>]
      /T (child)
      >>
      <<
      /Kids [
      <<
      /V ()
      /T (node1)
      >>
      <<
      /V ()
      /T (node2)
      >>]
      /T (child2)
      >>]
      /T (hierarchy2)
      >>
      <<
      /V ()
      /T (TextField1)
      >>
      <<
      /V ()
      /T (TextField2)
      >>
      <<
      /V ()
      /T (TextFieldPage2)
      >>
      <<
      /V ()
      /T (List Box)
      >>
      <<
      /V ()
      /T (TextFieldPage3)
      >>
      <<
      /Kids [
      <<
      /V ()
      /T (node1)
      >>
      <<
      /V ()
      /T (node4)
      >>
      <<
      /V ()
      /T (node3)
      >>
      <<
      /V ()
      /T (node2)
      >>]
      /T (hierarchy)
      >>
      <<
      /V ()
      /T (betweenHierarch)
      >>
      <<
      /V /Off
      /T (RadioGroup)
      >>
      <<
      /V /Off
      /T (checkBox)
      >>]
      >>
      >>
      endobj
      trailer

      <<
      /Root 1 0 R
      >>
      %%EOF


      This file represents the form fields in this pdf file.



      Using my function, the output is:



                      fdfLines                  fields
      1 %FDF-1.2
      2 %âãÏÓ
      3 1 0 obj
      4 <<
      5 /FDF
      6 <<
      7 /Fields [
      8 <<
      9 /V () node1
      10 /T (node1)
      11 >>
      12 <<
      13 /Kids [
      14 <<
      15 /Kids [
      16 <<
      17 /V () hierarchy2.child.node1
      18 /T (node1)
      19 >>
      20 <<
      21 /V () hierarchy2.child.node3
      22 /T (node3)
      23 >>
      24 <<
      25 /V () hierarchy2.child.node2
      26 /T (node2)
      27 >>]
      28 /T (child)
      29 >>
      30 <<
      31 /Kids [
      32 <<
      33 /V () hierarchy2.child2.node1
      34 /T (node1)
      35 >>
      36 <<
      37 /V () hierarchy2.child2.node2
      38 /T (node2)
      39 >>]
      40 /T (child2)
      41 >>]
      42 /T (hierarchy2)
      43 >>
      44 <<
      45 /V () TextField1
      46 /T (TextField1)
      47 >>
      48 <<
      49 /V () TextField2
      50 /T (TextField2)
      51 >>
      52 <<
      53 /V () TextFieldPage2
      54 /T (TextFieldPage2)
      55 >>
      56 <<
      57 /V () List Box
      58 /T (List Box)
      59 >>
      60 <<
      61 /V () TextFieldPage3
      62 /T (TextFieldPage3)
      63 >>
      64 <<
      65 /Kids [
      66 <<
      67 /V () hierarchy.node1
      68 /T (node1)
      69 >>
      70 <<
      71 /V () hierarchy.node4
      72 /T (node4)
      73 >>
      74 <<
      75 /V () hierarchy.node3
      76 /T (node3)
      77 >>
      78 <<
      79 /V () hierarchy.node2
      80 /T (node2)
      81 >>]
      82 /T (hierarchy)
      83 >>
      84 <<
      85 /V () betweenHierarch
      86 /T (betweenHierarch)
      87 >>
      88 <<
      89 /V /Off RadioGroup
      90 /T (RadioGroup)
      91 >>
      92 <<
      93 /V /Off checkBox
      94 /T (checkBox)
      95 >>]
      96 >>
      97 >>
      98 endobj
      99 trailer
      100
      101 <<
      102 /Root 1 0 R
      103 >>
      104 %%EOF






      parsing r






      share|improve this question







      New contributor




      OganM is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question







      New contributor




      OganM is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question






      New contributor




      OganM is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 13 mins ago









      OganMOganM

      1012




      1012




      New contributor




      OganM is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      OganM is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      OganM is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          0






          active

          oldest

          votes











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });






          OganM is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f212118%2fa-faux-parser-for-fdf-files%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          OganM is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          OganM is a new contributor. Be nice, and check out our Code of Conduct.













          OganM is a new contributor. Be nice, and check out our Code of Conduct.












          OganM is a new contributor. Be nice, and check out our Code of Conduct.
















          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f212118%2fa-faux-parser-for-fdf-files%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Список кардиналов, возведённых папой римским Каликстом III

          Deduzione

          Mysql.sock missing - “Can't connect to local MySQL server through socket”